From 9b3967bfd7fa1d0da30413817358d9b9963e0288 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Wed, 19 Nov 2025 10:54:16 +0100 Subject: [PATCH 01/31] Move the existing routing code to `routing/road`, and create a new folder (`routing/pt`) for PT routing --- .gitignore | 14 +++++++++----- README.md | 2 +- src/FleetSimulationBase.py | 2 +- src/demand/TravelerModels.py | 2 +- src/fleetctrl/BrokerAndExchangeFleetControl.py | 2 +- src/fleetctrl/FleetControlBase.py | 2 +- src/fleetctrl/RPPFleetControl.py | 2 +- ...PoolingBatchOptimizationFleetControlBase.py | 2 +- src/fleetctrl/planning/PlanRequest.py | 2 +- src/fleetctrl/planning/VehiclePlan.py | 2 +- .../pooling/GeneralPoolingFunctions.py | 2 +- .../batch/AlonsoMora/AlonsoMoraAssignment.py | 2 +- src/fleetctrl/pooling/batch/AlonsoMora/V2RB.py | 2 +- .../batch/BatchAssignmentAlgorithmBase.py | 2 +- .../batch/Simonetto/SimonettoAssignment.py | 2 +- src/fleetctrl/pooling/immediate/insertion.py | 2 +- .../pooling/immediate/singleVehicleDARP.py | 2 +- src/fleetctrl/pooling/objectives.py | 2 +- ...SamplingRidePoolingRebalancingMultiStage.py | 2 +- ...ePoolingRebalancingMultiStageReservation.py | 2 +- .../BatchSchedulingRevelationHorizonBase.py | 2 +- .../ContinuousBatchRevelationReservation.py | 2 +- .../reservation/ReservationRequestBatch.py | 2 +- .../misc/ArtificialReservationFleetControl.py | 2 +- src/fleetctrl/reservation/misc/RequestGroup.py | 2 +- .../rideparcelpooling/immediate/insertion.py | 2 +- src/infra/ChargingInfrastructure.py | 2 +- src/misc/init_modules.py | 18 +++++++++--------- .../demand/aggregate_trip_demand.py | 2 +- .../access_point_distribution_preprocessing.py | 2 +- .../preprocess_boarding_point_distances.py | 2 +- .../create_Xto1_preprocessing_files.py | 4 ++-- ...artially_preprocessed_travel_time_tables.py | 4 ++-- src/preprocessing/pubtrans/PTScheduleGen.py | 2 +- src/routing/{ => road}/NetworkBase.py | 0 src/routing/{ => road}/NetworkBasic.py | 4 ++-- src/routing/{ => road}/NetworkBasicCpp.py | 4 ++-- .../{ => road}/NetworkBasicWithStore.py | 4 ++-- .../{ => road}/NetworkBasicWithStoreCpp.py | 4 ++-- .../{ => road}/NetworkForPreprocessing.py | 2 +- .../{ => road}/NetworkImmediatePreproc.py | 2 +- .../{ => road}/NetworkPartialPreprocessed.py | 4 ++-- .../NetworkPartialPreprocessedCpp.py | 4 ++-- src/routing/{ => road}/NetworkTTMatrix.py | 2 +- src/routing/{ => road}/cpp_router/Edge.cpp | 0 src/routing/{ => road}/cpp_router/Edge.h | 0 src/routing/{ => road}/cpp_router/Network.cpp | 0 src/routing/{ => road}/cpp_router/Network.h | 0 src/routing/{ => road}/cpp_router/Network.pxd | 0 src/routing/{ => road}/cpp_router/Node.cpp | 0 src/routing/{ => road}/cpp_router/Node.h | 0 .../{ => road}/cpp_router/PyNetwork.pyx | 0 .../cpp_router/cpp_router_checker.py | 4 ++-- src/routing/{ => road}/cpp_router/setup.py | 0 .../routing_imports/PriorityQueue_python3.py | 0 .../{ => road}/routing_imports/Router.py | 2 +- .../{ => road}/routing_imports/__init__.py | 0 src/simulation/Offers.py | 2 +- src/simulation/Vehicles.py | 2 +- 59 files changed, 72 insertions(+), 68 deletions(-) rename src/routing/{ => road}/NetworkBase.py (100%) rename src/routing/{ => road}/NetworkBasic.py (99%) rename src/routing/{ => road}/NetworkBasicCpp.py (99%) rename src/routing/{ => road}/NetworkBasicWithStore.py (98%) rename src/routing/{ => road}/NetworkBasicWithStoreCpp.py (98%) rename src/routing/{ => road}/NetworkForPreprocessing.py (93%) rename src/routing/{ => road}/NetworkImmediatePreproc.py (97%) rename src/routing/{ => road}/NetworkPartialPreprocessed.py (98%) rename src/routing/{ => road}/NetworkPartialPreprocessedCpp.py (99%) rename src/routing/{ => road}/NetworkTTMatrix.py (99%) rename src/routing/{ => road}/cpp_router/Edge.cpp (100%) rename src/routing/{ => road}/cpp_router/Edge.h (100%) rename src/routing/{ => road}/cpp_router/Network.cpp (100%) rename src/routing/{ => road}/cpp_router/Network.h (100%) rename src/routing/{ => road}/cpp_router/Network.pxd (100%) rename src/routing/{ => road}/cpp_router/Node.cpp (100%) rename src/routing/{ => road}/cpp_router/Node.h (100%) rename src/routing/{ => road}/cpp_router/PyNetwork.pyx (100%) rename src/routing/{ => road}/cpp_router/cpp_router_checker.py (92%) rename src/routing/{ => road}/cpp_router/setup.py (100%) rename src/routing/{ => road}/routing_imports/PriorityQueue_python3.py (100%) rename src/routing/{ => road}/routing_imports/Router.py (99%) rename src/routing/{ => road}/routing_imports/__init__.py (100%) diff --git a/.gitignore b/.gitignore index 1e17640c..9234f785 100644 --- a/.gitignore +++ b/.gitignore @@ -46,15 +46,15 @@ studies/chicago_case_study/results/* studies/munich_case_study/results/* # system dependent C++ Router files -src/routing/cpp_router/*.pyd -src/routing/cpp_router/build/* -src/routing/cpp_router/PyNetwork.cpp -src/routing/extractors/cache/* +src/routing/road/cpp_router/*.pyd +src/routing/road/cpp_router/build/* +src/routing/road/cpp_router/PyNetwork.cpp +src/routing/road/extractors/cache/* # IDE-related files *.idea .vscode/* -src/routing/cpp_router/.vs/* +src/routing/road/cpp_router/.vs/* # Byte-compiled / optimized / DLL files __pycache__/ @@ -186,3 +186,7 @@ dmypy.json # Pyre type checker .pyre/ + +# MacOS +.DS_Store + diff --git a/README.md b/README.md index a53ad9ba..bfc16301 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ conda activate fleetpy For improved routing efficiency, compile the C++ router: ```bash -cd FleetPy/src/routing/cpp_router +cd FleetPy/src/routing/road/cpp_router python setup.py build_ext --inplace ``` diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index acf621c5..aec8ed26 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -26,7 +26,7 @@ from src.simulation.Vehicles import SimulationVehicle if tp.TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.broker.BrokerBase import BrokerBase from src.python_plots.plot_classes import PyPlot diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index f55f913a..f0dc5dd6 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -15,7 +15,7 @@ # src imports # ----------- from src.misc.functions import PiecewiseContinuousLinearFunction -from src.routing.NetworkBase import return_position_str +from src.routing.road.NetworkBase import return_position_str # -------------------------------------------------------------------------------------------------------------------- # # global variables # ---------------- diff --git a/src/fleetctrl/BrokerAndExchangeFleetControl.py b/src/fleetctrl/BrokerAndExchangeFleetControl.py index 1f4b0e0f..5dfa1970 100644 --- a/src/fleetctrl/BrokerAndExchangeFleetControl.py +++ b/src/fleetctrl/BrokerAndExchangeFleetControl.py @@ -19,7 +19,7 @@ if TYPE_CHECKING: from src.fleetctrl.planning.VehiclePlan import VehiclePlan from src.simulation.Vehicles import SimulationVehicle - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.infra.Zoning import ZoneSystem LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/FleetControlBase.py b/src/fleetctrl/FleetControlBase.py index bcad9548..11007018 100644 --- a/src/fleetctrl/FleetControlBase.py +++ b/src/fleetctrl/FleetControlBase.py @@ -30,7 +30,7 @@ load_dynamic_fleet_sizing_strategy, load_dynamic_pricing_strategy, load_reservation_strategy from src.fleetctrl.pooling.GeneralPoolingFunctions import get_assigned_rids_from_vehplan if TYPE_CHECKING: - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.simulation.Vehicles import SimulationVehicle from src.infra.Zoning import ZoneSystem from src.infra.ChargingInfrastructure import OperatorChargingAndDepotInfrastructure, PublicChargingInfrastructureOperator diff --git a/src/fleetctrl/RPPFleetControl.py b/src/fleetctrl/RPPFleetControl.py index 375a2486..3e46de85 100644 --- a/src/fleetctrl/RPPFleetControl.py +++ b/src/fleetctrl/RPPFleetControl.py @@ -21,7 +21,7 @@ from src.simulation.Offers import TravellerOffer if TYPE_CHECKING: from src.demand.TravelerModels import RequestBase, ParcelRequestBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.simulation.Vehicles import SimulationVehicle # -------------------------------------------------------------------------------------------------------------------- # diff --git a/src/fleetctrl/RidePoolingBatchOptimizationFleetControlBase.py b/src/fleetctrl/RidePoolingBatchOptimizationFleetControlBase.py index 22bdd3bd..c88c5a6f 100644 --- a/src/fleetctrl/RidePoolingBatchOptimizationFleetControlBase.py +++ b/src/fleetctrl/RidePoolingBatchOptimizationFleetControlBase.py @@ -14,7 +14,7 @@ from src.misc.globals import * if TYPE_CHECKING: - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.batch.BatchAssignmentAlgorithmBase import BatchAssignmentAlgorithmBase from src.simulation.Vehicles import SimulationVehicle from src.infra.ChargingInfrastructure import OperatorChargingAndDepotInfrastructure, PublicChargingInfrastructureOperator diff --git a/src/fleetctrl/planning/PlanRequest.py b/src/fleetctrl/planning/PlanRequest.py index 1595b443..76a38715 100644 --- a/src/fleetctrl/planning/PlanRequest.py +++ b/src/fleetctrl/planning/PlanRequest.py @@ -9,7 +9,7 @@ # ---------------- from src.misc.globals import * from src.demand.TravelerModels import RequestBase -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.simulation.Offers import TravellerOffer LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/planning/VehiclePlan.py b/src/fleetctrl/planning/VehiclePlan.py index 0608bad1..9851f0c1 100644 --- a/src/fleetctrl/planning/VehiclePlan.py +++ b/src/fleetctrl/planning/VehiclePlan.py @@ -14,7 +14,7 @@ from src.simulation.Legs import VehicleRouteLeg from src.simulation.Vehicles import SimulationVehicle from src.fleetctrl.planning.PlanRequest import PlanRequest -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/fleetctrl/pooling/GeneralPoolingFunctions.py b/src/fleetctrl/pooling/GeneralPoolingFunctions.py index 44ea1886..26ab7bcc 100644 --- a/src/fleetctrl/pooling/GeneralPoolingFunctions.py +++ b/src/fleetctrl/pooling/GeneralPoolingFunctions.py @@ -2,7 +2,7 @@ from typing import Callable, Dict, List, Any, Tuple, TYPE_CHECKING if TYPE_CHECKING: - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.batch.AlonsoMora.AlonsoMoraParallelization import ParallelizationManager from src.fleetctrl.FleetControlBase import FleetControlBase from src.fleetctrl.planning.PlanRequest import PlanRequest diff --git a/src/fleetctrl/pooling/batch/AlonsoMora/AlonsoMoraAssignment.py b/src/fleetctrl/pooling/batch/AlonsoMora/AlonsoMoraAssignment.py index fc7aa128..ea4ff274 100644 --- a/src/fleetctrl/pooling/batch/AlonsoMora/AlonsoMoraAssignment.py +++ b/src/fleetctrl/pooling/batch/AlonsoMora/AlonsoMoraAssignment.py @@ -17,7 +17,7 @@ from src.misc.globals import * from src.simulation.Legs import VehicleRouteLeg if TYPE_CHECKING: - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.batch.AlonsoMora.AlonsoMoraParallelization import ParallelizationManager from src.fleetctrl.FleetControlBase import FleetControlBase from src.fleetctrl.planning.PlanRequest import PlanRequest diff --git a/src/fleetctrl/pooling/batch/AlonsoMora/V2RB.py b/src/fleetctrl/pooling/batch/AlonsoMora/V2RB.py index 0eb2c06d..cce98248 100644 --- a/src/fleetctrl/pooling/batch/AlonsoMora/V2RB.py +++ b/src/fleetctrl/pooling/batch/AlonsoMora/V2RB.py @@ -7,7 +7,7 @@ if TYPE_CHECKING: from src.fleetctrl.pooling.batch.BatchAssignmentAlgorithmBase import SimulationVehicleStruct - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.planning.PlanRequest import PlanRequest from src.simulation.Legs import VehicleRouteLeg diff --git a/src/fleetctrl/pooling/batch/BatchAssignmentAlgorithmBase.py b/src/fleetctrl/pooling/batch/BatchAssignmentAlgorithmBase.py index 7c89ea9a..51aba354 100644 --- a/src/fleetctrl/pooling/batch/BatchAssignmentAlgorithmBase.py +++ b/src/fleetctrl/pooling/batch/BatchAssignmentAlgorithmBase.py @@ -8,7 +8,7 @@ from src.fleetctrl.planning.VehiclePlan import VehiclePlan from src.simulation.Legs import VehicleRouteLeg from src.simulation.Vehicles import SimulationVehicle -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.misc.globals import * LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/pooling/batch/Simonetto/SimonettoAssignment.py b/src/fleetctrl/pooling/batch/Simonetto/SimonettoAssignment.py index 5705a251..3b12eccd 100644 --- a/src/fleetctrl/pooling/batch/Simonetto/SimonettoAssignment.py +++ b/src/fleetctrl/pooling/batch/Simonetto/SimonettoAssignment.py @@ -11,7 +11,7 @@ from src.fleetctrl.planning.VehiclePlan import VehiclePlan, BoardingPlanStop from src.fleetctrl.pooling.immediate.insertion import simple_remove, insert_prq_in_selected_veh_list from src.misc.globals import * -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.simulation.Legs import VehicleRouteLeg from src.simulation.Vehicles import SimulationVehicle diff --git a/src/fleetctrl/pooling/immediate/insertion.py b/src/fleetctrl/pooling/immediate/insertion.py index 46f4ee6c..cce39fbb 100644 --- a/src/fleetctrl/pooling/immediate/insertion.py +++ b/src/fleetctrl/pooling/immediate/insertion.py @@ -2,7 +2,7 @@ from src.fleetctrl.planning.VehiclePlan import BoardingPlanStop, PlanStop, VehiclePlan from src.fleetctrl.planning.PlanRequest import PlanRequest from src.simulation.Vehicles import SimulationVehicle -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.immediate.searchVehicles import veh_search_for_immediate_request,\ veh_search_for_reservation_request from src.fleetctrl.pooling.immediate.SelectRV import filter_directionality, filter_least_number_tasks diff --git a/src/fleetctrl/pooling/immediate/singleVehicleDARP.py b/src/fleetctrl/pooling/immediate/singleVehicleDARP.py index f6566546..d443075a 100644 --- a/src/fleetctrl/pooling/immediate/singleVehicleDARP.py +++ b/src/fleetctrl/pooling/immediate/singleVehicleDARP.py @@ -6,7 +6,7 @@ from src.fleetctrl.planning.VehiclePlan import BoardingPlanStop, PlanStop, VehiclePlan from src.fleetctrl.planning.PlanRequest import PlanRequest from src.simulation.Vehicles import SimulationVehicle -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.immediate.insertion import simple_insert, simple_remove LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/pooling/objectives.py b/src/fleetctrl/pooling/objectives.py index e941f620..f93068d9 100644 --- a/src/fleetctrl/pooling/objectives.py +++ b/src/fleetctrl/pooling/objectives.py @@ -8,7 +8,7 @@ from src.fleetctrl.planning.VehiclePlan import VehiclePlan from src.fleetctrl.planning.PlanRequest import PlanRequest from src.simulation.Vehicles import SimulationVehicle - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStage.py b/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStage.py index cb08ef5a..979b9e6f 100644 --- a/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStage.py +++ b/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStage.py @@ -25,7 +25,7 @@ from typing import TYPE_CHECKING, List, Dict, Tuple, Callable, Any if TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase OPT_TIME_LIMIT = 120 WRITE_SOL = True diff --git a/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStageReservation.py b/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStageReservation.py index 209126ca..da918c08 100644 --- a/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStageReservation.py +++ b/src/fleetctrl/repositioning/FullSamplingRidePoolingRebalancingMultiStageReservation.py @@ -25,7 +25,7 @@ from typing import TYPE_CHECKING, List, Dict, Tuple, Callable, Any if TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase OPT_TIME_LIMIT = 120 WRITE_SOL = True diff --git a/src/fleetctrl/reservation/BatchSchedulingRevelationHorizonBase.py b/src/fleetctrl/reservation/BatchSchedulingRevelationHorizonBase.py index caf83423..ef08bf4a 100644 --- a/src/fleetctrl/reservation/BatchSchedulingRevelationHorizonBase.py +++ b/src/fleetctrl/reservation/BatchSchedulingRevelationHorizonBase.py @@ -7,7 +7,7 @@ from src.simulation.Offers import TravellerOffer from src.fleetctrl.FleetControlBase import FleetControlBase from src.fleetctrl.pooling.immediate.insertion import simple_remove -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.planning.VehiclePlan import PlanStopBase, RoutingTargetPlanStop from src.fleetctrl.planning.PlanRequest import PlanRequest from src.fleetctrl.reservation.RevelationHorizonBase import RevelationHorizonBase diff --git a/src/fleetctrl/reservation/ContinuousBatchRevelationReservation.py b/src/fleetctrl/reservation/ContinuousBatchRevelationReservation.py index 818efd75..5f9a8bdd 100644 --- a/src/fleetctrl/reservation/ContinuousBatchRevelationReservation.py +++ b/src/fleetctrl/reservation/ContinuousBatchRevelationReservation.py @@ -19,7 +19,7 @@ if TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase import logging LOG = logging.getLogger(__name__) diff --git a/src/fleetctrl/reservation/ReservationRequestBatch.py b/src/fleetctrl/reservation/ReservationRequestBatch.py index 866c91bc..60abb476 100644 --- a/src/fleetctrl/reservation/ReservationRequestBatch.py +++ b/src/fleetctrl/reservation/ReservationRequestBatch.py @@ -1,7 +1,7 @@ import numpy as np import pandas as pd from src.fleetctrl.FleetControlBase import FleetControlBase -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.planning.VehiclePlan import PlanStopBase from src.fleetctrl.planning.PlanRequest import PlanRequest from src.fleetctrl.reservation.misc.RequestGroup import RequestGroup, QuasiVehiclePlan, VehiclePlanSupportingPoint, rg_key diff --git a/src/fleetctrl/reservation/misc/ArtificialReservationFleetControl.py b/src/fleetctrl/reservation/misc/ArtificialReservationFleetControl.py index f69c422f..a3e74e61 100644 --- a/src/fleetctrl/reservation/misc/ArtificialReservationFleetControl.py +++ b/src/fleetctrl/reservation/misc/ArtificialReservationFleetControl.py @@ -1,7 +1,7 @@ from src.fleetctrl.RidePoolingBatchAssignmentFleetcontrol import RidePoolingBatchAssignmentFleetcontrol from src.fleetctrl.planning.VehiclePlan import VehiclePlan, BoardingPlanStop, PlanStopBase, RoutingTargetPlanStop from src.fleetctrl.planning.PlanRequest import PlanRequest -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.immediate.insertion import simple_insert, simple_remove from src.misc.globals import * from typing import Any, Callable, List, Dict, Tuple, Type diff --git a/src/fleetctrl/reservation/misc/RequestGroup.py b/src/fleetctrl/reservation/misc/RequestGroup.py index f8419b54..be8ccb12 100644 --- a/src/fleetctrl/reservation/misc/RequestGroup.py +++ b/src/fleetctrl/reservation/misc/RequestGroup.py @@ -1,7 +1,7 @@ from src.fleetctrl.FleetControlBase import FleetControlBase from src.fleetctrl.planning.VehiclePlan import VehiclePlan, BoardingPlanStop, PlanStopBase from src.fleetctrl.planning.PlanRequest import PlanRequest -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.immediate.insertion import simple_insert, simple_remove from src.misc.globals import * from typing import Any, Callable, List, Dict, Tuple, Type diff --git a/src/fleetctrl/rideparcelpooling/immediate/insertion.py b/src/fleetctrl/rideparcelpooling/immediate/insertion.py index 0b6a9acf..f38b91e3 100644 --- a/src/fleetctrl/rideparcelpooling/immediate/insertion.py +++ b/src/fleetctrl/rideparcelpooling/immediate/insertion.py @@ -4,7 +4,7 @@ from src.fleetctrl.planning.VehiclePlan import BoardingPlanStop, VehiclePlan from src.fleetctrl.planning.PlanRequest import PlanRequest from src.simulation.Vehicles import SimulationVehicle -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.pooling.immediate.insertion import simple_insert from src.misc.globals import * import numpy as np diff --git a/src/infra/ChargingInfrastructure.py b/src/infra/ChargingInfrastructure.py index f56e18a1..8d1f41f5 100644 --- a/src/infra/ChargingInfrastructure.py +++ b/src/infra/ChargingInfrastructure.py @@ -26,7 +26,7 @@ from src.fleetctrl.planning.VehiclePlan import ChargingPlanStop, VehiclePlan, RoutingTargetPlanStop from src.misc.config import decode_config_str if TYPE_CHECKING: - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.simulation.Vehicles import SimulationVehicle from src.fleetctrl.FleetControlBase import FleetControlBase diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index 46245ded..2b7baccd 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -5,7 +5,7 @@ import typing as tp if tp.TYPE_CHECKING: from src.FleetSimulationBase import FleetSimulationBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.FleetControlBase import FleetControlBase from src.broker.BrokerBase import BrokerBase from src.demand.TravelerModels import RequestBase @@ -57,14 +57,14 @@ def get_src_simulation_environments(): def get_src_routing_engines(): # FleetPy routing engine options re_dict = {} # str -> (module path, class name) - re_dict["NetworkBasic"] = ("src.routing.NetworkBasic", "NetworkBasic") - re_dict["NetworkImmediatePreproc"] = ("src.routing.NetworkImmediatePreproc", "NetworkImmediatePreproc") - re_dict["NetworkBasicWithStore"] = ("src.routing.NetworkBasicWithStore", "NetworkBasicWithStore") - re_dict["NetworkPartialPreprocessed"] = ("src.routing.NetworkPartialPreprocessed", "NetworkPartialPreprocessed") - re_dict["NetworkBasicWithStoreCpp"] = ("src.routing.NetworkBasicWithStoreCpp", "NetworkBasicWithStoreCpp") - re_dict["NetworkBasicCpp"] = ("src.routing.NetworkBasicCpp", "NetworkBasicCpp") - re_dict["NetworkPartialPreprocessedCpp"] = ("src.routing.NetworkPartialPreprocessedCpp", "NetworkPartialPreprocessedCpp") - re_dict["NetworkTTMatrix"] = ("src.routing.NetworkTTMatrix", "NetworkTTMatrix") + re_dict["NetworkBasic"] = ("src.routing.road.NetworkBasic", "NetworkBasic") + re_dict["NetworkImmediatePreproc"] = ("src.routing.road.NetworkImmediatePreproc", "NetworkImmediatePreproc") + re_dict["NetworkBasicWithStore"] = ("src.routing.road.NetworkBasicWithStore", "NetworkBasicWithStore") + re_dict["NetworkPartialPreprocessed"] = ("src.routing.road.NetworkPartialPreprocessed", "NetworkPartialPreprocessed") + re_dict["NetworkBasicWithStoreCpp"] = ("src.routing.road.NetworkBasicWithStoreCpp", "NetworkBasicWithStoreCpp") + re_dict["NetworkBasicCpp"] = ("src.routing.road.NetworkBasicCpp", "NetworkBasicCpp") + re_dict["NetworkPartialPreprocessedCpp"] = ("src.routing.road.NetworkPartialPreprocessedCpp", "NetworkPartialPreprocessedCpp") + re_dict["NetworkTTMatrix"] = ("src.routing.road.NetworkTTMatrix", "NetworkTTMatrix") # add development content if dev_content is not None: dev_re_dict = dev_content.add_dev_routing_engines() diff --git a/src/preprocessing/demand/aggregate_trip_demand.py b/src/preprocessing/demand/aggregate_trip_demand.py index d904f3c7..1d2578bd 100644 --- a/src/preprocessing/demand/aggregate_trip_demand.py +++ b/src/preprocessing/demand/aggregate_trip_demand.py @@ -5,7 +5,7 @@ import pandas as pd BASEPATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) sys.path.append(BASEPATH) -from src.routing.NetworkBasicWithStoreCpp import NetworkBasicWithStoreCpp +from src.routing.road.NetworkBasicWithStoreCpp import NetworkBasicWithStoreCpp from src.misc.safe_pathname import slugify from src.misc.globals import * diff --git a/src/preprocessing/infra/access_point_distribution_preprocessing.py b/src/preprocessing/infra/access_point_distribution_preprocessing.py index 45100e01..380ff9d6 100644 --- a/src/preprocessing/infra/access_point_distribution_preprocessing.py +++ b/src/preprocessing/infra/access_point_distribution_preprocessing.py @@ -9,7 +9,7 @@ print(MAIN_DIR) sys.path.append(MAIN_DIR) -from src.routing.NetworkBasic import NetworkBasic as Network +from src.routing.road.NetworkBasic import NetworkBasic as Network def routing_min_distance_cost_function(travel_time, travel_distance, current_node_index): """computes the customized section cost for routing (input for routing functions) diff --git a/src/preprocessing/infra/preprocess_boarding_point_distances.py b/src/preprocessing/infra/preprocess_boarding_point_distances.py index 0dfbb472..9bc19545 100644 --- a/src/preprocessing/infra/preprocess_boarding_point_distances.py +++ b/src/preprocessing/infra/preprocess_boarding_point_distances.py @@ -7,7 +7,7 @@ tum_fleet_sim_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) sys.path.append(tum_fleet_sim_path) -from src.routing.NetworkBasic import NetworkBasic as Network +from src.routing.road.NetworkBasic import NetworkBasic as Network from src.infra.BoardingPointInfrastructure import BoardingPointInfrastructure def routing_min_distance_cost_function(travel_time, travel_distance, current_node_index): diff --git a/src/preprocessing/networks/create_Xto1_preprocessing_files.py b/src/preprocessing/networks/create_Xto1_preprocessing_files.py index faae035f..3e3da8a5 100644 --- a/src/preprocessing/networks/create_Xto1_preprocessing_files.py +++ b/src/preprocessing/networks/create_Xto1_preprocessing_files.py @@ -5,11 +5,11 @@ from multiprocessing import Pool fleet_sim_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) try: - from src.routing.NetworkBasic import NetworkBasic as Network + from src.routing.road.NetworkBasic import NetworkBasic as Network except: #fleet_sim_path = r'C:\Users\ge37ser\Documents\Coding\TUM_VT_FleetSimulation\tum-vt-fleet-simulation' #to be adopted os.sys.path.append(fleet_sim_path) - from src.routing.NetworkBasic import NetworkBasic as Network + from src.routing.road.NetworkBasic import NetworkBasic as Network """ this script is used to preprocess travel time tables for the routing_engine NetworkPartialPreprocessed.py diff --git a/src/preprocessing/networks/create_partially_preprocessed_travel_time_tables.py b/src/preprocessing/networks/create_partially_preprocessed_travel_time_tables.py index 48b4b808..535ed65c 100644 --- a/src/preprocessing/networks/create_partially_preprocessed_travel_time_tables.py +++ b/src/preprocessing/networks/create_partially_preprocessed_travel_time_tables.py @@ -7,10 +7,10 @@ fleet_sim_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))) os.sys.path.append(fleet_sim_path) try: - from src.routing.NetworkBasicCpp import NetworkBasicCpp as Network + from src.routing.road.NetworkBasicCpp import NetworkBasicCpp as Network except: print("cpp router not found") - from src.routing.NetworkBasic import NetworkBasic as Network + from src.routing.road.NetworkBasic import NetworkBasic as Network """ this script is used to preprocess travel time tables for the routing_engine diff --git a/src/preprocessing/pubtrans/PTScheduleGen.py b/src/preprocessing/pubtrans/PTScheduleGen.py index f7261423..dced21fb 100755 --- a/src/preprocessing/pubtrans/PTScheduleGen.py +++ b/src/preprocessing/pubtrans/PTScheduleGen.py @@ -9,7 +9,7 @@ from scipy.stats import poisson from scipy.special import comb import plotly.graph_objects as go -from src.routing.NetworkBasic import NetworkBasic +from src.routing.road.NetworkBasic import NetworkBasic import rtree import math diff --git a/src/routing/NetworkBase.py b/src/routing/road/NetworkBase.py similarity index 100% rename from src/routing/NetworkBase.py rename to src/routing/road/NetworkBase.py diff --git a/src/routing/NetworkBasic.py b/src/routing/road/NetworkBasic.py similarity index 99% rename from src/routing/NetworkBasic.py rename to src/routing/road/NetworkBasic.py index 2f1eeeaf..dfae0693 100644 --- a/src/routing/NetworkBasic.py +++ b/src/routing/road/NetworkBasic.py @@ -23,8 +23,8 @@ # src imports # ----------- -from src.routing.NetworkBase import NetworkBase -from src.routing.routing_imports.Router import Router +from src.routing.road.NetworkBase import NetworkBase +from src.routing.road.routing_imports.Router import Router # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkBasicCpp.py b/src/routing/road/NetworkBasicCpp.py similarity index 99% rename from src/routing/NetworkBasicCpp.py rename to src/routing/road/NetworkBasicCpp.py index 44115335..652de37b 100644 --- a/src/routing/NetworkBasicCpp.py +++ b/src/routing/road/NetworkBasicCpp.py @@ -11,8 +11,8 @@ # src imports # ----------- -from src.routing.NetworkBasic import NetworkBasic -from src.routing.cpp_router.PyNetwork import PyNetwork +from src.routing.road.NetworkBasic import NetworkBasic +from src.routing.road.cpp_router.PyNetwork import PyNetwork # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkBasicWithStore.py b/src/routing/road/NetworkBasicWithStore.py similarity index 98% rename from src/routing/NetworkBasicWithStore.py rename to src/routing/road/NetworkBasicWithStore.py index d6272037..40644f18 100644 --- a/src/routing/NetworkBasicWithStore.py +++ b/src/routing/road/NetworkBasicWithStore.py @@ -22,8 +22,8 @@ # src imports # ----------- -from src.routing.NetworkBasic import NetworkBasic -from src.routing.routing_imports.Router import Router +from src.routing.road.NetworkBasic import NetworkBasic +from src.routing.road.routing_imports.Router import Router # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkBasicWithStoreCpp.py b/src/routing/road/NetworkBasicWithStoreCpp.py similarity index 98% rename from src/routing/NetworkBasicWithStoreCpp.py rename to src/routing/road/NetworkBasicWithStoreCpp.py index fbf08b32..9f70db35 100644 --- a/src/routing/NetworkBasicWithStoreCpp.py +++ b/src/routing/road/NetworkBasicWithStoreCpp.py @@ -22,8 +22,8 @@ # src imports # ----------- -from src.routing.NetworkBasicCpp import NetworkBasicCpp -from src.routing.cpp_router.PyNetwork import PyNetwork +from src.routing.road.NetworkBasicCpp import NetworkBasicCpp +from src.routing.road.cpp_router.PyNetwork import PyNetwork # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkForPreprocessing.py b/src/routing/road/NetworkForPreprocessing.py similarity index 93% rename from src/routing/NetworkForPreprocessing.py rename to src/routing/road/NetworkForPreprocessing.py index dfb54537..9f03f00e 100644 --- a/src/routing/NetworkForPreprocessing.py +++ b/src/routing/road/NetworkForPreprocessing.py @@ -1,4 +1,4 @@ -from src.routing.NetworkBasic import NetworkBasic, Node, Edge +from src.routing.road.NetworkBasic import NetworkBasic, Node, Edge class NetworkForPreprocessing(NetworkBasic): """ this network is only used in network_manipulation.py to evalute connectivity """ diff --git a/src/routing/NetworkImmediatePreproc.py b/src/routing/road/NetworkImmediatePreproc.py similarity index 97% rename from src/routing/NetworkImmediatePreproc.py rename to src/routing/road/NetworkImmediatePreproc.py index 63d21095..2e36b044 100644 --- a/src/routing/NetworkImmediatePreproc.py +++ b/src/routing/road/NetworkImmediatePreproc.py @@ -14,7 +14,7 @@ # ----------------------------- import os import logging -from src.routing.NetworkBasicWithStore import NetworkBasicWithStore +from src.routing.road.NetworkBasicWithStore import NetworkBasicWithStore # -------------------------------------------------------------------------------------------------------------------- # diff --git a/src/routing/NetworkPartialPreprocessed.py b/src/routing/road/NetworkPartialPreprocessed.py similarity index 98% rename from src/routing/NetworkPartialPreprocessed.py rename to src/routing/road/NetworkPartialPreprocessed.py index 2437ea35..102275bd 100644 --- a/src/routing/NetworkPartialPreprocessed.py +++ b/src/routing/road/NetworkPartialPreprocessed.py @@ -22,8 +22,8 @@ # src imports # ----------- -from src.routing.NetworkBasic import NetworkBasic, Node, Edge -from src.routing.routing_imports.Router import Router +from src.routing.road.NetworkBasic import NetworkBasic, Node, Edge +from src.routing.road.routing_imports.Router import Router # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkPartialPreprocessedCpp.py b/src/routing/road/NetworkPartialPreprocessedCpp.py similarity index 99% rename from src/routing/NetworkPartialPreprocessedCpp.py rename to src/routing/road/NetworkPartialPreprocessedCpp.py index 24be61a0..dbb5c2a2 100644 --- a/src/routing/NetworkPartialPreprocessedCpp.py +++ b/src/routing/road/NetworkPartialPreprocessedCpp.py @@ -22,8 +22,8 @@ # src imports # ----------- -from src.routing.NetworkBasicCpp import NetworkBasicCpp -from src.routing.cpp_router.PyNetwork import PyNetwork +from src.routing.road.NetworkBasicCpp import NetworkBasicCpp +from src.routing.road.cpp_router.PyNetwork import PyNetwork # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/NetworkTTMatrix.py b/src/routing/road/NetworkTTMatrix.py similarity index 99% rename from src/routing/NetworkTTMatrix.py rename to src/routing/road/NetworkTTMatrix.py index 2996fef9..3d338960 100644 --- a/src/routing/NetworkTTMatrix.py +++ b/src/routing/road/NetworkTTMatrix.py @@ -13,7 +13,7 @@ # src imports # ----------- -from src.routing.NetworkBase import NetworkBase +from src.routing.road.NetworkBase import NetworkBase # -------------------------------------------------------------------------------------------------------------------- # # global variables diff --git a/src/routing/cpp_router/Edge.cpp b/src/routing/road/cpp_router/Edge.cpp similarity index 100% rename from src/routing/cpp_router/Edge.cpp rename to src/routing/road/cpp_router/Edge.cpp diff --git a/src/routing/cpp_router/Edge.h b/src/routing/road/cpp_router/Edge.h similarity index 100% rename from src/routing/cpp_router/Edge.h rename to src/routing/road/cpp_router/Edge.h diff --git a/src/routing/cpp_router/Network.cpp b/src/routing/road/cpp_router/Network.cpp similarity index 100% rename from src/routing/cpp_router/Network.cpp rename to src/routing/road/cpp_router/Network.cpp diff --git a/src/routing/cpp_router/Network.h b/src/routing/road/cpp_router/Network.h similarity index 100% rename from src/routing/cpp_router/Network.h rename to src/routing/road/cpp_router/Network.h diff --git a/src/routing/cpp_router/Network.pxd b/src/routing/road/cpp_router/Network.pxd similarity index 100% rename from src/routing/cpp_router/Network.pxd rename to src/routing/road/cpp_router/Network.pxd diff --git a/src/routing/cpp_router/Node.cpp b/src/routing/road/cpp_router/Node.cpp similarity index 100% rename from src/routing/cpp_router/Node.cpp rename to src/routing/road/cpp_router/Node.cpp diff --git a/src/routing/cpp_router/Node.h b/src/routing/road/cpp_router/Node.h similarity index 100% rename from src/routing/cpp_router/Node.h rename to src/routing/road/cpp_router/Node.h diff --git a/src/routing/cpp_router/PyNetwork.pyx b/src/routing/road/cpp_router/PyNetwork.pyx similarity index 100% rename from src/routing/cpp_router/PyNetwork.pyx rename to src/routing/road/cpp_router/PyNetwork.pyx diff --git a/src/routing/cpp_router/cpp_router_checker.py b/src/routing/road/cpp_router/cpp_router_checker.py similarity index 92% rename from src/routing/cpp_router/cpp_router_checker.py rename to src/routing/road/cpp_router/cpp_router_checker.py index 6cf48311..857562bb 100644 --- a/src/routing/cpp_router/cpp_router_checker.py +++ b/src/routing/road/cpp_router/cpp_router_checker.py @@ -7,8 +7,8 @@ Fleetpy_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) sys.path.append(Fleetpy_dir) -from src.routing.NetworkBasicCpp import NetworkBasicCpp -from src.routing.NetworkBasic import NetworkBasic +from src.routing.road.NetworkBasicCpp import NetworkBasicCpp +from src.routing.road.NetworkBasic import NetworkBasic """ run this script to check if the C++ router returns the same results as the python router diff --git a/src/routing/cpp_router/setup.py b/src/routing/road/cpp_router/setup.py similarity index 100% rename from src/routing/cpp_router/setup.py rename to src/routing/road/cpp_router/setup.py diff --git a/src/routing/routing_imports/PriorityQueue_python3.py b/src/routing/road/routing_imports/PriorityQueue_python3.py similarity index 100% rename from src/routing/routing_imports/PriorityQueue_python3.py rename to src/routing/road/routing_imports/PriorityQueue_python3.py diff --git a/src/routing/routing_imports/Router.py b/src/routing/road/routing_imports/Router.py similarity index 99% rename from src/routing/routing_imports/Router.py rename to src/routing/road/routing_imports/Router.py index a818747c..32fa32ef 100644 --- a/src/routing/routing_imports/Router.py +++ b/src/routing/road/routing_imports/Router.py @@ -5,7 +5,7 @@ from . import PriorityQueue_python3 as PQ except: try: - import src.routing.routing_imports.PriorityQueue_python3 as PQ + import src.routing.road.routing_imports.PriorityQueue_python3 as PQ except: raise ImportError("couldnt import PriorityQueue_python3") diff --git a/src/routing/routing_imports/__init__.py b/src/routing/road/routing_imports/__init__.py similarity index 100% rename from src/routing/routing_imports/__init__.py rename to src/routing/road/routing_imports/__init__.py diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index 2b47bd35..09ccba97 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -1,7 +1,7 @@ # src imports # ----------- -from src.routing.NetworkBase import return_position_str +from src.routing.road.NetworkBase import return_position_str from src.misc.globals import * # -------------------------------------------------------------------------------------------------------------------- # diff --git a/src/simulation/Vehicles.py b/src/simulation/Vehicles.py index 5902b017..c95efdf5 100644 --- a/src/simulation/Vehicles.py +++ b/src/simulation/Vehicles.py @@ -14,7 +14,7 @@ if tp.TYPE_CHECKING: from src.demand.TravelerModels import RequestBase - from src.routing.NetworkBase import NetworkBase + from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.FleetControlBase import FleetControlBase LOG = logging.getLogger(__name__) From 106bce9cef2d31bb1864251411001eafa1abdb01 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 11 Dec 2025 19:18:29 +0100 Subject: [PATCH 02/31] Add Raptor CPP Router --- src/routing/pt/cpp_raptor_router/DateTime.h | 63 + .../NetworkObjects/DataStructures.h | 157 + .../NetworkObjects/GTFSObjects/Agency.cpp | 18 + .../NetworkObjects/GTFSObjects/Agency.h | 35 + .../NetworkObjects/GTFSObjects/GTFSObject.cpp | 46 + .../NetworkObjects/GTFSObjects/GTFSObject.h | 76 + .../NetworkObjects/GTFSObjects/Route.cpp | 39 + .../NetworkObjects/GTFSObjects/Route.h | 68 + .../NetworkObjects/GTFSObjects/Service.cpp | 49 + .../NetworkObjects/GTFSObjects/Service.h | 41 + .../NetworkObjects/GTFSObjects/Stop.cpp | 43 + .../NetworkObjects/GTFSObjects/Stop.h | 78 + .../NetworkObjects/GTFSObjects/Trip.cpp | 64 + .../NetworkObjects/GTFSObjects/Trip.h | 91 + src/routing/pt/cpp_raptor_router/Parser.cpp | 444 + src/routing/pt/cpp_raptor_router/Parser.h | 154 + .../pt/cpp_raptor_router/PyPTRouter.cpp | 14682 ++++++++++++++++ .../pt/cpp_raptor_router/PyPTRouter.pxd | 121 + .../pt/cpp_raptor_router/PyPTRouter.pyx | 293 + src/routing/pt/cpp_raptor_router/Raptor.cpp | 544 + src/routing/pt/cpp_raptor_router/Raptor.h | 272 + src/routing/pt/cpp_raptor_router/Utils.cpp | 130 + src/routing/pt/cpp_raptor_router/Utils.h | 164 + src/routing/pt/cpp_raptor_router/setup.py | 36 + 24 files changed, 17708 insertions(+) create mode 100644 src/routing/pt/cpp_raptor_router/DateTime.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.h create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.cpp create mode 100644 src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.h create mode 100644 src/routing/pt/cpp_raptor_router/Parser.cpp create mode 100644 src/routing/pt/cpp_raptor_router/Parser.h create mode 100644 src/routing/pt/cpp_raptor_router/PyPTRouter.cpp create mode 100644 src/routing/pt/cpp_raptor_router/PyPTRouter.pxd create mode 100644 src/routing/pt/cpp_raptor_router/PyPTRouter.pyx create mode 100644 src/routing/pt/cpp_raptor_router/Raptor.cpp create mode 100644 src/routing/pt/cpp_raptor_router/Raptor.h create mode 100644 src/routing/pt/cpp_raptor_router/Utils.cpp create mode 100644 src/routing/pt/cpp_raptor_router/Utils.h create mode 100644 src/routing/pt/cpp_raptor_router/setup.py diff --git a/src/routing/pt/cpp_raptor_router/DateTime.h b/src/routing/pt/cpp_raptor_router/DateTime.h new file mode 100644 index 00000000..410a21c8 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/DateTime.h @@ -0,0 +1,63 @@ +/** + * @file DateTime.h + * @brief Provides data structures for representing dates and times in the RAPTOR application. + * + * This header defines the Date and Time structures, along with auxiliary enums and constants, + * for handling and manipulating temporal data. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_DATETIME_H +#define RAPTOR_DATETIME_H + +#include + +/** + * @brief Represents midnight in seconds (24 hours * 3600 seconds per hour). + */ +static constexpr int MIDNIGHT = 24 * 3600; + +/** + * @brief Names of the weekdays starting from Monday. + */ +constexpr const char* weekdays_names[] = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}; + +/** + * @struct Date + * @brief Represents a specific date in the Gregorian calendar. + * + * Includes fields for the year, month, day, and the day of the week. + */ +struct Date { + int year; ///< Year of the date (e.g., 2024). + int month; ///< Month of the date (1 = January, ..., 12 = December). + int day; ///< Day of the month (1-31). + int weekday; ///< Day of the week (0 = Monday, 1 = Tuesday, ..., 6 = Sunday). +}; + +/** + * @enum Day + * @brief Represents the current or the next day for calculations. + */ +enum class Day { + CurrentDay, ///< Refers to the current day. + NextDay ///< Refers to the next day. +}; + +/** + * @struct Time + * @brief Represents a specific time of day in hours, minutes, and seconds. + */ +struct Time { + int hours; ///< Hours component of the time (0-23). + int minutes; ///< Minutes component of the time (0-59). + int seconds; ///< Seconds component of the time (0-59). +}; + +#endif //RAPTOR_DATETIME_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h new file mode 100644 index 00000000..4d4a4b45 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h @@ -0,0 +1,157 @@ +/** + * @file DataStructures.h + * @brief Defines core data structures and utility classes for the RAPTOR project. + * + * This header file includes declarations for structs like `Query`, `StopInfo`, `JourneyStep`, + * and `Journey`, which are used to represent transit queries, stop information, and journey details. + * It also provides hash functions for specific pair-based keys. + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef DATASTRUCTURES_H +#define DATASTRUCTURES_H + +#include +#include +#include +#include +#include + +#include "../DateTime.h" + +class Stop; + +/** + * @struct Query + * @brief Represents a transit query. + * + * This structure is used to define a user's query for transit planning, + * including source and target stops, the desired date, and departure time. + */ +struct Query { + std::vector> included_sources; ///< Stops in the source station with its station_stop_transfer_time (in seconds). + std::vector> included_targets; ///< Stops in the target station with its station_stop_transfer_time (in seconds). + Date date; ///< Date of the journey (year, month, day). + Time departure_time; ///< Desired departure time in the source station (in seconds from midnight). + int max_transfers; ///< Maximum number of transfers. +}; + +/** + * @struct StopInfo + * @brief Represents information about a transit stop during a journey. + * + * This structure holds details about a stop's arrival time, the trip and stop + * it depends on, and the day of operation. Values are optional to handle + * cases where a stop is unreachable or is a starting point. + */ +struct StopInfo { + std::optional arrival_seconds; ///< Arrival time in seconds, or `std::nullopt` if unreachable. + std::optional parent_trip_id; ///< ID of the parent trip, or `std::nullopt` for footpaths. + std::optional parent_stop_id; ///< ID of the parent stop, or `std::nullopt` for first stops. + std::optional day; ///< Day of arrival, or `std::nullopt` if unreachable. +}; + +/** + * @struct JourneyStep + * @brief Represents a single step in a journey. + * + * A journey step can correspond to a trip or a footpath. It contains information + * about the source and destination stops, departure and arrival times, and duration. + */ +struct JourneyStep { + std::optional trip_id; ///< ID of the trip, or `std::nullopt` for footpaths. + std::optional agency_name; ///< Name of the agency, or `std::nullopt` for footpaths. + Stop *src_stop{}; ///< Pointer to the source stop. + Stop *dest_stop{}; ///< Pointer to the destination stop. + + int departure_secs{}; ///< Departure time in seconds from midnight of the query day. + Day day{}; ///< Day of the journey step. + int duration{}; ///< Duration of the step in seconds. + int arrival_secs{}; ///< Arrival time in seconds from midnight of the query day. +}; + +/** + * @struct Journey + * @brief Represents an entire journey consisting of multiple steps. + * + * The `Journey` structure contains details about all steps in the journey, + * as well as overall departure and arrival times and durations. + */ +struct Journey { + std::vector steps; ///< Steps making up the journey. + int departure_secs; ///< Overall departure time in seconds from midnight of the query day at source station. + Day departure_day; ///< Departure day of the journey at source station. + + int arrival_secs; ///< Overall arrival time in seconds from midnight of the query day at target station. + Day arrival_day; ///< Arrival day of the journey at target station. + + int duration; ///< Total duration of the journey in seconds. + int source_transfer_time; ///< Transfer time from source station to source station stop in seconds. + int waiting_time; ///< Waiting time at the source station in seconds. + int trip_time; ///< Trip time from source station stops to target station in seconds. + + int num_transfers; ///< Number of transfers in the journey. +}; + +/** + * @struct StopTimeRecord + * @brief Represents a stop time record in the GTFS data. + * + * This struct stores information about a stop time record, including the stop ID, + * arrival time, departure time, and stop sequence. + */ +struct StopTimeRecord { + std::string stop_id; ///< The ID of the stops + int arrival_seconds; ///< The arrival time in seconds + int departure_seconds; ///< The departure time in seconds + int stop_sequence; ///< The sequence number of the stop in the trip + + bool operator<(const StopTimeRecord& other) const { + return stop_sequence < other.stop_sequence; + } +}; + +/** + * @struct pair_hash + * @brief Hash function for a pair of strings. + * + * Provides a custom hash implementation for pairs of strings, + * used in unordered containers like `std::unordered_map` and `std::unordered_set`. + */ +struct pair_hash { + /** + * @brief Computes the hash value for a pair of strings. + * @param pair The pair of strings to hash. + * @return The computed hash value. + */ + std::size_t operator()(const std::pair &pair) const { + return std::hash()(pair.first) ^ std::hash()(pair.second); + } +}; + +/** + * @struct nested_pair_hash + * @brief Hash function for nested pairs of strings. + * + * Provides a custom hash implementation for nested pairs of strings, + * used in unordered containers for hierarchical keys. + */ +struct nested_pair_hash { + /** + * @brief Computes the hash value for a nested pair of strings. + * @param nested_pair The nested pair to hash. + * @return The computed hash value. + */ + std::size_t operator()(const std::pair, std::string> &nested_pair) const { + std::size_t hash1 = pair_hash{}(nested_pair.first); // Hash of internal part + std::size_t hash2 = std::hash{}(nested_pair.second); + return hash1 ^ (hash2 << 1); + } +}; + +#endif //DATASTRUCTURES_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.cpp new file mode 100644 index 00000000..157b9eb0 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.cpp @@ -0,0 +1,18 @@ +/** + * @file Agency.cpp + * @brief Implements the Agency class. + * + * This file contains the implementation of the Agency class, which represents + * transit agencies in the GTFS dataset. + * + * @note Currently, this file serves as a placeholder for future extensions. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Agency.h" diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.h new file mode 100644 index 00000000..c486859d --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Agency.h @@ -0,0 +1,35 @@ +/** + * @file Agency.h + * @brief Defines the Agency class, representing transit agencies in the GTFS dataset. + * + * This header file declares the Agency class, which inherits from GTFSObject. + * The class serves as a representation of the GTFS "agency.txt" file, storing + * information about transit agencies. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ +#ifndef RAPTOR_AGENCY_H +#define RAPTOR_AGENCY_H + +#include "GTFSObject.h" + +/** + * @class Agency + * @brief Represents a transit agency in the GTFS data. + * + * This class inherits from GTFSObject and encapsulates the details of a transit agency. + * + * * @note This class currently acts as a placeholder and can be extended + * with specific attributes and methods relevant to transit agencies. + */ +class Agency : public GTFSObject { + +}; + + +#endif //RAPTOR_AGENCY_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.cpp new file mode 100644 index 00000000..f7d6e254 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.cpp @@ -0,0 +1,46 @@ +/** + * @file GTFSObject.cpp + * @brief Implements the GTFSObject class. + * + * This file contains the implementation of the GTFSObject class, which represents + * a generic GTFS object. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "GTFSObject.h" + +void GTFSObject::setField(const std::string &field, const std::string &value) { + fields[field] = value; +} + +std::string GTFSObject::getField(const std::string &field) const { + auto it = fields.find(field); + if (it == fields.end()) + throw std::runtime_error("Field not found: " + field); + return it->second; +} + +const std::unordered_map >FSObject::getFields() const { + return fields; +} + +bool GTFSObject::hasField(const std::string& field) const { + return fields.find(field) != fields.end(); +} + +void GTFSObject::merge(const GTFSObject &other, bool override) { + for (const auto &[key, value]: other.getFields()) { + if (hasField(key) && !override) { + // Keep the original value + continue; + } else { + fields[key] = value; + } + } +} diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.h new file mode 100644 index 00000000..5c7e0738 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/GTFSObject.h @@ -0,0 +1,76 @@ +/** + * @file GTFSObject.h + * @brief Defines the GTFSObject class, representing a generic GTFS object. + * + * This header file declares the GTFSObject class, + * which serves as a base class for all GTFS objects. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_GTFSOBJECT_H +#define RAPTOR_GTFSOBJECT_H + +#include +#include +#include +#include +#include + +#include "../../Utils.h" + +/** + * @class GTFSObject + * @brief Represents a generic GTFS object. + * + * This class serves as a base class for all GTFS objects. + * It provides a generic interface for setting and getting field values. + */ +class GTFSObject { +public: + /** + * @brief Sets the value of a field. + * @param field The name of the field. + * @param value The value to assign to the field. + */ + void setField(const std::string &field, const std::string &value); + + /** + * @brief Retrieves the value of a field. + * @param field The name of the field to retrieve. + * @return The value of the specified field. + * @throws std::runtime_error If the field does not exist. + */ + std::string getField(const std::string &field) const; + + /** + * @brief Gets all fields as an unordered map. + * @return A reference to the map of fields. + */ + const std::unordered_map &getFields() const; + + /** + * @brief Checks if a field exists. + * @param field The name of the field to check. + * @return True if the field exists, false otherwise. + */ + bool hasField(const std::string &field) const; + + /** + * @brief Merges two GTFS objects. + * @param other The GTFS object to merge with. + * @param override Whether to override existing fields. + */ + void merge(const GTFSObject &other, bool override = false); + +protected: + std::unordered_map fields; ///< Map of field names and values. + +}; + +#endif //RAPTOR_GTFSOBJECT_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.cpp new file mode 100644 index 00000000..793ad6eb --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.cpp @@ -0,0 +1,39 @@ +/** + * @file Route.cpp + * @brief Route class implementation + * + * This file contains the implementation of the Route class, which represents + * a route in the GTFS dataset. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Route.h" +#include + +void Route::addTripId(const std::string& trip_id) { + trips_ids.push_back(trip_id); +} + +void Route::addStopId(const std::string& stop_id) { + stops_ids.insert(stop_id); +} + +void Route::sortTrips(const std::function &comparator) { + std::sort(trips_ids.begin(), trips_ids.end(), comparator); +} + +const std::vector &Route::getTripsIds() const { + return trips_ids; +} + +const std::unordered_set &Route::getStopsIds() const { + return stops_ids; +} + + diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.h new file mode 100644 index 00000000..8ef0bfda --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Route.h @@ -0,0 +1,68 @@ +/** + * @file Route.h + * @brief Defines the Route class, representing a route in the GTFS dataset. + * + * This header file declares the Route class, which inherits from GTFSObject. + * The class serves as a representation of the GTFS "route.txt" file, storing + * information about a route. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_ROUTE_H +#define RAPTOR_ROUTE_H + +#include "GTFSObject.h" + +/** + * @class Route + * @brief Represents a route in the GTFS data. + * + * This class inherits from GTFSObject and manages trip and stop information + * for a specific route. It provides methods for adding trip and stop IDs, + * retrieving sorted data, and defining custom sorting mechanisms. + * + */ +class Route : public GTFSObject { +public: + /** + * @brief Adds a trip ID to the route. + * @param trip_id The ID of the trip to add. + */ + void addTripId(const std::string &trip_id); + + /** + * @brief Adds a stop ID to the route. + * @param stop_id The ID of the stop to add. + */ + void addStopId(const std::string &stop_id); + + /** + * @brief Sorts the trips using a custom comparator. + * @param comparator A function defining the sorting criteria. + */ + void sortTrips(const std::function &comparator); + + /** + * @brief Retrieves the list of trip IDs. + * @return A constant reference to the vector of trip IDs. + */ + const std::vector &getTripsIds() const; + + /** + * @brief Retrieves the list of stop IDs. + * @return A constant reference to the set of stop IDs. + */ + const std::unordered_set &getStopsIds() const; + +private: + std::vector trips_ids; ///< Vector of trip IDs, sorted by earliest arrival time + std::unordered_set stops_ids; ///< Set of stop IDs +}; + +#endif //RAPTOR_ROUTE_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.cpp new file mode 100644 index 00000000..6385523a --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.cpp @@ -0,0 +1,49 @@ +/** + * @file Service.cpp + * @brief Implements the Service class. + * + * This file contains the implementation of the Service class, which represents + * active days of a service in the GTFS dataset. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Service.h" + +bool Service::isActive(Date date) const { + int date_int = Utils::dateToInt(date); + int start_date = std::stoi(getField("start_date")); + int end_date = std::stoi(getField("end_date")); + + if (included_dates.find(date_int) != included_dates.end()) { + return true; + } + + if (excluded_dates.find(date_int) != excluded_dates.end()) { + return false; + } + + if (date_int < start_date || date_int > end_date) { + return false; + } + + return active_weekdays.find(date.weekday) != active_weekdays.end(); +} + +void Service::addActiveWeekday(int weekday) { + active_weekdays.insert(weekday); +} + +void Service::addExceptionDate(int date_int, int type) { + if (type == 1) { + included_dates.insert(date_int); + } else if (type == 2) { + excluded_dates.insert(date_int); + } +} + diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.h new file mode 100644 index 00000000..0f5ef262 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Service.h @@ -0,0 +1,41 @@ +/** + * @file Service.h + * @brief Defines the Service class, representing active days for a service. + * + * This header file declares the Service class, which inherits from GTFSObject. + * The class serves as a representation of the GTFS "calendar.txt" file and "calendar_dates.txt" file, storing + * information about active days of a service. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_SERVICE_H +#define RAPTOR_SERVICE_H + +#include "GTFSObject.h" + +/** + * @class Service + * @brief Represents active days for a service in the GTFS data. + * + * This class inherits from GTFSObject and encapsulates the details of active days for a service. + */ +class Service : public GTFSObject { +public: + bool isActive(Date date) const; + void addActiveWeekday(int weekday); + void addExceptionDate(int date_int, int type); + +private: + std::unordered_set active_weekdays; // 0-6, 0 = monday, 6 = sunday + std::unordered_set included_dates; // exception type 1 + std::unordered_set excluded_dates; // exception type 2 +}; + +#endif //RAPTOR_SERVICE_H + diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.cpp new file mode 100644 index 00000000..1c399d05 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.cpp @@ -0,0 +1,43 @@ +/** + * @file Stop.cpp + * @brief Stop class implementation + * + * This file contains the implementation of the Stop class, which represents + * a stop in the GTFS dataset. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Stop.h" + +void Stop::addRouteKey(const std::pair &route_key) { + routes_keys.insert(route_key); +} + +void Stop::addFootpath(const std::string &target_id, int duration) { + footpaths[target_id] = duration; +} + +const std::unordered_set, pair_hash> &Stop::getRouteKeys() const { + return routes_keys; +} + +int Stop::getFootpathTime(const std::string &target_id) const { + if (!hasFootpath(target_id)) + throw std::runtime_error("No footpath to " + target_id); + return footpaths.at(target_id); +} + +bool Stop::hasFootpath(const std::string &target_id) const { + return footpaths.find(target_id) != footpaths.end(); +} + +const std::unordered_map &Stop::getFootpaths() const { + return footpaths; +} + diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.h new file mode 100644 index 00000000..9c47e64b --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Stop.h @@ -0,0 +1,78 @@ +/** + * @file Stop.h + * @brief Defines the Stop class, representing a stop in the GTFS dataset. + * + * This header file declares the Stop class, which inherits from GTFSObject. + * The class serves as a representation of the GTFS "stop.txt" file, storing + * information about a stop. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_STOP_H +#define RAPTOR_STOP_H + +#include "GTFSObject.h" +#include "../DataStructures.h" + +/** + * @class Stop + * @brief Represents a stop in the GTFS data. + * + * This class inherits from GTFSObject and manages stop time and route information + * for a specific stop. It provides methods for adding stop time and route IDs, + * retrieving sorted data, and defining custom sorting mechanisms. + * + */ +class Stop : public GTFSObject { +public: + /** + * @brief Adds a route key (route_id, direction_id) to the stop. + * @param route_key A pair representing the route key. + */ + void addRouteKey(const std::pair &route_key); + + /** + * @brief Adds a footpath/transfer to another stop. + * @param target_id The ID of the other stop. + * @param duration The duration of the footpath/transfer in seconds. + */ + void addFootpath(const std::string &target_id, int duration); + + /** + * @brief Retrieves the set of route keys. + * @return A constant reference to the unordered set of route keys. + */ + const std::unordered_set, pair_hash> &getRouteKeys() const; + + /** + * @brief Retrieves the transfer time to another stop. + * @param target_id The ID of the other stop. + * @return The transfer time in seconds. + */ + int getFootpathTime(const std::string &target_id) const; + + /** + * @brief Checks if there is a transfer to another stop. + * @param target_id The ID of the other stop. + * @return True if there is a transfer, false otherwise. + */ + bool hasFootpath(const std::string &target_id) const; + + /** + * @brief Retrieves the map of footpaths. + * @return A constant reference to the map of footpaths. + */ + const std::unordered_map &getFootpaths() const; + +private: + std::unordered_set, pair_hash> routes_keys; ///< Set of route keys (route_id, direction_id) + std::unordered_map footpaths; ///< Map of footpaths to other stops +}; + +#endif //RAPTOR_STOP_H diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.cpp b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.cpp new file mode 100644 index 00000000..b1411272 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.cpp @@ -0,0 +1,64 @@ +/** + * @file Trip.cpp + * @brief Trip class implementation + * + * This file contains the implementation of the Trip class, which represents + * a trip in the GTFS dataset. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Trip.h" + +void Trip::addStopTimeRecord(const StopTimeRecord &record) { + stop_time_records_.push_back(record); +} + +const StopTimeRecord* Trip::getStopTimeRecord(const std::string &stop_id) const { + auto it = std::find_if(stop_time_records_.begin(), stop_time_records_.end(), + [&](const StopTimeRecord &record) { + return record.stop_id == stop_id; + }); + if (it == stop_time_records_.end()) { + return nullptr; + } + return &(*it); +} + +const std::vector &Trip::getStopTimeRecords() const { + return stop_time_records_; +} + +void Trip::sortStopTimeRecords() { + std::sort(stop_time_records_.begin(), stop_time_records_.end()); + is_sorted_ = true; +} + +std::vector Trip::getStopTimeRecordsAfter(const std::string &stop_id) const { + auto it = std::find_if(stop_time_records_.begin(), stop_time_records_.end(), [&](const StopTimeRecord &record) { + return record.stop_id == stop_id; + }); + + if (it == stop_time_records_.end()) { + return {}; + } + + return std::vector(it + 1, stop_time_records_.end()); +} + +bool Trip::isActive(Day day) const { + return active_days_.at(day); +} + +void Trip::setActive(Day day, bool is_active) { + active_days_[day] = is_active; +} + +bool Trip::isSorted() const { + return is_sorted_; +} diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.h new file mode 100644 index 00000000..0c72d55e --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/GTFSObjects/Trip.h @@ -0,0 +1,91 @@ +/** + * @file Trip.h + * @brief Defines the Trip class, representing a trip in the GTFS dataset. + * + * This header file declares the Trip class, which inherits from GTFSObject. + * The class serves as a representation of the GTFS "trip.txt" file, storing + * information about a trip. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_TRIP_H +#define RAPTOR_TRIP_H + +#include "GTFSObject.h" +#include "../DataStructures.h" + +/** + * @class Trip + * @brief Represents a trip in the GTFS data. + * + * This class inherits from GTFSObject and manages stop time information + * for a specific trip. It provides methods for adding stop time records, + * retrieving sorted data, and defining custom sorting mechanisms. + * + */ +class Trip : public GTFSObject { +public: + /** + * @brief Adds a stop time record to the trip. + * @param record The stop time record to add. + */ + void addStopTimeRecord(const StopTimeRecord &record); + + /** + * @brief Retrieves the stop time record for a specific stop. + * @param stop_id The ID of the stop to retrieve the stop time record for. + * @return A constant pointer to the stop time record for the specified stop. If the stop is not found, returns nullptr. + */ + const StopTimeRecord* getStopTimeRecord(const std::string &stop_id) const; + + /** + * @brief Retrieves the stop time records. + * @return A constant reference to the stop time records. + */ + const std::vector &getStopTimeRecords() const; + + /** + * @brief Sorts the stop time records. + */ + void sortStopTimeRecords(); + + /** + * @brief Retrieves the stop time records after a specific stop. + * @param stop_id The ID of the stop to retrieve the stop time records after. + * @return A vector of stop time records after the specified stop. + */ + std::vector getStopTimeRecordsAfter(const std::string &stop_id) const; + + /** + * @brief Sets the active status for a specific day. + * @param day + * @param is_active + */ + void setActive(Day day, bool is_active); + + /** + * @brief Checks if a specific day is active. + * @param day + * @return True if the day is active, false otherwise. + */ + bool isActive(Day day) const; + + /** + * @brief Checks if the stop time records are sorted. + * @return True if the stop time records are sorted, false otherwise. + */ + bool isSorted() const; + +private: + std::unordered_map active_days_; ///< Map of active days for the trip + std::vector stop_time_records_; ///< Vector of stop-time records, sorted by stopTime's sequence + bool is_sorted_; ///< Whether the stop time records are sorted +}; + +#endif //RAPTOR_TRIP_H diff --git a/src/routing/pt/cpp_raptor_router/Parser.cpp b/src/routing/pt/cpp_raptor_router/Parser.cpp new file mode 100644 index 00000000..0b1d1704 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Parser.cpp @@ -0,0 +1,444 @@ +/** + * @file Parser.cpp + * @brief Implementation of the Parser class + * + * This file contains the implementation of the Parser class, + * which is responsible for parsing GTFS data. + * + * @author Maria + * @date 11/20/2024 + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Parser.h" + +Parser::Parser(std::string directory) : inputDirectory(std::move(directory)) { + // // Record the start time + // auto start_time = std::chrono::high_resolution_clock::now(); + + // std::cout << "Parsing GTFS data from " << inputDirectory << "..." << std::endl; + parseData(); + + // std::cout << "Associating data..." << std::endl; + associateData(); + + // // Record the end time + // auto end_time = std::chrono::high_resolution_clock::now(); + + // // Calculate the duration + // auto duration = std::chrono::duration_cast(end_time - start_time); + + // std::cout << std::fixed << std::setprecision(2) + // << "Parsing completed in " << (duration.count() / 1000.0) << " seconds." << std::endl; +} + +void Parser::parseData() { + //The order of parsing is important due + // std::cout << "Parsing agencies..." << std::endl; + parseAgencies(); + + // std::cout << "Parsing calendars and calendar dates..." << std::endl; + parseServices(); + + // std::cout << "Parsing stop times..." << std::endl; + parseStopTimes(); + + // std::cout << "Parsing trips..." << std::endl; + parseTrips(); + + // std::cout << "Parsing routes..." << std::endl; + parseRoutes(); + + // std::cout << "Parsing stops..." << std::endl; + parseStops(); + + // std::cout << "Parsing transfers..." << std::endl; + parseTransfers(); +} + +void Parser::parseAgencies() { + std::ifstream file(inputDirectory + "/agency_fp.txt"); + + if (!file.is_open()) + throw std::runtime_error("Could not open agency_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + Agency agency; + + for (size_t i = 0; i < fields.size(); ++i) + agency.setField(fields[i], tokens[i]); + + agencies_[agency.getField("agency_id")] = agency; + } +} + +void Parser::parseServices() { + // 1. Parse calendar_fp.txt + std::ifstream file(inputDirectory + "/calendar_fp.txt"); + if (!file.is_open()) + throw std::runtime_error("Could not open calendar_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + Service service; + + for (size_t i = 0; i < fields.size(); ++i) + service.setField(fields[i], tokens[i]); + + // Register active_weekdays: 0-6, 0 = monday, 6 = sunday + for (int i = 0; i < 7; ++i) { + std::string weekdays_name = weekdays_names[i]; + if (service.getField(weekdays_name) == "1") { + service.addActiveWeekday(i); + } + } + + services_[service.getField("service_id")] = service; + } + + // 2. Parse calendar_dates.txt + std::ifstream dates_file(inputDirectory + "/calendar_dates_fp.txt"); + if (!dates_file.is_open()) + // This file is an optional file, so we don't throw an error if it's not found + return; + + std::getline(dates_file, line); + Utils::clean(line); + fields = Utils::split(line, ','); + + while (std::getline(dates_file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + GTFSObject calendar_date; + + for (size_t i = 0; i < fields.size(); ++i) + calendar_date.setField(fields[i], tokens[i]); + + std::string service_id = calendar_date.getField("service_id"); + + if (services_.find(service_id) != services_.end()) { + int date = std::stoi(calendar_date.getField("date")); + int type = std::stoi(calendar_date.getField("exception_type")); + + services_[service_id].addExceptionDate(date, type); + } + } +} + +void Parser::parseStopTimes() { + std::ifstream file(inputDirectory + "/stop_times_fp.txt"); + if (!file.is_open()) + throw std::runtime_error("Could not open stop_times_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + GTFSObject stop_time; + + for (size_t i = 0; i < fields.size(); ++i) + stop_time.setField(fields[i], tokens[i]); + + std::string trip_id = stop_time.getField("trip_id"); + std::string stop_id = stop_time.getField("stop_id"); + int stop_sequence = std::stoi(stop_time.getField("stop_sequence")); + // Convert arrival_time and departure_time to seconds + // If the departure_time is on the next day, add 24 hours to it + int arrival_seconds = Utils::timeToSeconds(stop_time.getField("arrival_time")); + int departure_seconds = Utils::timeToSeconds(stop_time.getField("departure_time")); + if (departure_seconds < arrival_seconds) { + departure_seconds += MIDNIGHT; + } + + // 1. Register active trip ids and corresponding stop time records + StopTimeRecord record = {stop_id, arrival_seconds, departure_seconds, stop_sequence}; + + if (trips_.find(trip_id) == trips_.end()) { + Trip trip; + trips_[trip_id] = trip; + } + trips_[trip_id].addStopTimeRecord(record); + + // 2. Register active stop ids + if (stops_.find(stop_id) == stops_.end()) { + Stop stop; + stops_[stop_id] = stop; + } + } +} + +void Parser::parseTrips() { + std::ifstream file(inputDirectory + "/trips_fp.txt"); + if (!file.is_open()) + throw std::runtime_error("Could not open trips_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + Trip trip; + + for (size_t i = 0; i < fields.size(); ++i) + trip.setField(fields[i], tokens[i]); + + // Only parse trips that are effective + std::string trip_id = trip.getField("trip_id"); + if (trips_.find(trip_id) != trips_.end()) { + std::string route_id = trip.getField("route_id"); + std::string direction_id = trip.getField("direction_id"); + + trips_[trip_id].setField("route_id", route_id); + trips_[trip_id].setField("direction_id", direction_id); + trips_[trip_id].setField("service_id", trip.getField("service_id")); + + // Register effective routes + auto route_key = std::make_pair(route_id, direction_id); + if (routes_.find(route_key) == routes_.end()) { + Route route; + routes_[route_key] = route; + } + routes_[route_key].addTripId(trip_id); + } + } +} + +void Parser::parseRoutes() { + std::ifstream file(inputDirectory + "/routes_fp.txt"); + + if (!file.is_open()) + throw std::runtime_error("Could not open routes_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + Route route; + for (size_t i = 0; i < fields.size(); ++i) + route.setField(fields[i], tokens[i]); + + // If there is only one agency, agency_id field is optional + if (!route.hasField("agency_id")) + route.setField("agency_id", agencies_.begin()->second.getField("agency_id")); + + // Iterate through all existing (route_id, direction_id) pairs in routes_ + for (auto &[key, r]: routes_) { + auto [route_id, direction_id] = key; + if (route_id == route.getField("route_id")) { + // Merge two routes with the same route_id, keep the original route + r.merge(route, false); + } + } + } +} + +void Parser::parseStops() { + std::ifstream file(inputDirectory + "/stops_fp.txt"); + + if (!file.is_open()) + throw std::runtime_error("Could not open stops_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + Stop stop; + for (size_t i = 0; i < fields.size(); ++i) + stop.setField(fields[i], tokens[i]); + + std::string stop_id = stop.getField("stop_id"); + + if (stops_.find(stop_id) != stops_.end()) { + stops_[stop_id].merge(stop, false); + } + } +} + +void Parser::parseTransfers() { + std::ifstream file(inputDirectory + "/transfers_fp.txt"); + if (!file.is_open()) + throw std::runtime_error("Could not open transfers_fp.txt"); + + std::string line; + std::getline(file, line); + Utils::clean(line); + std::vector fields = Utils::split(line, ','); + + while (std::getline(file, line)) { + Utils::clean(line); + + if (line.empty()) continue; + + std::vector tokens = Utils::split(line, ','); + + if (tokens.size() != fields.size()) + throw std::runtime_error("Mismatched number of tokens and fields"); + + GTFSObject transfer; + for (size_t i = 0; i < fields.size(); ++i) + transfer.setField(fields[i], tokens[i]); + + int min_transfer_time = static_cast(std::stof(transfer.getField("min_transfer_time"))); + + std::string from_stop_id = transfer.getField("from_stop_id"); + std::string to_stop_id = transfer.getField("to_stop_id"); + + if (stops_.find(from_stop_id) != stops_.end() && + stops_.find(to_stop_id) != stops_.end()) { + stops_[from_stop_id].addFootpath(to_stop_id, min_transfer_time); + } + } +} + +void Parser::associateData() { + // 0. Check data effectiveness of all data structures + + + // 1. Sort trip time records in stop_times_ + for (auto &[key, trip]: trips_) { + trip.sortStopTimeRecords(); + } + + // 2. Update routes_ with trips_ + for (auto &[route_key, route]: routes_) { + // Sort trips in the route by arrival time of the first stop time record + route.sortTrips( + [&](const std::string &a, const std::string &b) { + const Trip &tripA = trips_.at(a); + const Trip &tripB = trips_.at(b); + + // Find the first stop_time record of the trip + const StopTimeRecord &stopTimeA = tripA.getStopTimeRecords().front(); + const StopTimeRecord &stopTimeB = tripB.getStopTimeRecords().front(); + + int timeA = stopTimeA.arrival_seconds; + int timeB = stopTimeB.arrival_seconds; + + return timeA < timeB; + } + ); + + // Find all possible stops ids in the route + for (const auto &trip_id: route.getTripsIds()) { + const Trip &trip = trips_[trip_id]; + for (const auto &stop_time_record: trip.getStopTimeRecords()) { + route.addStopId(stop_time_record.stop_id); + } + } + } + + // routes_[{"R01", "0"}] = { + // trips_ids: ["T101", "T102", "T103"], + // stops_ids: ["S001", "S002", "S004", "S005"] + // }; + + // 3. Associate routes to stops + for (auto &[route_key, route]: routes_) { + for (const auto &stop_id: route.getStopsIds()) { + stops_[stop_id].addRouteKey(route_key); + } + } +} + +std::unordered_map Parser::getAgencies() { + return agencies_; +} + +std::unordered_map Parser::getServices() { + return services_; +} + +std::unordered_map Parser::getStops() { + return stops_; +} + +std::unordered_map, Route, pair_hash> Parser::getRoutes() { + return routes_; +} + +std::unordered_map Parser::getTrips() { + return trips_; +} \ No newline at end of file diff --git a/src/routing/pt/cpp_raptor_router/Parser.h b/src/routing/pt/cpp_raptor_router/Parser.h new file mode 100644 index 00000000..6715fbf2 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Parser.h @@ -0,0 +1,154 @@ +/** + * @file Parser.h + * @brief Provides the Parser class for parsing GTFS data files. + * + * This header file declares the Parser class, which is responsible for parsing + * GTFS data files and associating the data to construct a transit network. + * + * @author Maria + * @date 11/20/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef PARSE_H +#define PARSE_H + +#include // for file input +#include // for string stream +#include // for input and output +#include // for timing + +#include "Utils.h" // for hash functions +#include "DateTime.h" // for Date and Time + +#include "NetworkObjects/GTFSObjects/GTFSObject.h" // for GTFSObject +#include "NetworkObjects/DataStructures.h" // for DataStructures +#include "NetworkObjects/GTFSObjects/Agency.h" // for Agency +#include "NetworkObjects/GTFSObjects/Service.h" // for Calendar and CalendarDate +#include "NetworkObjects/GTFSObjects/Route.h" // for Route +#include "NetworkObjects/GTFSObjects/Stop.h" // for Stop +#include "NetworkObjects/GTFSObjects/Trip.h" // for Trip + +/** + * @class Parser + * @brief Class for parsing GTFS data files and organizing the information. + * + * This class is responsible for parsing various GTFS data files such as agencies, calendars, stops, routes, + * trips, and stop times. It stores the parsed data in appropriate data structures and allows access to the + * parsed information. + */ +class Parser { +private: + + std::string inputDirectory; /**< Directory where the input files are located. */ + + /** + * Maps to store parsed data. + */ + std::unordered_map agencies_; ///< A map from agency IDs to Agency objects. + std::unordered_map services_; ///< A map from service IDs to Service objects. + std::unordered_map stops_; ///< A map from stop IDs to Stop objects. + std::unordered_map, Route, pair_hash> routes_; ///< A map from (route_id, direction_id) to Route objects. + std::unordered_map trips_; ///< A map from trip IDs to Trip objects. + + /** + *@brief Parses the GTFS data files and stores the results in the appropriate maps. + */ + void parseData(); + + /** + * @brief Parses the agencies file and stores the results in the agencies_ map. + */ + void parseAgencies(); + + /** + * @brief Parses the calendars file and the calendar_dates file, + * stores the results in the services_ map. + */ + void parseServices(); + + /** + * @brief Parses the stop times file and stores the results in the stop_times_ map. + */ + void parseStopTimes(); + + /** + * @brief Parses the trips file and stores the results in the trips_ map. + */ + void parseTrips(); + + /** + * @brief Parses the routes file and stores the results in the routes_ map. + */ + void parseRoutes(); + + /** + * @brief Parses the stops file and stores the results in the stops_ map. + */ + void parseStops(); + + /** + * @brief Parses the transfers file and stores the results in the transfers_ map. + */ + void parseTransfers(); + + /** + * @brief Associates data across various GTFS components (routes, trips, stops, etc.). + * + * This method processes the data from different GTFS files and associates the relevant information + * such as matching trips with corresponding stops and stop times. + */ + void associateData(); + +public: + + /** + * @brief Constructor for the Parser class. + * + * Initializes the parser with the specified directory containing the GTFS data files. + * + * @param[in] directory Path to the directory containing the GTFS files. + */ + explicit Parser(std::string directory); + + /** + * @brief Gets the parsed agencies data. + * + * @return A map of agency IDs to Agency objects. + */ + [[nodiscard]] std::unordered_map getAgencies(); + + /** + * @brief Gets the parsed services data. + * + * @return A map of service IDs to Service objects. + */ + [[nodiscard]] std::unordered_map getServices(); + + + /** + * @brief Gets the parsed stops data. + * + * @return A map of stop IDs to Stop objects. + */ + [[nodiscard]] std::unordered_map getStops(); + + /** + * @brief Gets the parsed routes data. + * + * @return A map of (route_id, direction_id) pairs to Route objects. + */ + [[nodiscard]] std::unordered_map, Route, pair_hash> getRoutes(); + + /** + * @brief Gets the parsed trips data. + * + * @return A map of trip IDs to Trip objects. + */ + [[nodiscard]] std::unordered_map getTrips(); +}; + +#endif //PARSE_H diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp b/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp new file mode 100644 index 00000000..7606e7fb --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp @@ -0,0 +1,14682 @@ +/* Generated by Cython 3.0.11 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [ + "DateTime.h", + "NetworkObjects\\DataStructures.h", + "NetworkObjects\\GTFSObjects\\Agency.h", + "NetworkObjects\\GTFSObjects\\GTFSObject.h", + "NetworkObjects\\GTFSObjects\\Route.h", + "NetworkObjects\\GTFSObjects\\Service.h", + "NetworkObjects\\GTFSObjects\\Stop.h", + "NetworkObjects\\GTFSObjects\\Trip.h", + "Parser.h", + "Raptor.h" + ], + "extra_compile_args": [ + "/std:c++20" + ], + "include_dirs": [ + "." + ], + "language": "c++", + "name": "PyPTRouter", + "sources": [ + "PyPTRouter.pyx", + ".\\Parser.cpp", + ".\\Raptor.cpp", + ".\\Utils.cpp", + ".\\NetworkObjects\\GTFSObjects\\Agency.cpp", + ".\\NetworkObjects\\GTFSObjects\\GTFSObject.cpp", + ".\\NetworkObjects\\GTFSObjects\\Route.cpp", + ".\\NetworkObjects\\GTFSObjects\\Service.cpp", + ".\\NetworkObjects\\GTFSObjects\\Stop.cpp", + ".\\NetworkObjects\\GTFSObjects\\Trip.cpp" + ] + }, + "module_name": "PyPTRouter" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#if defined(CYTHON_LIMITED_API) && 0 + #ifndef Py_LIMITED_API + #if CYTHON_LIMITED_API+0 > 0x03030000 + #define Py_LIMITED_API CYTHON_LIMITED_API + #else + #define Py_LIMITED_API 0x03030000 + #endif + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.7+ or Python 3.3+. +#else +#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API +#define __PYX_EXTRA_ABI_MODULE_NAME "limited" +#else +#define __PYX_EXTRA_ABI_MODULE_NAME "" +#endif +#define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." +#define CYTHON_HEX_VERSION 0x03000BF0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #define HAVE_LONG_LONG +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #undef CYTHON_CLINE_IN_TRACEBACK + #define CYTHON_CLINE_IN_TRACEBACK 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 1 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 +#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #endif +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_NOGIL 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #if PY_VERSION_HEX < 0x030400a1 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #elif !defined(CYTHON_USE_TP_FINALIZE) + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #if PY_VERSION_HEX < 0x030600B1 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) + #endif + #if PY_VERSION_HEX < 0x030700A3 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if !defined(CYTHON_VECTORCALL) +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) +#endif +#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + #endif + #endif + #if _MSC_VER < 1300 + #ifdef _WIN64 + typedef unsigned long long __pyx_uintptr_t; + #else + typedef unsigned int __pyx_uintptr_t; + #endif + #else + #ifdef _WIN64 + typedef unsigned __int64 __pyx_uintptr_t; + #else + typedef unsigned __int32 __pyx_uintptr_t; + #endif + #endif +#else + #include + typedef uintptr_t __pyx_uintptr_t; +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +#ifndef __cplusplus + #error "Cython files generated with the C++ option must be compiled with a C++ compiler." +#endif +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #else + #define CYTHON_INLINE inline + #endif +#endif +template +void __Pyx_call_destructor(T& x) { + x.~T(); +} +template +class __Pyx_FakeReference { + public: + __Pyx_FakeReference() : ptr(NULL) { } + __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } + T *operator->() { return ptr; } + T *operator&() { return ptr; } + operator T&() { return *ptr; } + template bool operator ==(const U& other) const { return *ptr == other; } + template bool operator !=(const U& other) const { return *ptr != other; } + template bool operator==(const __Pyx_FakeReference& other) const { return *ptr == *other.ptr; } + template bool operator!=(const __Pyx_FakeReference& other) const { return *ptr != *other.ptr; } + private: + T *ptr; +}; + +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_DefaultClassType PyClass_Type + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } + #ifndef CO_OPTIMIZED + #define CO_OPTIMIZED 0x0001 + #endif + #ifndef CO_NEWLOCALS + #define CO_NEWLOCALS 0x0002 + #endif + #ifndef CO_VARARGS + #define CO_VARARGS 0x0004 + #endif + #ifndef CO_VARKEYWORDS + #define CO_VARKEYWORDS 0x0008 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x0200 + #endif + #ifndef CO_GENERATOR + #define CO_GENERATOR 0x0020 + #endif + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x0080 + #endif +#elif PY_VERSION_HEX >= 0x030B0000 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); + if (!empty_bytes) return NULL; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); + Py_DECREF(empty_bytes); + return result; + } +#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +#endif +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 +#endif +#ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#elif CYTHON_BACKPORT_VECTORCALL + typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_MAJOR_VERSION >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if PY_MAJOR_VERSION < 3 + #if CYTHON_COMPILING_IN_PYPY + #if PYPY_VERSION_NUM < 0x07030600 + #if defined(__cplusplus) && __cplusplus >= 201402L + [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] + #elif defined(__GNUC__) || defined(__clang__) + __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) + #elif defined(_MSC_VER) + __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) + #endif + static CYTHON_INLINE int PyGILState_Check(void) { + return 0; + } + #else // PYPY_VERSION_NUM < 0x07030600 + #endif // PYPY_VERSION_NUM < 0x07030600 + #else + static CYTHON_INLINE int PyGILState_Check(void) { + PyThreadState * tstate = _PyThreadState_Current; + return tstate && (tstate == PyGILState_GetThisThreadState()); + } + #endif +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) + #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) + #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) +#else + #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) +#endif +#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) + #undef PyUnicode_Contains + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#if CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define __Pyx_Py3Int_Check(op) PyLong_Check(op) + #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#else + #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) + #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #define __PYX_EXTERN_C extern "C++" +#endif + +#define __PYX_HAVE__PyPTRouter +#define __PYX_HAVE_API__PyPTRouter +/* Early includes */ +#include +#include +#include "ios" +#include "new" +#include "stdexcept" +#include "typeinfo" +#include +#include + + #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600) + // move should be defined for these versions of MSVC, but __cplusplus isn't set usefully + #include + + namespace cython_std { + template typename std::remove_reference::type&& move(T& t) noexcept { return std::move(t); } + template typename std::remove_reference::type&& move(T&& t) noexcept { return std::move(t); } + } + + #endif + +#include +#include +#include "DateTime.h" +#include "NetworkObjects/DataStructures.h" +#include "NetworkObjects/GTFSObjects/GTFSObject.h" +#include "NetworkObjects/GTFSObjects/Stop.h" +#include "NetworkObjects/GTFSObjects/Agency.h" +#include "NetworkObjects/GTFSObjects/Service.h" +#include "NetworkObjects/GTFSObjects/Route.h" +#include "NetworkObjects/GTFSObjects/Trip.h" +#include "Parser.h" +#include "Raptor.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +#include +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = (char) c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#include +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char *__pyx_f[] = { + "PyPTRouter.pyx", + "", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* ForceInitThreads.proto */ +#ifndef __PYX_FORCE_INIT_THREADS + #define __PYX_FORCE_INIT_THREADS 0 +#endif + +/* EnumClassDecl.proto */ +#if defined (_MSC_VER) + #if _MSC_VER >= 1910 + #define __PYX_ENUM_CLASS_DECL enum + #else + #define __PYX_ENUM_CLASS_DECL + #endif +#else + #define __PYX_ENUM_CLASS_DECL enum +#endif + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +struct __pyx_obj_10PyPTRouter_PyPTRouter; + +/* "PyPTRouter.pyx":10 + * from datetime import datetime + * + * cdef class PyPTRouter: # <<<<<<<<<<<<<< + * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping + * + */ +struct __pyx_obj_10PyPTRouter_PyPTRouter { + PyObject_HEAD + struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *__pyx_vtab; + Raptor *raptor_ptr; +}; + + + +struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter { + PyObject *(*_convert_journey_to_dict)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct Journey, bool); + PyObject *(*_day_to_str)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, __PYX_ENUM_CLASS_DECL Day); + PyObject *(*_convert_journey_step)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct JourneyStep); +}; +static struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *__pyx_vtabptr_10PyPTRouter_PyPTRouter; +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) + #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() +#endif + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); +#define __Pyx_PyObject_Dict_GetItem(obj, name)\ + (likely(PyDict_CheckExact(obj)) ?\ + __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) +#else +#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) +#endif + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* MoveIfSupported.proto */ +#if CYTHON_USE_CPP_STD_MOVE + #include + #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) +#else + #define __PYX_STD_MOVE_IF_SUPPORTED(x) x +#endif + +/* TupleAndListFromArray.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) +#else + #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) +#endif +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) + #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) +#else + #define __Pyx_Arg_NewRef_VARARGS(arg) arg + #define __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_Arg_FASTCALL(args, i) args[i] + #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif + #define __Pyx_Arg_NewRef_FASTCALL(arg) arg /* no-op, __Pyx_Arg_FASTCALL is direct and this needs + to have the same reference counting */ + #define __Pyx_Arg_XDECREF_FASTCALL(arg) +#else + #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS + #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) + #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) +#else +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, + const char* function_name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#if !CYTHON_VECTORCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if !CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03080000 + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets() + #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) +#else + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif +#endif +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* PyObjectFormatSimple.proto */ +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#elif PY_MAJOR_VERSION < 3 + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ + PyObject_Format(s, f)) +#elif CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) :\ + likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) :\ + PyObject_Format(s, f)) +#else + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 + L->ob_item[len] = x; + #else + PyList_SET_ITEM(list, len, x); + #endif + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* append.proto */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); + +/* IncludeCppStringH.proto */ +#include + +/* decode_c_string_utf16.proto */ +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = 0; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = -1; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = 1; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} + +/* decode_c_bytes.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( + const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); + +/* decode_cpp_string.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_cpp_string( + std::string cppstring, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + return __Pyx_decode_c_bytes( + cppstring.data(), cppstring.size(), start, stop, encoding, errors, decode_func); +} + +/* KeywordStringCheck.proto */ +static int __Pyx_CheckKeywordStrings(PyObject *kw, const char* function_name, int kw_allowed); + +/* IncludeStructmemberH.proto */ +#include + +/* FixUpExtensionType.proto */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); +#endif + +/* PyObjectCallNoArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* ValidateBasesTuple.proto */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); +#endif + +/* PyType_Ready.proto */ +CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PyObject_GenericGetAttr.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr +#endif + +/* SetVTable.proto */ +static int __Pyx_SetVtable(PyTypeObject* typeptr , void* vtable); + +/* GetVTable.proto */ +static void* __Pyx_GetVtable(PyTypeObject *type); + +/* MergeVTables.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_MergeVtables(PyTypeObject *type); +#endif + +/* SetupReduce.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_setup_reduce(PyObject* type_obj); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportDottedModule.proto */ +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); +#endif + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* FetchSharedCythonModule.proto */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto */ +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); +#else +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); +#endif + +/* PyMethodNew.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + typesModule = PyImport_ImportModule("types"); + if (!typesModule) return NULL; + methodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + if (!methodType) return NULL; + result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); + Py_DECREF(methodType); + return result; +} +#elif PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#else + #define __Pyx_PyMethod_New PyMethod_New +#endif + +/* PyVectorcallFastCallDict.proto */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_BACKPORT_VECTORCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + void *defaults; + int defaults_pyobjects; + size_t defaults_size; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_BACKPORT_VECTORCALL +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +#if !CYTHON_COMPILING_IN_LIMITED_API +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); +#endif + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* GCCDiagnostics.proto */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* CppExceptionConversion.proto */ +#ifndef __Pyx_CppExn2PyErr +#include +#include +#include +#include +static void __Pyx_CppExn2PyErr() { + try { + if (PyErr_Occurred()) + ; // let the latest Python exn pass through and ignore the current one + else + throw; + } catch (const std::bad_alloc& exn) { + PyErr_SetString(PyExc_MemoryError, exn.what()); + } catch (const std::bad_cast& exn) { + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::bad_typeid& exn) { + PyErr_SetString(PyExc_TypeError, exn.what()); + } catch (const std::domain_error& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const std::invalid_argument& exn) { + PyErr_SetString(PyExc_ValueError, exn.what()); + } catch (const std::ios_base::failure& exn) { + PyErr_SetString(PyExc_IOError, exn.what()); + } catch (const std::out_of_range& exn) { + PyErr_SetString(PyExc_IndexError, exn.what()); + } catch (const std::overflow_error& exn) { + PyErr_SetString(PyExc_OverflowError, exn.what()); + } catch (const std::range_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + } catch (const std::underflow_error& exn) { + PyErr_SetString(PyExc_ArithmeticError, exn.what()); + } catch (const std::exception& exn) { + PyErr_SetString(PyExc_RuntimeError, exn.what()); + } + catch (...) + { + PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); + } +} +#endif + +static PyObject* __pyx_convert__to_py_struct__Date(struct Date s); +static PyObject* __pyx_convert__to_py_struct__Time(struct Time s); +/* RaiseUnexpectedTypeError.proto */ +static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#else +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static unsigned long __Pyx_get_runtime_version(void); +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +/* #### Code section: module_declarations ### */ +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct Journey __pyx_v_journey, bool __pyx_v_detailed); /* proto*/ +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, __PYX_ENUM_CLASS_DECL Day __pyx_v_day); /* proto*/ +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct JourneyStep __pyx_v_step); /* proto*/ + +/* Module declarations from "libc.string" */ + +/* Module declarations from "libcpp.string" */ + +/* Module declarations from "libcpp.vector" */ + +/* Module declarations from "libcpp.utility" */ + +/* Module declarations from "libcpp.unordered_map" */ + +/* Module declarations from "libcpp" */ + +/* Module declarations from "libcpp.optional" */ + +/* Module declarations from "PyPTRouter" */ +static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ +static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____int(std::pair const &); /*proto*/ +static PyObject *__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(std::vector > const &); /*proto*/ +static std::pair __pyx_convert_pair_from_py_std_3a__3a_string__and_int(PyObject *); /*proto*/ +static std::vector > __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(PyObject *); /*proto*/ +static struct Date __pyx_convert__from_py_struct__Date(PyObject *); /*proto*/ +static struct Time __pyx_convert__from_py_struct__Time(PyObject *); /*proto*/ +static struct Query __pyx_convert__from_py_struct__Query(PyObject *); /*proto*/ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "PyPTRouter" +extern int __pyx_module_is_main_PyPTRouter; +int __pyx_module_is_main_PyPTRouter = 0; + +/* Implementation of "PyPTRouter" */ +/* #### Code section: global_var ### */ +static PyObject *__pyx_builtin_TypeError; +static PyObject *__pyx_builtin_RuntimeError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_MemoryError; +static PyObject *__pyx_builtin_KeyError; +static PyObject *__pyx_builtin_ValueError; +/* #### Code section: string_decls ### */ +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_gc[] = "gc"; +static const char __pyx_k__14[] = "*"; +static const char __pyx_k__15[] = "."; +static const char __pyx_k__28[] = "?"; +static const char __pyx_k_day[] = "day"; +static const char __pyx_k_date[] = "date"; +static const char __pyx_k_hour[] = "hour"; +static const char __pyx_k_json[] = "json"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_self[] = "self"; +static const char __pyx_k_spec[] = "__spec__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_year[] = "year"; +static const char __pyx_k_hours[] = "hours"; +static const char __pyx_k_month[] = "month"; +static const char __pyx_k_query[] = "query"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_steps[] = "steps"; +static const char __pyx_k_utf_8[] = "utf-8"; +static const char __pyx_k_append[] = "append"; +static const char __pyx_k_enable[] = "enable"; +static const char __pyx_k_encode[] = "encode"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_minute[] = "minute"; +static const char __pyx_k_reduce[] = "__reduce__"; +static const char __pyx_k_second[] = "second"; +static const char __pyx_k_Unknown[] = "Unknown"; +static const char __pyx_k_disable[] = "disable"; +static const char __pyx_k_inc_src[] = "inc_src"; +static const char __pyx_k_inc_tgt[] = "inc_tgt"; +static const char __pyx_k_journey[] = "journey"; +static const char __pyx_k_minutes[] = "minutes"; +static const char __pyx_k_seconds[] = "seconds"; +static const char __pyx_k_src_vec[] = "src_vec"; +static const char __pyx_k_tgt_vec[] = "tgt_vec"; +static const char __pyx_k_trip_id[] = "trip_id"; +static const char __pyx_k_walking[] = "walking"; +static const char __pyx_k_weekday[] = "weekday"; +static const char __pyx_k_KeyError[] = "KeyError"; +static const char __pyx_k_datetime[] = "datetime"; +static const char __pyx_k_detailed[] = "detailed"; +static const char __pyx_k_duration[] = "duration"; +static const char __pyx_k_getstate[] = "__getstate__"; +static const char __pyx_k_journeys[] = "journeys"; +static const char __pyx_k_next_day[] = "next_day"; +static const char __pyx_k_setstate[] = "__setstate__"; +static const char __pyx_k_TypeError[] = "TypeError"; +static const char __pyx_k_isenabled[] = "isenabled"; +static const char __pyx_k_pyx_state[] = "__pyx_state"; +static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_trip_time[] = "trip_time"; +static const char __pyx_k_PyPTRouter[] = "PyPTRouter"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; +static const char __pyx_k_to_stop_id[] = "to_stop_id"; +static const char __pyx_k_MemoryError[] = "MemoryError"; +static const char __pyx_k_agency_name[] = "agency_name"; +static const char __pyx_k_arrival_day[] = "arrival_day"; +static const char __pyx_k_current_day[] = "current_day"; +static const char __pyx_k_journey_opt[] = "journey_opt"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_arrival_time[] = "arrival_time"; +static const char __pyx_k_from_stop_id[] = "from_stop_id"; +static const char __pyx_k_initializing[] = "_initializing"; +static const char __pyx_k_is_coroutine[] = "_is_coroutine"; +static const char __pyx_k_journey_dict[] = "journey_dict"; +static const char __pyx_k_stringsource[] = ""; +static const char __pyx_k_waiting_time[] = "waiting_time"; +static const char __pyx_k_departure_day[] = "departure_day"; +static const char __pyx_k_journeys_list[] = "journeys_list"; +static const char __pyx_k_max_transfers[] = "max_transfers"; +static const char __pyx_k_num_transfers[] = "num_transfers"; +static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_PyPTRouter_pyx[] = "PyPTRouter.pyx"; +static const char __pyx_k_departure_time[] = "departure_time"; +static const char __pyx_k_construct_query[] = "construct_query"; +static const char __pyx_k_input_directory[] = "input_directory"; +static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; +static const char __pyx_k_arrival_datetime[] = "arrival_datetime"; +static const char __pyx_k_included_sources[] = "included_sources"; +static const char __pyx_k_included_targets[] = "included_targets"; +static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_source_transfer_time[] = "source_transfer_time"; +static const char __pyx_k_return_pt_journeys_1to1[] = "return_pt_journeys_1to1"; +static const char __pyx_k_PyPTRouter___reduce_cython[] = "PyPTRouter.__reduce_cython__"; +static const char __pyx_k_PyPTRouter_construct_query[] = "PyPTRouter.construct_query"; +static const char __pyx_k_PyPTRouter___setstate_cython[] = "PyPTRouter.__setstate_cython__"; +static const char __pyx_k_Expected_string_int_tuple_got[] = "Expected (string, int) tuple, got "; +static const char __pyx_k_return_fastest_pt_journey_1to1[] = "return_fastest_pt_journey_1to1"; +static const char __pyx_k_No_value_specified_for_struct_at[] = "No value specified for struct attribute 'year'"; +static const char __pyx_k_PyPTRouter_return_fastest_pt_jou[] = "PyPTRouter.return_fastest_pt_journey_1to1"; +static const char __pyx_k_PyPTRouter_return_pt_journeys_1t[] = "PyPTRouter.return_pt_journeys_1to1"; +static const char __pyx_k_RAPTOR_router_not_initialized_Pl[] = "RAPTOR router not initialized. Please initialize first."; +static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; +static const char __pyx_k_No_value_specified_for_struct_at_2[] = "No value specified for struct attribute 'month'"; +static const char __pyx_k_No_value_specified_for_struct_at_3[] = "No value specified for struct attribute 'day'"; +static const char __pyx_k_No_value_specified_for_struct_at_4[] = "No value specified for struct attribute 'weekday'"; +static const char __pyx_k_No_value_specified_for_struct_at_5[] = "No value specified for struct attribute 'hours'"; +static const char __pyx_k_No_value_specified_for_struct_at_6[] = "No value specified for struct attribute 'minutes'"; +static const char __pyx_k_No_value_specified_for_struct_at_7[] = "No value specified for struct attribute 'seconds'"; +static const char __pyx_k_No_value_specified_for_struct_at_8[] = "No value specified for struct attribute 'included_sources'"; +static const char __pyx_k_No_value_specified_for_struct_at_9[] = "No value specified for struct attribute 'included_targets'"; +static const char __pyx_k_No_value_specified_for_struct_at_10[] = "No value specified for struct attribute 'date'"; +static const char __pyx_k_No_value_specified_for_struct_at_11[] = "No value specified for struct attribute 'departure_time'"; +static const char __pyx_k_No_value_specified_for_struct_at_12[] = "No value specified for struct attribute 'max_transfers'"; +/* #### Code section: decls ### */ +static int __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_input_directory); /* proto */ +static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_tp_new_10PyPTRouter_PyPTRouter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + #ifdef __Pyx_CyFunction_USED + PyTypeObject *__pyx_CyFunctionType; + #endif + #ifdef __Pyx_FusedFunction_USED + PyTypeObject *__pyx_FusedFunctionType; + #endif + #ifdef __Pyx_Generator_USED + PyTypeObject *__pyx_GeneratorType; + #endif + #ifdef __Pyx_IterableCoroutine_USED + PyTypeObject *__pyx_IterableCoroutineType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineAwaitType; + #endif + #ifdef __Pyx_Coroutine_USED + PyTypeObject *__pyx_CoroutineType; + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + #endif + #if CYTHON_USE_MODULE_STATE + PyObject *__pyx_type_10PyPTRouter_PyPTRouter; + #endif + PyTypeObject *__pyx_ptype_10PyPTRouter_PyPTRouter; + PyObject *__pyx_kp_u_Expected_string_int_tuple_got; + PyObject *__pyx_n_s_KeyError; + PyObject *__pyx_n_s_MemoryError; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_10; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_11; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_12; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_2; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_3; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_4; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_5; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_6; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_7; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_8; + PyObject *__pyx_kp_s_No_value_specified_for_struct_at_9; + PyObject *__pyx_n_s_PyPTRouter; + PyObject *__pyx_n_s_PyPTRouter___reduce_cython; + PyObject *__pyx_n_s_PyPTRouter___setstate_cython; + PyObject *__pyx_n_s_PyPTRouter_construct_query; + PyObject *__pyx_kp_s_PyPTRouter_pyx; + PyObject *__pyx_n_s_PyPTRouter_return_fastest_pt_jou; + PyObject *__pyx_n_s_PyPTRouter_return_pt_journeys_1t; + PyObject *__pyx_kp_u_RAPTOR_router_not_initialized_Pl; + PyObject *__pyx_n_s_RuntimeError; + PyObject *__pyx_n_s_TypeError; + PyObject *__pyx_n_u_Unknown; + PyObject *__pyx_n_s_ValueError; + PyObject *__pyx_n_s__14; + PyObject *__pyx_kp_u__15; + PyObject *__pyx_n_s__28; + PyObject *__pyx_n_u_agency_name; + PyObject *__pyx_n_s_append; + PyObject *__pyx_n_s_arrival_datetime; + PyObject *__pyx_n_u_arrival_day; + PyObject *__pyx_n_u_arrival_time; + PyObject *__pyx_n_s_asyncio_coroutines; + PyObject *__pyx_n_s_cline_in_traceback; + PyObject *__pyx_n_s_construct_query; + PyObject *__pyx_n_u_current_day; + PyObject *__pyx_n_s_date; + PyObject *__pyx_n_s_datetime; + PyObject *__pyx_n_s_day; + PyObject *__pyx_n_u_day; + PyObject *__pyx_n_u_departure_day; + PyObject *__pyx_n_s_departure_time; + PyObject *__pyx_n_u_departure_time; + PyObject *__pyx_n_s_detailed; + PyObject *__pyx_kp_u_disable; + PyObject *__pyx_n_u_duration; + PyObject *__pyx_kp_u_enable; + PyObject *__pyx_n_s_encode; + PyObject *__pyx_n_u_from_stop_id; + PyObject *__pyx_kp_u_gc; + PyObject *__pyx_n_s_getstate; + PyObject *__pyx_n_s_hour; + PyObject *__pyx_n_s_hours; + PyObject *__pyx_n_s_i; + PyObject *__pyx_n_s_import; + PyObject *__pyx_n_s_inc_src; + PyObject *__pyx_n_s_inc_tgt; + PyObject *__pyx_n_s_included_sources; + PyObject *__pyx_n_s_included_targets; + PyObject *__pyx_n_s_initializing; + PyObject *__pyx_n_s_input_directory; + PyObject *__pyx_n_s_is_coroutine; + PyObject *__pyx_kp_u_isenabled; + PyObject *__pyx_n_s_journey; + PyObject *__pyx_n_s_journey_dict; + PyObject *__pyx_n_s_journey_opt; + PyObject *__pyx_n_s_journeys; + PyObject *__pyx_n_s_journeys_list; + PyObject *__pyx_n_s_json; + PyObject *__pyx_n_s_main; + PyObject *__pyx_n_s_max_transfers; + PyObject *__pyx_n_s_minute; + PyObject *__pyx_n_s_minutes; + PyObject *__pyx_n_s_month; + PyObject *__pyx_n_s_name; + PyObject *__pyx_n_u_next_day; + PyObject *__pyx_kp_s_no_default___reduce___due_to_non; + PyObject *__pyx_n_u_num_transfers; + PyObject *__pyx_n_s_pyx_state; + PyObject *__pyx_n_s_pyx_vtable; + PyObject *__pyx_n_s_query; + PyObject *__pyx_n_s_range; + PyObject *__pyx_n_s_reduce; + PyObject *__pyx_n_s_reduce_cython; + PyObject *__pyx_n_s_reduce_ex; + PyObject *__pyx_n_s_return_fastest_pt_journey_1to1; + PyObject *__pyx_n_s_return_pt_journeys_1to1; + PyObject *__pyx_n_s_second; + PyObject *__pyx_n_s_seconds; + PyObject *__pyx_n_s_self; + PyObject *__pyx_n_s_setstate; + PyObject *__pyx_n_s_setstate_cython; + PyObject *__pyx_n_u_source_transfer_time; + PyObject *__pyx_n_s_spec; + PyObject *__pyx_n_s_src_vec; + PyObject *__pyx_n_u_steps; + PyObject *__pyx_kp_s_stringsource; + PyObject *__pyx_n_s_test; + PyObject *__pyx_n_s_tgt_vec; + PyObject *__pyx_n_u_to_stop_id; + PyObject *__pyx_n_u_trip_id; + PyObject *__pyx_n_u_trip_time; + PyObject *__pyx_kp_u_utf_8; + PyObject *__pyx_n_u_waiting_time; + PyObject *__pyx_n_u_walking; + PyObject *__pyx_n_s_weekday; + PyObject *__pyx_n_s_year; + PyObject *__pyx_int_neg_1; + PyObject *__pyx_tuple_; + PyObject *__pyx_tuple__2; + PyObject *__pyx_tuple__3; + PyObject *__pyx_tuple__4; + PyObject *__pyx_tuple__5; + PyObject *__pyx_tuple__6; + PyObject *__pyx_tuple__7; + PyObject *__pyx_tuple__8; + PyObject *__pyx_tuple__9; + PyObject *__pyx_tuple__10; + PyObject *__pyx_tuple__11; + PyObject *__pyx_tuple__12; + PyObject *__pyx_tuple__13; + PyObject *__pyx_tuple__16; + PyObject *__pyx_tuple__18; + PyObject *__pyx_tuple__19; + PyObject *__pyx_tuple__21; + PyObject *__pyx_tuple__22; + PyObject *__pyx_tuple__24; + PyObject *__pyx_tuple__26; + PyObject *__pyx_codeobj__17; + PyObject *__pyx_codeobj__20; + PyObject *__pyx_codeobj__23; + PyObject *__pyx_codeobj__25; + PyObject *__pyx_codeobj__27; +} __pyx_mstate; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { + extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) + +#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) + +#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstate __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_clear(PyObject *m) { + __pyx_mstate *clear_module_state = __pyx_mstate(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); + #endif + Py_CLEAR(clear_module_state->__pyx_ptype_10PyPTRouter_PyPTRouter); + Py_CLEAR(clear_module_state->__pyx_type_10PyPTRouter_PyPTRouter); + Py_CLEAR(clear_module_state->__pyx_kp_u_Expected_string_int_tuple_got); + Py_CLEAR(clear_module_state->__pyx_n_s_KeyError); + Py_CLEAR(clear_module_state->__pyx_n_s_MemoryError); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_10); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_11); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_12); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_2); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_3); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_4); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_5); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_6); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_7); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_8); + Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_9); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter___reduce_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter___setstate_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_construct_query); + Py_CLEAR(clear_module_state->__pyx_kp_s_PyPTRouter_pyx); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_return_fastest_pt_jou); + Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_return_pt_journeys_1t); + Py_CLEAR(clear_module_state->__pyx_kp_u_RAPTOR_router_not_initialized_Pl); + Py_CLEAR(clear_module_state->__pyx_n_s_RuntimeError); + Py_CLEAR(clear_module_state->__pyx_n_s_TypeError); + Py_CLEAR(clear_module_state->__pyx_n_u_Unknown); + Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); + Py_CLEAR(clear_module_state->__pyx_n_s__14); + Py_CLEAR(clear_module_state->__pyx_kp_u__15); + Py_CLEAR(clear_module_state->__pyx_n_s__28); + Py_CLEAR(clear_module_state->__pyx_n_u_agency_name); + Py_CLEAR(clear_module_state->__pyx_n_s_append); + Py_CLEAR(clear_module_state->__pyx_n_s_arrival_datetime); + Py_CLEAR(clear_module_state->__pyx_n_u_arrival_day); + Py_CLEAR(clear_module_state->__pyx_n_u_arrival_time); + Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); + Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); + Py_CLEAR(clear_module_state->__pyx_n_s_construct_query); + Py_CLEAR(clear_module_state->__pyx_n_u_current_day); + Py_CLEAR(clear_module_state->__pyx_n_s_date); + Py_CLEAR(clear_module_state->__pyx_n_s_datetime); + Py_CLEAR(clear_module_state->__pyx_n_s_day); + Py_CLEAR(clear_module_state->__pyx_n_u_day); + Py_CLEAR(clear_module_state->__pyx_n_u_departure_day); + Py_CLEAR(clear_module_state->__pyx_n_s_departure_time); + Py_CLEAR(clear_module_state->__pyx_n_u_departure_time); + Py_CLEAR(clear_module_state->__pyx_n_s_detailed); + Py_CLEAR(clear_module_state->__pyx_kp_u_disable); + Py_CLEAR(clear_module_state->__pyx_n_u_duration); + Py_CLEAR(clear_module_state->__pyx_kp_u_enable); + Py_CLEAR(clear_module_state->__pyx_n_s_encode); + Py_CLEAR(clear_module_state->__pyx_n_u_from_stop_id); + Py_CLEAR(clear_module_state->__pyx_kp_u_gc); + Py_CLEAR(clear_module_state->__pyx_n_s_getstate); + Py_CLEAR(clear_module_state->__pyx_n_s_hour); + Py_CLEAR(clear_module_state->__pyx_n_s_hours); + Py_CLEAR(clear_module_state->__pyx_n_s_i); + Py_CLEAR(clear_module_state->__pyx_n_s_import); + Py_CLEAR(clear_module_state->__pyx_n_s_inc_src); + Py_CLEAR(clear_module_state->__pyx_n_s_inc_tgt); + Py_CLEAR(clear_module_state->__pyx_n_s_included_sources); + Py_CLEAR(clear_module_state->__pyx_n_s_included_targets); + Py_CLEAR(clear_module_state->__pyx_n_s_initializing); + Py_CLEAR(clear_module_state->__pyx_n_s_input_directory); + Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); + Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); + Py_CLEAR(clear_module_state->__pyx_n_s_journey); + Py_CLEAR(clear_module_state->__pyx_n_s_journey_dict); + Py_CLEAR(clear_module_state->__pyx_n_s_journey_opt); + Py_CLEAR(clear_module_state->__pyx_n_s_journeys); + Py_CLEAR(clear_module_state->__pyx_n_s_journeys_list); + Py_CLEAR(clear_module_state->__pyx_n_s_json); + Py_CLEAR(clear_module_state->__pyx_n_s_main); + Py_CLEAR(clear_module_state->__pyx_n_s_max_transfers); + Py_CLEAR(clear_module_state->__pyx_n_s_minute); + Py_CLEAR(clear_module_state->__pyx_n_s_minutes); + Py_CLEAR(clear_module_state->__pyx_n_s_month); + Py_CLEAR(clear_module_state->__pyx_n_s_name); + Py_CLEAR(clear_module_state->__pyx_n_u_next_day); + Py_CLEAR(clear_module_state->__pyx_kp_s_no_default___reduce___due_to_non); + Py_CLEAR(clear_module_state->__pyx_n_u_num_transfers); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_state); + Py_CLEAR(clear_module_state->__pyx_n_s_pyx_vtable); + Py_CLEAR(clear_module_state->__pyx_n_s_query); + Py_CLEAR(clear_module_state->__pyx_n_s_range); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_reduce_ex); + Py_CLEAR(clear_module_state->__pyx_n_s_return_fastest_pt_journey_1to1); + Py_CLEAR(clear_module_state->__pyx_n_s_return_pt_journeys_1to1); + Py_CLEAR(clear_module_state->__pyx_n_s_second); + Py_CLEAR(clear_module_state->__pyx_n_s_seconds); + Py_CLEAR(clear_module_state->__pyx_n_s_self); + Py_CLEAR(clear_module_state->__pyx_n_s_setstate); + Py_CLEAR(clear_module_state->__pyx_n_s_setstate_cython); + Py_CLEAR(clear_module_state->__pyx_n_u_source_transfer_time); + Py_CLEAR(clear_module_state->__pyx_n_s_spec); + Py_CLEAR(clear_module_state->__pyx_n_s_src_vec); + Py_CLEAR(clear_module_state->__pyx_n_u_steps); + Py_CLEAR(clear_module_state->__pyx_kp_s_stringsource); + Py_CLEAR(clear_module_state->__pyx_n_s_test); + Py_CLEAR(clear_module_state->__pyx_n_s_tgt_vec); + Py_CLEAR(clear_module_state->__pyx_n_u_to_stop_id); + Py_CLEAR(clear_module_state->__pyx_n_u_trip_id); + Py_CLEAR(clear_module_state->__pyx_n_u_trip_time); + Py_CLEAR(clear_module_state->__pyx_kp_u_utf_8); + Py_CLEAR(clear_module_state->__pyx_n_u_waiting_time); + Py_CLEAR(clear_module_state->__pyx_n_u_walking); + Py_CLEAR(clear_module_state->__pyx_n_s_weekday); + Py_CLEAR(clear_module_state->__pyx_n_s_year); + Py_CLEAR(clear_module_state->__pyx_int_neg_1); + Py_CLEAR(clear_module_state->__pyx_tuple_); + Py_CLEAR(clear_module_state->__pyx_tuple__2); + Py_CLEAR(clear_module_state->__pyx_tuple__3); + Py_CLEAR(clear_module_state->__pyx_tuple__4); + Py_CLEAR(clear_module_state->__pyx_tuple__5); + Py_CLEAR(clear_module_state->__pyx_tuple__6); + Py_CLEAR(clear_module_state->__pyx_tuple__7); + Py_CLEAR(clear_module_state->__pyx_tuple__8); + Py_CLEAR(clear_module_state->__pyx_tuple__9); + Py_CLEAR(clear_module_state->__pyx_tuple__10); + Py_CLEAR(clear_module_state->__pyx_tuple__11); + Py_CLEAR(clear_module_state->__pyx_tuple__12); + Py_CLEAR(clear_module_state->__pyx_tuple__13); + Py_CLEAR(clear_module_state->__pyx_tuple__16); + Py_CLEAR(clear_module_state->__pyx_tuple__18); + Py_CLEAR(clear_module_state->__pyx_tuple__19); + Py_CLEAR(clear_module_state->__pyx_tuple__21); + Py_CLEAR(clear_module_state->__pyx_tuple__22); + Py_CLEAR(clear_module_state->__pyx_tuple__24); + Py_CLEAR(clear_module_state->__pyx_tuple__26); + Py_CLEAR(clear_module_state->__pyx_codeobj__17); + Py_CLEAR(clear_module_state->__pyx_codeobj__20); + Py_CLEAR(clear_module_state->__pyx_codeobj__23); + Py_CLEAR(clear_module_state->__pyx_codeobj__25); + Py_CLEAR(clear_module_state->__pyx_codeobj__27); + return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstate *traverse_module_state = __pyx_mstate(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + Py_VISIT(traverse_module_state->__pyx_empty_tuple); + Py_VISIT(traverse_module_state->__pyx_empty_bytes); + Py_VISIT(traverse_module_state->__pyx_empty_unicode); + #ifdef __Pyx_CyFunction_USED + Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + #endif + #ifdef __Pyx_FusedFunction_USED + Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); + #endif + Py_VISIT(traverse_module_state->__pyx_ptype_10PyPTRouter_PyPTRouter); + Py_VISIT(traverse_module_state->__pyx_type_10PyPTRouter_PyPTRouter); + Py_VISIT(traverse_module_state->__pyx_kp_u_Expected_string_int_tuple_got); + Py_VISIT(traverse_module_state->__pyx_n_s_KeyError); + Py_VISIT(traverse_module_state->__pyx_n_s_MemoryError); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_10); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_11); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_12); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_2); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_3); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_4); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_5); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_6); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_7); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_8); + Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_9); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter___reduce_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter___setstate_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_construct_query); + Py_VISIT(traverse_module_state->__pyx_kp_s_PyPTRouter_pyx); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_return_fastest_pt_jou); + Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_return_pt_journeys_1t); + Py_VISIT(traverse_module_state->__pyx_kp_u_RAPTOR_router_not_initialized_Pl); + Py_VISIT(traverse_module_state->__pyx_n_s_RuntimeError); + Py_VISIT(traverse_module_state->__pyx_n_s_TypeError); + Py_VISIT(traverse_module_state->__pyx_n_u_Unknown); + Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); + Py_VISIT(traverse_module_state->__pyx_n_s__14); + Py_VISIT(traverse_module_state->__pyx_kp_u__15); + Py_VISIT(traverse_module_state->__pyx_n_s__28); + Py_VISIT(traverse_module_state->__pyx_n_u_agency_name); + Py_VISIT(traverse_module_state->__pyx_n_s_append); + Py_VISIT(traverse_module_state->__pyx_n_s_arrival_datetime); + Py_VISIT(traverse_module_state->__pyx_n_u_arrival_day); + Py_VISIT(traverse_module_state->__pyx_n_u_arrival_time); + Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); + Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); + Py_VISIT(traverse_module_state->__pyx_n_s_construct_query); + Py_VISIT(traverse_module_state->__pyx_n_u_current_day); + Py_VISIT(traverse_module_state->__pyx_n_s_date); + Py_VISIT(traverse_module_state->__pyx_n_s_datetime); + Py_VISIT(traverse_module_state->__pyx_n_s_day); + Py_VISIT(traverse_module_state->__pyx_n_u_day); + Py_VISIT(traverse_module_state->__pyx_n_u_departure_day); + Py_VISIT(traverse_module_state->__pyx_n_s_departure_time); + Py_VISIT(traverse_module_state->__pyx_n_u_departure_time); + Py_VISIT(traverse_module_state->__pyx_n_s_detailed); + Py_VISIT(traverse_module_state->__pyx_kp_u_disable); + Py_VISIT(traverse_module_state->__pyx_n_u_duration); + Py_VISIT(traverse_module_state->__pyx_kp_u_enable); + Py_VISIT(traverse_module_state->__pyx_n_s_encode); + Py_VISIT(traverse_module_state->__pyx_n_u_from_stop_id); + Py_VISIT(traverse_module_state->__pyx_kp_u_gc); + Py_VISIT(traverse_module_state->__pyx_n_s_getstate); + Py_VISIT(traverse_module_state->__pyx_n_s_hour); + Py_VISIT(traverse_module_state->__pyx_n_s_hours); + Py_VISIT(traverse_module_state->__pyx_n_s_i); + Py_VISIT(traverse_module_state->__pyx_n_s_import); + Py_VISIT(traverse_module_state->__pyx_n_s_inc_src); + Py_VISIT(traverse_module_state->__pyx_n_s_inc_tgt); + Py_VISIT(traverse_module_state->__pyx_n_s_included_sources); + Py_VISIT(traverse_module_state->__pyx_n_s_included_targets); + Py_VISIT(traverse_module_state->__pyx_n_s_initializing); + Py_VISIT(traverse_module_state->__pyx_n_s_input_directory); + Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); + Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); + Py_VISIT(traverse_module_state->__pyx_n_s_journey); + Py_VISIT(traverse_module_state->__pyx_n_s_journey_dict); + Py_VISIT(traverse_module_state->__pyx_n_s_journey_opt); + Py_VISIT(traverse_module_state->__pyx_n_s_journeys); + Py_VISIT(traverse_module_state->__pyx_n_s_journeys_list); + Py_VISIT(traverse_module_state->__pyx_n_s_json); + Py_VISIT(traverse_module_state->__pyx_n_s_main); + Py_VISIT(traverse_module_state->__pyx_n_s_max_transfers); + Py_VISIT(traverse_module_state->__pyx_n_s_minute); + Py_VISIT(traverse_module_state->__pyx_n_s_minutes); + Py_VISIT(traverse_module_state->__pyx_n_s_month); + Py_VISIT(traverse_module_state->__pyx_n_s_name); + Py_VISIT(traverse_module_state->__pyx_n_u_next_day); + Py_VISIT(traverse_module_state->__pyx_kp_s_no_default___reduce___due_to_non); + Py_VISIT(traverse_module_state->__pyx_n_u_num_transfers); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_state); + Py_VISIT(traverse_module_state->__pyx_n_s_pyx_vtable); + Py_VISIT(traverse_module_state->__pyx_n_s_query); + Py_VISIT(traverse_module_state->__pyx_n_s_range); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_reduce_ex); + Py_VISIT(traverse_module_state->__pyx_n_s_return_fastest_pt_journey_1to1); + Py_VISIT(traverse_module_state->__pyx_n_s_return_pt_journeys_1to1); + Py_VISIT(traverse_module_state->__pyx_n_s_second); + Py_VISIT(traverse_module_state->__pyx_n_s_seconds); + Py_VISIT(traverse_module_state->__pyx_n_s_self); + Py_VISIT(traverse_module_state->__pyx_n_s_setstate); + Py_VISIT(traverse_module_state->__pyx_n_s_setstate_cython); + Py_VISIT(traverse_module_state->__pyx_n_u_source_transfer_time); + Py_VISIT(traverse_module_state->__pyx_n_s_spec); + Py_VISIT(traverse_module_state->__pyx_n_s_src_vec); + Py_VISIT(traverse_module_state->__pyx_n_u_steps); + Py_VISIT(traverse_module_state->__pyx_kp_s_stringsource); + Py_VISIT(traverse_module_state->__pyx_n_s_test); + Py_VISIT(traverse_module_state->__pyx_n_s_tgt_vec); + Py_VISIT(traverse_module_state->__pyx_n_u_to_stop_id); + Py_VISIT(traverse_module_state->__pyx_n_u_trip_id); + Py_VISIT(traverse_module_state->__pyx_n_u_trip_time); + Py_VISIT(traverse_module_state->__pyx_kp_u_utf_8); + Py_VISIT(traverse_module_state->__pyx_n_u_waiting_time); + Py_VISIT(traverse_module_state->__pyx_n_u_walking); + Py_VISIT(traverse_module_state->__pyx_n_s_weekday); + Py_VISIT(traverse_module_state->__pyx_n_s_year); + Py_VISIT(traverse_module_state->__pyx_int_neg_1); + Py_VISIT(traverse_module_state->__pyx_tuple_); + Py_VISIT(traverse_module_state->__pyx_tuple__2); + Py_VISIT(traverse_module_state->__pyx_tuple__3); + Py_VISIT(traverse_module_state->__pyx_tuple__4); + Py_VISIT(traverse_module_state->__pyx_tuple__5); + Py_VISIT(traverse_module_state->__pyx_tuple__6); + Py_VISIT(traverse_module_state->__pyx_tuple__7); + Py_VISIT(traverse_module_state->__pyx_tuple__8); + Py_VISIT(traverse_module_state->__pyx_tuple__9); + Py_VISIT(traverse_module_state->__pyx_tuple__10); + Py_VISIT(traverse_module_state->__pyx_tuple__11); + Py_VISIT(traverse_module_state->__pyx_tuple__12); + Py_VISIT(traverse_module_state->__pyx_tuple__13); + Py_VISIT(traverse_module_state->__pyx_tuple__16); + Py_VISIT(traverse_module_state->__pyx_tuple__18); + Py_VISIT(traverse_module_state->__pyx_tuple__19); + Py_VISIT(traverse_module_state->__pyx_tuple__21); + Py_VISIT(traverse_module_state->__pyx_tuple__22); + Py_VISIT(traverse_module_state->__pyx_tuple__24); + Py_VISIT(traverse_module_state->__pyx_tuple__26); + Py_VISIT(traverse_module_state->__pyx_codeobj__17); + Py_VISIT(traverse_module_state->__pyx_codeobj__20); + Py_VISIT(traverse_module_state->__pyx_codeobj__23); + Py_VISIT(traverse_module_state->__pyx_codeobj__25); + Py_VISIT(traverse_module_state->__pyx_codeobj__27); + return 0; +} +#endif +/* #### Code section: module_state_defines ### */ +#define __pyx_d __pyx_mstate_global->__pyx_d +#define __pyx_b __pyx_mstate_global->__pyx_b +#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime +#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple +#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes +#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode +#ifdef __Pyx_CyFunction_USED +#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType +#endif +#ifdef __Pyx_FusedFunction_USED +#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType +#endif +#ifdef __Pyx_Generator_USED +#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType +#endif +#ifdef __Pyx_IterableCoroutine_USED +#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType +#endif +#ifdef __Pyx_Coroutine_USED +#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#endif +#if CYTHON_USE_MODULE_STATE +#define __pyx_type_10PyPTRouter_PyPTRouter __pyx_mstate_global->__pyx_type_10PyPTRouter_PyPTRouter +#endif +#define __pyx_ptype_10PyPTRouter_PyPTRouter __pyx_mstate_global->__pyx_ptype_10PyPTRouter_PyPTRouter +#define __pyx_kp_u_Expected_string_int_tuple_got __pyx_mstate_global->__pyx_kp_u_Expected_string_int_tuple_got +#define __pyx_n_s_KeyError __pyx_mstate_global->__pyx_n_s_KeyError +#define __pyx_n_s_MemoryError __pyx_mstate_global->__pyx_n_s_MemoryError +#define __pyx_kp_s_No_value_specified_for_struct_at __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at +#define __pyx_kp_s_No_value_specified_for_struct_at_10 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_10 +#define __pyx_kp_s_No_value_specified_for_struct_at_11 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_11 +#define __pyx_kp_s_No_value_specified_for_struct_at_12 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_12 +#define __pyx_kp_s_No_value_specified_for_struct_at_2 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_2 +#define __pyx_kp_s_No_value_specified_for_struct_at_3 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_3 +#define __pyx_kp_s_No_value_specified_for_struct_at_4 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_4 +#define __pyx_kp_s_No_value_specified_for_struct_at_5 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_5 +#define __pyx_kp_s_No_value_specified_for_struct_at_6 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_6 +#define __pyx_kp_s_No_value_specified_for_struct_at_7 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_7 +#define __pyx_kp_s_No_value_specified_for_struct_at_8 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_8 +#define __pyx_kp_s_No_value_specified_for_struct_at_9 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_9 +#define __pyx_n_s_PyPTRouter __pyx_mstate_global->__pyx_n_s_PyPTRouter +#define __pyx_n_s_PyPTRouter___reduce_cython __pyx_mstate_global->__pyx_n_s_PyPTRouter___reduce_cython +#define __pyx_n_s_PyPTRouter___setstate_cython __pyx_mstate_global->__pyx_n_s_PyPTRouter___setstate_cython +#define __pyx_n_s_PyPTRouter_construct_query __pyx_mstate_global->__pyx_n_s_PyPTRouter_construct_query +#define __pyx_kp_s_PyPTRouter_pyx __pyx_mstate_global->__pyx_kp_s_PyPTRouter_pyx +#define __pyx_n_s_PyPTRouter_return_fastest_pt_jou __pyx_mstate_global->__pyx_n_s_PyPTRouter_return_fastest_pt_jou +#define __pyx_n_s_PyPTRouter_return_pt_journeys_1t __pyx_mstate_global->__pyx_n_s_PyPTRouter_return_pt_journeys_1t +#define __pyx_kp_u_RAPTOR_router_not_initialized_Pl __pyx_mstate_global->__pyx_kp_u_RAPTOR_router_not_initialized_Pl +#define __pyx_n_s_RuntimeError __pyx_mstate_global->__pyx_n_s_RuntimeError +#define __pyx_n_s_TypeError __pyx_mstate_global->__pyx_n_s_TypeError +#define __pyx_n_u_Unknown __pyx_mstate_global->__pyx_n_u_Unknown +#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError +#define __pyx_n_s__14 __pyx_mstate_global->__pyx_n_s__14 +#define __pyx_kp_u__15 __pyx_mstate_global->__pyx_kp_u__15 +#define __pyx_n_s__28 __pyx_mstate_global->__pyx_n_s__28 +#define __pyx_n_u_agency_name __pyx_mstate_global->__pyx_n_u_agency_name +#define __pyx_n_s_append __pyx_mstate_global->__pyx_n_s_append +#define __pyx_n_s_arrival_datetime __pyx_mstate_global->__pyx_n_s_arrival_datetime +#define __pyx_n_u_arrival_day __pyx_mstate_global->__pyx_n_u_arrival_day +#define __pyx_n_u_arrival_time __pyx_mstate_global->__pyx_n_u_arrival_time +#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines +#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback +#define __pyx_n_s_construct_query __pyx_mstate_global->__pyx_n_s_construct_query +#define __pyx_n_u_current_day __pyx_mstate_global->__pyx_n_u_current_day +#define __pyx_n_s_date __pyx_mstate_global->__pyx_n_s_date +#define __pyx_n_s_datetime __pyx_mstate_global->__pyx_n_s_datetime +#define __pyx_n_s_day __pyx_mstate_global->__pyx_n_s_day +#define __pyx_n_u_day __pyx_mstate_global->__pyx_n_u_day +#define __pyx_n_u_departure_day __pyx_mstate_global->__pyx_n_u_departure_day +#define __pyx_n_s_departure_time __pyx_mstate_global->__pyx_n_s_departure_time +#define __pyx_n_u_departure_time __pyx_mstate_global->__pyx_n_u_departure_time +#define __pyx_n_s_detailed __pyx_mstate_global->__pyx_n_s_detailed +#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable +#define __pyx_n_u_duration __pyx_mstate_global->__pyx_n_u_duration +#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable +#define __pyx_n_s_encode __pyx_mstate_global->__pyx_n_s_encode +#define __pyx_n_u_from_stop_id __pyx_mstate_global->__pyx_n_u_from_stop_id +#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc +#define __pyx_n_s_getstate __pyx_mstate_global->__pyx_n_s_getstate +#define __pyx_n_s_hour __pyx_mstate_global->__pyx_n_s_hour +#define __pyx_n_s_hours __pyx_mstate_global->__pyx_n_s_hours +#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i +#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import +#define __pyx_n_s_inc_src __pyx_mstate_global->__pyx_n_s_inc_src +#define __pyx_n_s_inc_tgt __pyx_mstate_global->__pyx_n_s_inc_tgt +#define __pyx_n_s_included_sources __pyx_mstate_global->__pyx_n_s_included_sources +#define __pyx_n_s_included_targets __pyx_mstate_global->__pyx_n_s_included_targets +#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing +#define __pyx_n_s_input_directory __pyx_mstate_global->__pyx_n_s_input_directory +#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine +#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled +#define __pyx_n_s_journey __pyx_mstate_global->__pyx_n_s_journey +#define __pyx_n_s_journey_dict __pyx_mstate_global->__pyx_n_s_journey_dict +#define __pyx_n_s_journey_opt __pyx_mstate_global->__pyx_n_s_journey_opt +#define __pyx_n_s_journeys __pyx_mstate_global->__pyx_n_s_journeys +#define __pyx_n_s_journeys_list __pyx_mstate_global->__pyx_n_s_journeys_list +#define __pyx_n_s_json __pyx_mstate_global->__pyx_n_s_json +#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main +#define __pyx_n_s_max_transfers __pyx_mstate_global->__pyx_n_s_max_transfers +#define __pyx_n_s_minute __pyx_mstate_global->__pyx_n_s_minute +#define __pyx_n_s_minutes __pyx_mstate_global->__pyx_n_s_minutes +#define __pyx_n_s_month __pyx_mstate_global->__pyx_n_s_month +#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name +#define __pyx_n_u_next_day __pyx_mstate_global->__pyx_n_u_next_day +#define __pyx_kp_s_no_default___reduce___due_to_non __pyx_mstate_global->__pyx_kp_s_no_default___reduce___due_to_non +#define __pyx_n_u_num_transfers __pyx_mstate_global->__pyx_n_u_num_transfers +#define __pyx_n_s_pyx_state __pyx_mstate_global->__pyx_n_s_pyx_state +#define __pyx_n_s_pyx_vtable __pyx_mstate_global->__pyx_n_s_pyx_vtable +#define __pyx_n_s_query __pyx_mstate_global->__pyx_n_s_query +#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range +#define __pyx_n_s_reduce __pyx_mstate_global->__pyx_n_s_reduce +#define __pyx_n_s_reduce_cython __pyx_mstate_global->__pyx_n_s_reduce_cython +#define __pyx_n_s_reduce_ex __pyx_mstate_global->__pyx_n_s_reduce_ex +#define __pyx_n_s_return_fastest_pt_journey_1to1 __pyx_mstate_global->__pyx_n_s_return_fastest_pt_journey_1to1 +#define __pyx_n_s_return_pt_journeys_1to1 __pyx_mstate_global->__pyx_n_s_return_pt_journeys_1to1 +#define __pyx_n_s_second __pyx_mstate_global->__pyx_n_s_second +#define __pyx_n_s_seconds __pyx_mstate_global->__pyx_n_s_seconds +#define __pyx_n_s_self __pyx_mstate_global->__pyx_n_s_self +#define __pyx_n_s_setstate __pyx_mstate_global->__pyx_n_s_setstate +#define __pyx_n_s_setstate_cython __pyx_mstate_global->__pyx_n_s_setstate_cython +#define __pyx_n_u_source_transfer_time __pyx_mstate_global->__pyx_n_u_source_transfer_time +#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec +#define __pyx_n_s_src_vec __pyx_mstate_global->__pyx_n_s_src_vec +#define __pyx_n_u_steps __pyx_mstate_global->__pyx_n_u_steps +#define __pyx_kp_s_stringsource __pyx_mstate_global->__pyx_kp_s_stringsource +#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test +#define __pyx_n_s_tgt_vec __pyx_mstate_global->__pyx_n_s_tgt_vec +#define __pyx_n_u_to_stop_id __pyx_mstate_global->__pyx_n_u_to_stop_id +#define __pyx_n_u_trip_id __pyx_mstate_global->__pyx_n_u_trip_id +#define __pyx_n_u_trip_time __pyx_mstate_global->__pyx_n_u_trip_time +#define __pyx_kp_u_utf_8 __pyx_mstate_global->__pyx_kp_u_utf_8 +#define __pyx_n_u_waiting_time __pyx_mstate_global->__pyx_n_u_waiting_time +#define __pyx_n_u_walking __pyx_mstate_global->__pyx_n_u_walking +#define __pyx_n_s_weekday __pyx_mstate_global->__pyx_n_s_weekday +#define __pyx_n_s_year __pyx_mstate_global->__pyx_n_s_year +#define __pyx_int_neg_1 __pyx_mstate_global->__pyx_int_neg_1 +#define __pyx_tuple_ __pyx_mstate_global->__pyx_tuple_ +#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 +#define __pyx_tuple__3 __pyx_mstate_global->__pyx_tuple__3 +#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 +#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 +#define __pyx_tuple__6 __pyx_mstate_global->__pyx_tuple__6 +#define __pyx_tuple__7 __pyx_mstate_global->__pyx_tuple__7 +#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 +#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 +#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10 +#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 +#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 +#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 +#define __pyx_tuple__16 __pyx_mstate_global->__pyx_tuple__16 +#define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18 +#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 +#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21 +#define __pyx_tuple__22 __pyx_mstate_global->__pyx_tuple__22 +#define __pyx_tuple__24 __pyx_mstate_global->__pyx_tuple__24 +#define __pyx_tuple__26 __pyx_mstate_global->__pyx_tuple__26 +#define __pyx_codeobj__17 __pyx_mstate_global->__pyx_codeobj__17 +#define __pyx_codeobj__20 __pyx_mstate_global->__pyx_codeobj__20 +#define __pyx_codeobj__23 __pyx_mstate_global->__pyx_codeobj__23 +#define __pyx_codeobj__25 __pyx_mstate_global->__pyx_codeobj__25 +#define __pyx_codeobj__27 __pyx_mstate_global->__pyx_codeobj__27 +/* #### Code section: module_code ### */ + +/* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + +static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *__pyx_v_o) { + Py_ssize_t __pyx_v_length; + char const *__pyx_v_data; + std::string __pyx_r; + char const *__pyx_t_1; + std::string __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + + /* "string.from_py":14 + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: + * cdef Py_ssize_t length = 0 # <<<<<<<<<<<<<< + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + * return string(data, length) + */ + __pyx_v_length = 0; + + /* "string.from_py":15 + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) # <<<<<<<<<<<<<< + * return string(data, length) + * + */ + __pyx_t_1 = __Pyx_PyObject_AsStringAndSize(__pyx_v_o, (&__pyx_v_length)); if (unlikely(__pyx_t_1 == ((char const *)NULL))) __PYX_ERR(1, 15, __pyx_L1_error) + __pyx_v_data = __pyx_t_1; + + /* "string.from_py":16 + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + * return string(data, length) # <<<<<<<<<<<<<< + * + * + */ + try { + __pyx_t_2 = std::string(__pyx_v_data, __pyx_v_length); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(1, 16, __pyx_L1_error) + } + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "string.from_py":13 + * + * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") + * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< + * cdef Py_ssize_t length = 0 + * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("string.from_py.__pyx_convert_string_from_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + return __pyx_r; +} + +/* "string.to_py":31 + * + * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + +static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string", 1); + + /* "string.to_py":32 + * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): + * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< + * cdef extern from *: + * cdef object __Pyx_PyUnicode_FromStringAndSize(const char*, size_t) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "string.to_py":31 + * + * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("string.to_py.__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "string.to_py":37 + * + * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + +static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string", 1); + + /* "string.to_py":38 + * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): + * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< + * cdef extern from *: + * cdef object __Pyx_PyStr_FromStringAndSize(const char*, size_t) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyUnicode_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "string.to_py":37 + * + * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("string.to_py.__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "string.to_py":43 + * + * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + +static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string", 1); + + /* "string.to_py":44 + * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): + * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< + * cdef extern from *: + * cdef object __Pyx_PyBytes_FromStringAndSize(const char*, size_t) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyStr_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "string.to_py":43 + * + * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("string.to_py.__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "string.to_py":49 + * + * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + +static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string", 1); + + /* "string.to_py":50 + * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): + * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< + * cdef extern from *: + * cdef object __Pyx_PyByteArray_FromStringAndSize(const char*, size_t) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "string.to_py":49 + * + * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) + * cdef extern from *: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("string.to_py.__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "string.to_py":55 + * + * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) + * + */ + +static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string", 1); + + /* "string.to_py":56 + * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): + * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyByteArray_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "string.to_py":55 + * + * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") + * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< + * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("string.to_py.__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "pair.to_py":190 + * + * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") + * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): # <<<<<<<<<<<<<< + * return p.first, p.second + * + */ + +static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____int(std::pair const &__pyx_v_p) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_pair_to_py_std_3a__3a_string____int", 1); + + /* "pair.to_py":191 + * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") + * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): + * return p.first, p.second # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(__pyx_v_p.first); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_p.second); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_1); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 191, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_2); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(1, 191, __pyx_L1_error); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "pair.to_py":190 + * + * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") + * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): # <<<<<<<<<<<<<< + * return p.first, p.second + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("pair.to_py.__pyx_convert_pair_to_py_std_3a__3a_string____int", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "vector.to_py":66 + * + * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): # <<<<<<<<<<<<<< + * if v.size() > PY_SSIZE_T_MAX: + * raise MemoryError() + */ + +static PyObject *__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(std::vector > const &__pyx_v_v) { + Py_ssize_t __pyx_v_v_size_signed; + PyObject *__pyx_v_o = NULL; + Py_ssize_t __pyx_v_i; + PyObject *__pyx_v_item = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + Py_ssize_t __pyx_t_4; + Py_ssize_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", 1); + + /* "vector.to_py":67 + * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): + * if v.size() > PY_SSIZE_T_MAX: # <<<<<<<<<<<<<< + * raise MemoryError() + * v_size_signed = v.size() + */ + __pyx_t_1 = (__pyx_v_v.size() > ((size_t)PY_SSIZE_T_MAX)); + if (unlikely(__pyx_t_1)) { + + /* "vector.to_py":68 + * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): + * if v.size() > PY_SSIZE_T_MAX: + * raise MemoryError() # <<<<<<<<<<<<<< + * v_size_signed = v.size() + * + */ + PyErr_NoMemory(); __PYX_ERR(1, 68, __pyx_L1_error) + + /* "vector.to_py":67 + * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): + * if v.size() > PY_SSIZE_T_MAX: # <<<<<<<<<<<<<< + * raise MemoryError() + * v_size_signed = v.size() + */ + } + + /* "vector.to_py":69 + * if v.size() > PY_SSIZE_T_MAX: + * raise MemoryError() + * v_size_signed = v.size() # <<<<<<<<<<<<<< + * + * o = PyList_New(v_size_signed) + */ + __pyx_v_v_size_signed = ((Py_ssize_t)__pyx_v_v.size()); + + /* "vector.to_py":71 + * v_size_signed = v.size() + * + * o = PyList_New(v_size_signed) # <<<<<<<<<<<<<< + * + * cdef Py_ssize_t i + */ + __pyx_t_2 = PyList_New(__pyx_v_v_size_signed); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_o = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "vector.to_py":76 + * cdef object item + * + * for i in range(v_size_signed): # <<<<<<<<<<<<<< + * item = v[i] + * Py_INCREF(item) + */ + __pyx_t_3 = __pyx_v_v_size_signed; + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "vector.to_py":77 + * + * for i in range(v_size_signed): + * item = v[i] # <<<<<<<<<<<<<< + * Py_INCREF(item) + * PyList_SET_ITEM(o, i, item) + */ + __pyx_t_2 = __pyx_convert_pair_to_py_std_3a__3a_string____int((__pyx_v_v[__pyx_v_i])); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_2); + __pyx_t_2 = 0; + + /* "vector.to_py":78 + * for i in range(v_size_signed): + * item = v[i] + * Py_INCREF(item) # <<<<<<<<<<<<<< + * PyList_SET_ITEM(o, i, item) + * + */ + Py_INCREF(__pyx_v_item); + + /* "vector.to_py":79 + * item = v[i] + * Py_INCREF(item) + * PyList_SET_ITEM(o, i, item) # <<<<<<<<<<<<<< + * + * return o + */ + PyList_SET_ITEM(__pyx_v_o, __pyx_v_i, __pyx_v_item); + } + + /* "vector.to_py":81 + * PyList_SET_ITEM(o, i, item) + * + * return o # <<<<<<<<<<<<<< + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_o); + __pyx_r = __pyx_v_o; + goto __pyx_L0; + + /* "vector.to_py":66 + * + * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): # <<<<<<<<<<<<<< + * if v.size() > PY_SSIZE_T_MAX: + * raise MemoryError() + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("vector.to_py.__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_o); + __Pyx_XDECREF(__pyx_v_item); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "pair.from_py":177 + * + * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") + * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: # <<<<<<<<<<<<<< + * x, y = o + * return pair[X,Y](x, y) + */ + +static std::pair __pyx_convert_pair_from_py_std_3a__3a_string__and_int(PyObject *__pyx_v_o) { + PyObject *__pyx_v_x = NULL; + PyObject *__pyx_v_y = NULL; + std::pair __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *(*__pyx_t_4)(PyObject *); + std::string __pyx_t_5; + int __pyx_t_6; + std::pair __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_pair_from_py_std_3a__3a_string__and_int", 1); + + /* "pair.from_py":178 + * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") + * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: + * x, y = o # <<<<<<<<<<<<<< + * return pair[X,Y](x, y) + * + */ + if ((likely(PyTuple_CheckExact(__pyx_v_o))) || (PyList_CheckExact(__pyx_v_o))) { + PyObject* sequence = __pyx_v_o; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(1, 178, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_1 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #endif + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_v_o); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 178, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); + index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_1); + index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(1, 178, __pyx_L1_error) + __pyx_t_4 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L4_unpacking_done; + __pyx_L3_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(1, 178, __pyx_L1_error) + __pyx_L4_unpacking_done:; + } + __pyx_v_x = __pyx_t_1; + __pyx_t_1 = 0; + __pyx_v_y = __pyx_t_2; + __pyx_t_2 = 0; + + /* "pair.from_py":179 + * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: + * x, y = o + * return pair[X,Y](x, y) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_5 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_v_x); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 179, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_v_y); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 179, __pyx_L1_error) + try { + __pyx_t_7 = std::pair (((std::string)__pyx_t_5), ((int)__pyx_t_6)); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(1, 179, __pyx_L1_error) + } + __pyx_r = __pyx_t_7; + goto __pyx_L0; + + /* "pair.from_py":177 + * + * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") + * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: # <<<<<<<<<<<<<< + * x, y = o + * return pair[X,Y](x, y) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("pair.from_py.__pyx_convert_pair_from_py_std_3a__3a_string__and_int", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_x); + __Pyx_XDECREF(__pyx_v_y); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "vector.from_py":45 + * + * @cname("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: # <<<<<<<<<<<<<< + * cdef vector[X] v + * for item in o: + */ + +static std::vector > __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(PyObject *__pyx_v_o) { + std::vector > __pyx_v_v; + PyObject *__pyx_v_item = NULL; + std::vector > __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *(*__pyx_t_3)(PyObject *); + PyObject *__pyx_t_4 = NULL; + std::pair __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", 1); + + /* "vector.from_py":47 + * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: + * cdef vector[X] v + * for item in o: # <<<<<<<<<<<<<< + * v.push_back(item) + * return v + */ + if (likely(PyList_CheckExact(__pyx_v_o)) || PyTuple_CheckExact(__pyx_v_o)) { + __pyx_t_1 = __pyx_v_o; __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = 0; + __pyx_t_3 = NULL; + } else { + __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_o); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 47, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_3)) { + if (likely(PyList_CheckExact(__pyx_t_1))) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 47, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(1, 47, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + { + Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 47, __pyx_L1_error) + #endif + if (__pyx_t_2 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(1, 47, __pyx_L1_error) + #else + __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } + } else { + __pyx_t_4 = __pyx_t_3(__pyx_t_1); + if (unlikely(!__pyx_t_4)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(1, 47, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_4); + } + __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_4); + __pyx_t_4 = 0; + + /* "vector.from_py":48 + * cdef vector[X] v + * for item in o: + * v.push_back(item) # <<<<<<<<<<<<<< + * return v + * + */ + __pyx_t_5 = __pyx_convert_pair_from_py_std_3a__3a_string__and_int(__pyx_v_item); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 48, __pyx_L1_error) + try { + __pyx_v_v.push_back(((std::pair )__pyx_t_5)); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(1, 48, __pyx_L1_error) + } + + /* "vector.from_py":47 + * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: + * cdef vector[X] v + * for item in o: # <<<<<<<<<<<<<< + * v.push_back(item) + * return v + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "vector.from_py":49 + * for item in o: + * v.push_back(item) + * return v # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_v; + goto __pyx_L0; + + /* "vector.from_py":45 + * + * @cname("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") + * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: # <<<<<<<<<<<<<< + * cdef vector[X] v + * for item in o: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("vector.from_py.__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_item); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "FromPyStructUtility":12 + * + * @cname("__pyx_convert__from_py_struct__Date") + * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: # <<<<<<<<<<<<<< + * cdef struct_type result + * if not PyMapping_Check(obj): + */ + +static struct Date __pyx_convert__from_py_struct__Date(PyObject *__pyx_v_obj) { + struct Date __pyx_v_result; + PyObject *__pyx_v_value = NULL; + struct Date __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Date", 1); + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); + if (__pyx_t_1) { + + /* "FromPyStructUtility":15 + * cdef struct_type result + * if not PyMapping_Check(obj): + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + } + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['year'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":18 + * + * try: + * value = obj['year'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'year'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_year); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_v_value = __pyx_t_6; + __pyx_t_6 = 0; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['year'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L9_try_end; + __pyx_L4_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "FromPyStructUtility":19 + * try: + * value = obj['year'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'year'") + * result.year = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":20 + * value = obj['year'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'year'") # <<<<<<<<<<<<<< + * result.year = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 20, __pyx_L6_except_error) + } + goto __pyx_L6_except_error; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['year'] + * except KeyError: + */ + __pyx_L6_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L9_try_end:; + } + + /* "FromPyStructUtility":21 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'year'") + * result.year = value # <<<<<<<<<<<<<< + * try: + * value = obj['month'] + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) + __pyx_v_result.year = __pyx_t_2; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'year'") + * result.year = value + * try: # <<<<<<<<<<<<<< + * value = obj['month'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "FromPyStructUtility":23 + * result.year = value + * try: + * value = obj['month'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'month'") + */ + __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_month); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); + __pyx_t_8 = 0; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'year'") + * result.year = value + * try: # <<<<<<<<<<<<<< + * value = obj['month'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L17_try_end; + __pyx_L12_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":24 + * try: + * value = obj['month'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'month'") + * result.month = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_6); + + /* "FromPyStructUtility":25 + * value = obj['month'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'month'") # <<<<<<<<<<<<<< + * result.month = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 25, __pyx_L14_except_error) + } + goto __pyx_L14_except_error; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'year'") + * result.year = value + * try: # <<<<<<<<<<<<<< + * value = obj['month'] + * except KeyError: + */ + __pyx_L14_except_error:; + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L17_try_end:; + } + + /* "FromPyStructUtility":26 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'month'") + * result.month = value # <<<<<<<<<<<<<< + * try: + * value = obj['day'] + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) + __pyx_v_result.month = __pyx_t_2; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'month'") + * result.month = value + * try: # <<<<<<<<<<<<<< + * value = obj['day'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":28 + * result.month = value + * try: + * value = obj['day'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'day'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_day); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); + __pyx_t_6 = 0; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'month'") + * result.month = value + * try: # <<<<<<<<<<<<<< + * value = obj['day'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L25_try_end; + __pyx_L20_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":29 + * try: + * value = obj['day'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'day'") + * result.day = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":30 + * value = obj['day'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'day'") # <<<<<<<<<<<<<< + * result.day = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 30, __pyx_L22_except_error) + } + goto __pyx_L22_except_error; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'month'") + * result.month = value + * try: # <<<<<<<<<<<<<< + * value = obj['day'] + * except KeyError: + */ + __pyx_L22_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L25_try_end:; + } + + /* "FromPyStructUtility":31 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'day'") + * result.day = value # <<<<<<<<<<<<<< + * try: + * value = obj['weekday'] + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) + __pyx_v_result.day = __pyx_t_2; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'day'") + * result.day = value + * try: # <<<<<<<<<<<<<< + * value = obj['weekday'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "FromPyStructUtility":33 + * result.day = value + * try: + * value = obj['weekday'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'weekday'") + */ + __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_weekday); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 33, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); + __pyx_t_8 = 0; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'day'") + * result.day = value + * try: # <<<<<<<<<<<<<< + * value = obj['weekday'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L33_try_end; + __pyx_L28_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":34 + * try: + * value = obj['weekday'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'weekday'") + * result.weekday = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 34, __pyx_L30_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_6); + + /* "FromPyStructUtility":35 + * value = obj['weekday'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'weekday'") # <<<<<<<<<<<<<< + * result.weekday = value + * return result + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 35, __pyx_L30_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 35, __pyx_L30_except_error) + } + goto __pyx_L30_except_error; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'day'") + * result.day = value + * try: # <<<<<<<<<<<<<< + * value = obj['weekday'] + * except KeyError: + */ + __pyx_L30_except_error:; + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L33_try_end:; + } + + /* "FromPyStructUtility":36 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'weekday'") + * result.weekday = value # <<<<<<<<<<<<<< + * return result + * + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 36, __pyx_L1_error) + __pyx_v_result.weekday = __pyx_t_2; + + /* "FromPyStructUtility":37 + * raise ValueError("No value specified for struct attribute 'weekday'") + * result.weekday = value + * return result # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_result; + goto __pyx_L0; + + /* "FromPyStructUtility":12 + * + * @cname("__pyx_convert__from_py_struct__Date") + * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: # <<<<<<<<<<<<<< + * cdef struct_type result + * if not PyMapping_Check(obj): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_value); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct Time __pyx_convert__from_py_struct__Time(PyObject *__pyx_v_obj) { + struct Time __pyx_v_result; + PyObject *__pyx_v_value = NULL; + struct Time __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Time", 1); + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); + if (__pyx_t_1) { + + /* "FromPyStructUtility":15 + * cdef struct_type result + * if not PyMapping_Check(obj): + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + } + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['hours'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":18 + * + * try: + * value = obj['hours'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'hours'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_hours); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_v_value = __pyx_t_6; + __pyx_t_6 = 0; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['hours'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L9_try_end; + __pyx_L4_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "FromPyStructUtility":19 + * try: + * value = obj['hours'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'hours'") + * result.hours = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":20 + * value = obj['hours'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'hours'") # <<<<<<<<<<<<<< + * result.hours = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 20, __pyx_L6_except_error) + } + goto __pyx_L6_except_error; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['hours'] + * except KeyError: + */ + __pyx_L6_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L9_try_end:; + } + + /* "FromPyStructUtility":21 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'hours'") + * result.hours = value # <<<<<<<<<<<<<< + * try: + * value = obj['minutes'] + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) + __pyx_v_result.hours = __pyx_t_2; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'hours'") + * result.hours = value + * try: # <<<<<<<<<<<<<< + * value = obj['minutes'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "FromPyStructUtility":23 + * result.hours = value + * try: + * value = obj['minutes'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'minutes'") + */ + __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_minutes); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); + __pyx_t_8 = 0; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'hours'") + * result.hours = value + * try: # <<<<<<<<<<<<<< + * value = obj['minutes'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L17_try_end; + __pyx_L12_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":24 + * try: + * value = obj['minutes'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'minutes'") + * result.minutes = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_6); + + /* "FromPyStructUtility":25 + * value = obj['minutes'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'minutes'") # <<<<<<<<<<<<<< + * result.minutes = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 25, __pyx_L14_except_error) + } + goto __pyx_L14_except_error; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'hours'") + * result.hours = value + * try: # <<<<<<<<<<<<<< + * value = obj['minutes'] + * except KeyError: + */ + __pyx_L14_except_error:; + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L17_try_end:; + } + + /* "FromPyStructUtility":26 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'minutes'") + * result.minutes = value # <<<<<<<<<<<<<< + * try: + * value = obj['seconds'] + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) + __pyx_v_result.minutes = __pyx_t_2; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'minutes'") + * result.minutes = value + * try: # <<<<<<<<<<<<<< + * value = obj['seconds'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":28 + * result.minutes = value + * try: + * value = obj['seconds'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'seconds'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_seconds); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); + __pyx_t_6 = 0; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'minutes'") + * result.minutes = value + * try: # <<<<<<<<<<<<<< + * value = obj['seconds'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L25_try_end; + __pyx_L20_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":29 + * try: + * value = obj['seconds'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'seconds'") + * result.seconds = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":30 + * value = obj['seconds'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'seconds'") # <<<<<<<<<<<<<< + * result.seconds = value + * return result + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 30, __pyx_L22_except_error) + } + goto __pyx_L22_except_error; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'minutes'") + * result.minutes = value + * try: # <<<<<<<<<<<<<< + * value = obj['seconds'] + * except KeyError: + */ + __pyx_L22_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L25_try_end:; + } + + /* "FromPyStructUtility":31 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'seconds'") + * result.seconds = value # <<<<<<<<<<<<<< + * return result + * + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) + __pyx_v_result.seconds = __pyx_t_2; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'seconds'") + * result.seconds = value + * return result # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_result; + goto __pyx_L0; + + /* "FromPyStructUtility":12 + * + * @cname("__pyx_convert__from_py_struct__Time") + * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: # <<<<<<<<<<<<<< + * cdef struct_type result + * if not PyMapping_Check(obj): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_value); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct Query __pyx_convert__from_py_struct__Query(PyObject *__pyx_v_obj) { + struct Query __pyx_v_result; + PyObject *__pyx_v_value = NULL; + struct Query __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + std::vector > __pyx_t_10; + struct Date __pyx_t_11; + struct Time __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Query", 1); + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); + if (__pyx_t_1) { + + /* "FromPyStructUtility":15 + * cdef struct_type result + * if not PyMapping_Check(obj): + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) + + /* "FromPyStructUtility":14 + * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: + * cdef struct_type result + * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + */ + } + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['included_sources'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":18 + * + * try: + * value = obj['included_sources'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_sources'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_included_sources); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_v_value = __pyx_t_6; + __pyx_t_6 = 0; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['included_sources'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L9_try_end; + __pyx_L4_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "FromPyStructUtility":19 + * try: + * value = obj['included_sources'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'included_sources'") + * result.included_sources = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":20 + * value = obj['included_sources'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_sources'") # <<<<<<<<<<<<<< + * result.included_sources = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 20, __pyx_L6_except_error) + } + goto __pyx_L6_except_error; + + /* "FromPyStructUtility":17 + * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) + * + * try: # <<<<<<<<<<<<<< + * value = obj['included_sources'] + * except KeyError: + */ + __pyx_L6_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L9_try_end:; + } + + /* "FromPyStructUtility":21 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_sources'") + * result.included_sources = value # <<<<<<<<<<<<<< + * try: + * value = obj['included_targets'] + */ + __pyx_t_10 = __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) + __pyx_v_result.included_sources = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_10); + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'included_sources'") + * result.included_sources = value + * try: # <<<<<<<<<<<<<< + * value = obj['included_targets'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "FromPyStructUtility":23 + * result.included_sources = value + * try: + * value = obj['included_targets'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_targets'") + */ + __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_included_targets); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); + __pyx_t_8 = 0; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'included_sources'") + * result.included_sources = value + * try: # <<<<<<<<<<<<<< + * value = obj['included_targets'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L17_try_end; + __pyx_L12_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":24 + * try: + * value = obj['included_targets'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'included_targets'") + * result.included_targets = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_6); + + /* "FromPyStructUtility":25 + * value = obj['included_targets'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_targets'") # <<<<<<<<<<<<<< + * result.included_targets = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 25, __pyx_L14_except_error) + } + goto __pyx_L14_except_error; + + /* "FromPyStructUtility":22 + * raise ValueError("No value specified for struct attribute 'included_sources'") + * result.included_sources = value + * try: # <<<<<<<<<<<<<< + * value = obj['included_targets'] + * except KeyError: + */ + __pyx_L14_except_error:; + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L17_try_end:; + } + + /* "FromPyStructUtility":26 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_targets'") + * result.included_targets = value # <<<<<<<<<<<<<< + * try: + * value = obj['date'] + */ + __pyx_t_10 = __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) + __pyx_v_result.included_targets = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_10); + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'included_targets'") + * result.included_targets = value + * try: # <<<<<<<<<<<<<< + * value = obj['date'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":28 + * result.included_targets = value + * try: + * value = obj['date'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'date'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_date); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); + __pyx_t_6 = 0; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'included_targets'") + * result.included_targets = value + * try: # <<<<<<<<<<<<<< + * value = obj['date'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L25_try_end; + __pyx_L20_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":29 + * try: + * value = obj['date'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'date'") + * result.date = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":30 + * value = obj['date'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'date'") # <<<<<<<<<<<<<< + * result.date = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 30, __pyx_L22_except_error) + } + goto __pyx_L22_except_error; + + /* "FromPyStructUtility":27 + * raise ValueError("No value specified for struct attribute 'included_targets'") + * result.included_targets = value + * try: # <<<<<<<<<<<<<< + * value = obj['date'] + * except KeyError: + */ + __pyx_L22_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L25_try_end:; + } + + /* "FromPyStructUtility":31 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'date'") + * result.date = value # <<<<<<<<<<<<<< + * try: + * value = obj['departure_time'] + */ + __pyx_t_11 = __pyx_convert__from_py_struct__Date(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) + __pyx_v_result.date = __pyx_t_11; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'date'") + * result.date = value + * try: # <<<<<<<<<<<<<< + * value = obj['departure_time'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "FromPyStructUtility":33 + * result.date = value + * try: + * value = obj['departure_time'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'departure_time'") + */ + __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_departure_time); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 33, __pyx_L28_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); + __pyx_t_8 = 0; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'date'") + * result.date = value + * try: # <<<<<<<<<<<<<< + * value = obj['departure_time'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L33_try_end; + __pyx_L28_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":34 + * try: + * value = obj['departure_time'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'departure_time'") + * result.departure_time = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 34, __pyx_L30_except_error) + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_6); + + /* "FromPyStructUtility":35 + * value = obj['departure_time'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'departure_time'") # <<<<<<<<<<<<<< + * result.departure_time = value + * try: + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 35, __pyx_L30_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 35, __pyx_L30_except_error) + } + goto __pyx_L30_except_error; + + /* "FromPyStructUtility":32 + * raise ValueError("No value specified for struct attribute 'date'") + * result.date = value + * try: # <<<<<<<<<<<<<< + * value = obj['departure_time'] + * except KeyError: + */ + __pyx_L30_except_error:; + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L33_try_end:; + } + + /* "FromPyStructUtility":36 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'departure_time'") + * result.departure_time = value # <<<<<<<<<<<<<< + * try: + * value = obj['max_transfers'] + */ + __pyx_t_12 = __pyx_convert__from_py_struct__Time(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 36, __pyx_L1_error) + __pyx_v_result.departure_time = __pyx_t_12; + + /* "FromPyStructUtility":37 + * raise ValueError("No value specified for struct attribute 'departure_time'") + * result.departure_time = value + * try: # <<<<<<<<<<<<<< + * value = obj['max_transfers'] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + /*try:*/ { + + /* "FromPyStructUtility":38 + * result.departure_time = value + * try: + * value = obj['max_transfers'] # <<<<<<<<<<<<<< + * except KeyError: + * raise ValueError("No value specified for struct attribute 'max_transfers'") + */ + __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_max_transfers); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 38, __pyx_L36_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); + __pyx_t_6 = 0; + + /* "FromPyStructUtility":37 + * raise ValueError("No value specified for struct attribute 'departure_time'") + * result.departure_time = value + * try: # <<<<<<<<<<<<<< + * value = obj['max_transfers'] + * except KeyError: + */ + } + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + goto __pyx_L41_try_end; + __pyx_L36_error:; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "FromPyStructUtility":39 + * try: + * value = obj['max_transfers'] + * except KeyError: # <<<<<<<<<<<<<< + * raise ValueError("No value specified for struct attribute 'max_transfers'") + * result.max_transfers = value + */ + __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_2) { + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 39, __pyx_L38_except_error) + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + + /* "FromPyStructUtility":40 + * value = obj['max_transfers'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'max_transfers'") # <<<<<<<<<<<<<< + * result.max_transfers = value + * return result + */ + __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 40, __pyx_L38_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(1, 40, __pyx_L38_except_error) + } + goto __pyx_L38_except_error; + + /* "FromPyStructUtility":37 + * raise ValueError("No value specified for struct attribute 'departure_time'") + * result.departure_time = value + * try: # <<<<<<<<<<<<<< + * value = obj['max_transfers'] + * except KeyError: + */ + __pyx_L38_except_error:; + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); + goto __pyx_L1_error; + __pyx_L41_try_end:; + } + + /* "FromPyStructUtility":41 + * except KeyError: + * raise ValueError("No value specified for struct attribute 'max_transfers'") + * result.max_transfers = value # <<<<<<<<<<<<<< + * return result + * + */ + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 41, __pyx_L1_error) + __pyx_v_result.max_transfers = __pyx_t_2; + + /* "FromPyStructUtility":42 + * raise ValueError("No value specified for struct attribute 'max_transfers'") + * result.max_transfers = value + * return result # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_result; + goto __pyx_L0; + + /* "FromPyStructUtility":12 + * + * @cname("__pyx_convert__from_py_struct__Query") + * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: # <<<<<<<<<<<<<< + * cdef struct_type result + * if not PyMapping_Check(obj): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_pretend_to_initialize(&__pyx_r); + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_value); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":13 + * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping + * + * def __cinit__(self, str input_directory): # <<<<<<<<<<<<<< + * """Initialize the RAPTOR router + * + */ + +/* Python wrapper */ +static int __pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_input_directory = 0; + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return -1; + #endif + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_directory,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_input_directory)) != 0)) { + (void)__Pyx_Arg_NewRef_VARARGS(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__cinit__") < 0)) __PYX_ERR(0, 13, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); + } + __pyx_v_input_directory = ((PyObject*)values[0]); + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 13, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_input_directory), (&PyUnicode_Type), 1, "input_directory", 1))) __PYX_ERR(0, 13, __pyx_L1_error) + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_input_directory); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = -1; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_input_directory) { + std::string __pyx_v_cpp_directory; + std::unordered_map __pyx_v_agencies; + std::unordered_map __pyx_v_services; + std::unordered_map __pyx_v_trips; + std::unordered_map ,Route,struct pair_hash> __pyx_v_routes; + std::unordered_map __pyx_v_stops; + Parser *__pyx_v_parser; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + std::string __pyx_t_2; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 1); + + /* "PyPTRouter.pyx":30 + * """ + * # Convert Python string to C++ string + * cdef string cpp_directory = input_directory.encode('utf-8') # <<<<<<<<<<<<<< + * + * # Initialize data containers for GTFS data + */ + if (unlikely(__pyx_v_input_directory == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode"); + __PYX_ERR(0, 30, __pyx_L1_error) + } + __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_input_directory); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_cpp_directory = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_2); + + /* "PyPTRouter.pyx":40 + * + * # Process directory + * cdef Parser* parser = new Parser(cpp_directory) # <<<<<<<<<<<<<< + * + * agencies = parser.getAgencies() + */ + __pyx_v_parser = new Parser(__pyx_v_cpp_directory); + + /* "PyPTRouter.pyx":42 + * cdef Parser* parser = new Parser(cpp_directory) + * + * agencies = parser.getAgencies() # <<<<<<<<<<<<<< + * services = parser.getServices() + * trips = parser.getTrips() + */ + __pyx_v_agencies = __pyx_v_parser->getAgencies(); + + /* "PyPTRouter.pyx":43 + * + * agencies = parser.getAgencies() + * services = parser.getServices() # <<<<<<<<<<<<<< + * trips = parser.getTrips() + * routes = parser.getRoutes() + */ + __pyx_v_services = __pyx_v_parser->getServices(); + + /* "PyPTRouter.pyx":44 + * agencies = parser.getAgencies() + * services = parser.getServices() + * trips = parser.getTrips() # <<<<<<<<<<<<<< + * routes = parser.getRoutes() + * stops = parser.getStops() + */ + __pyx_v_trips = __pyx_v_parser->getTrips(); + + /* "PyPTRouter.pyx":45 + * services = parser.getServices() + * trips = parser.getTrips() + * routes = parser.getRoutes() # <<<<<<<<<<<<<< + * stops = parser.getStops() + * + */ + __pyx_v_routes = __pyx_v_parser->getRoutes(); + + /* "PyPTRouter.pyx":46 + * trips = parser.getTrips() + * routes = parser.getRoutes() + * stops = parser.getStops() # <<<<<<<<<<<<<< + * + * del parser + */ + __pyx_v_stops = __pyx_v_parser->getStops(); + + /* "PyPTRouter.pyx":48 + * stops = parser.getStops() + * + * del parser # <<<<<<<<<<<<<< + * + * # Clean up existing instance if any + */ + delete __pyx_v_parser; + + /* "PyPTRouter.pyx":51 + * + * # Clean up existing instance if any + * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< + * del self.raptor_ptr + * + */ + __pyx_t_3 = (__pyx_v_self->raptor_ptr != NULL); + if (__pyx_t_3) { + + /* "PyPTRouter.pyx":52 + * # Clean up existing instance if any + * if self.raptor_ptr != NULL: + * del self.raptor_ptr # <<<<<<<<<<<<<< + * + * # Create new RAPTOR instance with data + */ + delete __pyx_v_self->raptor_ptr; + + /* "PyPTRouter.pyx":51 + * + * # Clean up existing instance if any + * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< + * del self.raptor_ptr + * + */ + } + + /* "PyPTRouter.pyx":55 + * + * # Create new RAPTOR instance with data + * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) # <<<<<<<<<<<<<< + * + * def __dealloc__(self): + */ + __pyx_v_self->raptor_ptr = new Raptor(__pyx_v_agencies, __pyx_v_services, __pyx_v_stops, __pyx_v_routes, __pyx_v_trips); + + /* "PyPTRouter.pyx":13 + * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping + * + * def __cinit__(self, str input_directory): # <<<<<<<<<<<<<< + * """Initialize the RAPTOR router + * + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":57 + * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * """Deallocate the RAPTOR router + * + */ + +/* Python wrapper */ +static void __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(PyObject *__pyx_v_self) { + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); + __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self) { + int __pyx_t_1; + + /* "PyPTRouter.pyx":68 + * - Sets raptor_ptr to NULL after deletion is handled by C++ + * """ + * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< + * del self.raptor_ptr + * + */ + __pyx_t_1 = (__pyx_v_self->raptor_ptr != NULL); + if (__pyx_t_1) { + + /* "PyPTRouter.pyx":69 + * """ + * if self.raptor_ptr != NULL: + * del self.raptor_ptr # <<<<<<<<<<<<<< + * + * def construct_query( + */ + delete __pyx_v_self->raptor_ptr; + + /* "PyPTRouter.pyx":68 + * - Sets raptor_ptr to NULL after deletion is handled by C++ + * """ + * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< + * del self.raptor_ptr + * + */ + } + + /* "PyPTRouter.pyx":57 + * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * """Deallocate the RAPTOR router + * + */ + + /* function exit code */ +} + +/* "PyPTRouter.pyx":71 + * del self.raptor_ptr + * + * def construct_query( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query, "PyPTRouter.construct_query(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1)\nConstruct query information.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed\n\n Returns:\n query (Query)\n "); +static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query = {"construct_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query}; +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_included_sources = 0; + PyObject *__pyx_v_included_targets = 0; + int __pyx_v_max_transfers; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("construct_query (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, 1); __PYX_ERR(0, 71, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, 2); __PYX_ERR(0, 71, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "construct_query") < 0)) __PYX_ERR(0, 71, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_arrival_datetime = values[0]; + __pyx_v_included_sources = ((PyObject*)values[1]); + __pyx_v_included_targets = ((PyObject*)values[2]); + if (values[3]) { + __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 74, __pyx_L3_error) + } else { + __pyx_v_max_transfers = ((int)-1); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 71, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.construct_query", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 74, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 74, __pyx_L1_error) + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers) { + int __pyx_v_year; + int __pyx_v_month; + int __pyx_v_day; + int __pyx_v_weekday; + int __pyx_v_hours; + int __pyx_v_minutes; + int __pyx_v_seconds; + struct Date __pyx_v_date; + struct Time __pyx_v_departure_time; + std::vector > __pyx_v_src_vec; + std::vector > __pyx_v_tgt_vec; + PyObject *__pyx_v_inc_src = NULL; + PyObject *__pyx_v_inc_tgt = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + unsigned int __pyx_t_5; + struct Date __pyx_t_6; + struct Time __pyx_t_7; + std::vector > __pyx_t_8; + Py_ssize_t __pyx_t_9; + int __pyx_t_10; + int __pyx_t_11; + Py_ssize_t __pyx_t_12; + PyObject *__pyx_t_13 = NULL; + std::string __pyx_t_14; + std::pair __pyx_t_15; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("construct_query", 1); + + /* "PyPTRouter.pyx":88 + * """ + * # Calculate day of week using Python's datetime + * cdef int year = arrival_datetime.year # <<<<<<<<<<<<<< + * cdef int month = arrival_datetime.month + * cdef int day = arrival_datetime.day + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_year); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_year = __pyx_t_2; + + /* "PyPTRouter.pyx":89 + * # Calculate day of week using Python's datetime + * cdef int year = arrival_datetime.year + * cdef int month = arrival_datetime.month # <<<<<<<<<<<<<< + * cdef int day = arrival_datetime.day + * cdef int weekday = arrival_datetime.weekday() + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_month); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_month = __pyx_t_2; + + /* "PyPTRouter.pyx":90 + * cdef int year = arrival_datetime.year + * cdef int month = arrival_datetime.month + * cdef int day = arrival_datetime.day # <<<<<<<<<<<<<< + * cdef int weekday = arrival_datetime.weekday() + * cdef int hours = arrival_datetime.hour + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_day); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 90, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_day = __pyx_t_2; + + /* "PyPTRouter.pyx":91 + * cdef int month = arrival_datetime.month + * cdef int day = arrival_datetime.day + * cdef int weekday = arrival_datetime.weekday() # <<<<<<<<<<<<<< + * cdef int hours = arrival_datetime.hour + * cdef int minutes = arrival_datetime.minute + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_weekday); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 0+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 91, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_weekday = __pyx_t_2; + + /* "PyPTRouter.pyx":92 + * cdef int day = arrival_datetime.day + * cdef int weekday = arrival_datetime.weekday() + * cdef int hours = arrival_datetime.hour # <<<<<<<<<<<<<< + * cdef int minutes = arrival_datetime.minute + * cdef int seconds = arrival_datetime.second + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_hour); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_hours = __pyx_t_2; + + /* "PyPTRouter.pyx":93 + * cdef int weekday = arrival_datetime.weekday() + * cdef int hours = arrival_datetime.hour + * cdef int minutes = arrival_datetime.minute # <<<<<<<<<<<<<< + * cdef int seconds = arrival_datetime.second + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_minute); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_minutes = __pyx_t_2; + + /* "PyPTRouter.pyx":94 + * cdef int hours = arrival_datetime.hour + * cdef int minutes = arrival_datetime.minute + * cdef int seconds = arrival_datetime.second # <<<<<<<<<<<<<< + * + * # Create date, time objects for C++ + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_second); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_seconds = __pyx_t_2; + + /* "PyPTRouter.pyx":97 + * + * # Create date, time objects for C++ + * cdef Date date = Date(year, month, day, weekday) # <<<<<<<<<<<<<< + * cdef Time departure_time = Time(hours, minutes, seconds) + * + */ + __pyx_t_6.year = __pyx_v_year; + __pyx_t_6.month = __pyx_v_month; + __pyx_t_6.day = __pyx_v_day; + __pyx_t_6.weekday = __pyx_v_weekday; + __pyx_v_date = __pyx_t_6; + + /* "PyPTRouter.pyx":98 + * # Create date, time objects for C++ + * cdef Date date = Date(year, month, day, weekday) + * cdef Time departure_time = Time(hours, minutes, seconds) # <<<<<<<<<<<<<< + * + * cdef Query query + */ + __pyx_t_7.hours = __pyx_v_hours; + __pyx_t_7.minutes = __pyx_v_minutes; + __pyx_t_7.seconds = __pyx_v_seconds; + __pyx_v_departure_time = __pyx_t_7; + + /* "PyPTRouter.pyx":105 + * cdef vector[pair[string, int]] tgt_vec + * + * src_vec = vector[pair[string, int]]() # <<<<<<<<<<<<<< + * for inc_src in included_sources: + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): + */ + try { + __pyx_t_8 = std::vector > (); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 105, __pyx_L1_error) + } + __pyx_v_src_vec = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_8); + + /* "PyPTRouter.pyx":106 + * + * src_vec = vector[pair[string, int]]() + * for inc_src in included_sources: # <<<<<<<<<<<<<< + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + */ + if (unlikely(__pyx_v_included_sources == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(0, 106, __pyx_L1_error) + } + __pyx_t_1 = __pyx_v_included_sources; __Pyx_INCREF(__pyx_t_1); + __pyx_t_9 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 106, __pyx_L1_error) + #endif + if (__pyx_t_9 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_9); __Pyx_INCREF(__pyx_t_3); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 106, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_inc_src, __pyx_t_3); + __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":107 + * src_vec = vector[pair[string, int]]() + * for inc_src in included_sources: + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): # <<<<<<<<<<<<<< + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + * else: + */ + __pyx_t_11 = PyTuple_Check(__pyx_v_inc_src); + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_12 = PyObject_Length(__pyx_v_inc_src); if (unlikely(__pyx_t_12 == ((Py_ssize_t)-1))) __PYX_ERR(0, 107, __pyx_L1_error) + __pyx_t_11 = (__pyx_t_12 == 2); + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = PyUnicode_Check(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = PyInt_Check(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __pyx_t_11; + __pyx_L6_bool_binop_done:; + if (likely(__pyx_t_10)) { + + /* "PyPTRouter.pyx":108 + * for inc_src in included_sources: + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) # <<<<<<<<<<<<<< + * else: + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") + */ + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_inc_src, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_encode); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_13))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_13); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_13, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_kp_u_utf_8}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_13, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + } + __pyx_t_14 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + try { + __pyx_t_15 = std::pair (__pyx_t_14, __pyx_t_2); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 108, __pyx_L1_error) + } + try { + __pyx_v_src_vec.push_back(__pyx_t_15); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 108, __pyx_L1_error) + } + + /* "PyPTRouter.pyx":107 + * src_vec = vector[pair[string, int]]() + * for inc_src in included_sources: + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): # <<<<<<<<<<<<<< + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + * else: + */ + goto __pyx_L5; + } + + /* "PyPTRouter.pyx":110 + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + * else: + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") # <<<<<<<<<<<<<< + * + * tgt_vec = vector[pair[string, int]]() + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_inc_src)), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_13 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Expected_string_int_tuple_got, __pyx_t_3); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_13); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 110, __pyx_L1_error) + } + __pyx_L5:; + + /* "PyPTRouter.pyx":106 + * + * src_vec = vector[pair[string, int]]() + * for inc_src in included_sources: # <<<<<<<<<<<<<< + * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): + * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "PyPTRouter.pyx":112 + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") + * + * tgt_vec = vector[pair[string, int]]() # <<<<<<<<<<<<<< + * for inc_tgt in included_targets: + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): + */ + try { + __pyx_t_8 = std::vector > (); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 112, __pyx_L1_error) + } + __pyx_v_tgt_vec = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_8); + + /* "PyPTRouter.pyx":113 + * + * tgt_vec = vector[pair[string, int]]() + * for inc_tgt in included_targets: # <<<<<<<<<<<<<< + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + */ + if (unlikely(__pyx_v_included_targets == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(0, 113, __pyx_L1_error) + } + __pyx_t_1 = __pyx_v_included_targets; __Pyx_INCREF(__pyx_t_1); + __pyx_t_9 = 0; + for (;;) { + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 113, __pyx_L1_error) + #endif + if (__pyx_t_9 >= __pyx_temp) break; + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_9); __Pyx_INCREF(__pyx_t_3); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 113, __pyx_L1_error) + #else + __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_inc_tgt, __pyx_t_3); + __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":114 + * tgt_vec = vector[pair[string, int]]() + * for inc_tgt in included_targets: + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): # <<<<<<<<<<<<<< + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + * else: + */ + __pyx_t_11 = PyTuple_Check(__pyx_v_inc_tgt); + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_12 = PyObject_Length(__pyx_v_inc_tgt); if (unlikely(__pyx_t_12 == ((Py_ssize_t)-1))) __PYX_ERR(0, 114, __pyx_L1_error) + __pyx_t_11 = (__pyx_t_12 == 2); + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = PyUnicode_Check(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_11) { + } else { + __pyx_t_10 = __pyx_t_11; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_11 = PyInt_Check(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_10 = __pyx_t_11; + __pyx_L14_bool_binop_done:; + if (likely(__pyx_t_10)) { + + /* "PyPTRouter.pyx":115 + * for inc_tgt in included_targets: + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) # <<<<<<<<<<<<<< + * else: + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") + */ + __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __pyx_t_13 = NULL; + __pyx_t_5 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_13)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_13); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_5 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_13, __pyx_kp_u_utf_8}; + __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __pyx_t_14 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + try { + __pyx_t_15 = std::pair (__pyx_t_14, __pyx_t_2); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 115, __pyx_L1_error) + } + try { + __pyx_v_tgt_vec.push_back(__pyx_t_15); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 115, __pyx_L1_error) + } + + /* "PyPTRouter.pyx":114 + * tgt_vec = vector[pair[string, int]]() + * for inc_tgt in included_targets: + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): # <<<<<<<<<<<<<< + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + * else: + */ + goto __pyx_L13; + } + + /* "PyPTRouter.pyx":117 + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + * else: + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") # <<<<<<<<<<<<<< + * + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_inc_tgt)), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Expected_string_int_tuple_got, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 117, __pyx_L1_error) + } + __pyx_L13:; + + /* "PyPTRouter.pyx":113 + * + * tgt_vec = vector[pair[string, int]]() + * for inc_tgt in included_targets: # <<<<<<<<<<<<<< + * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): + * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "PyPTRouter.pyx":119 + * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") + * + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) # <<<<<<<<<<<<<< + * + * def return_pt_journeys_1to1( + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_src_vec); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_included_sources, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_tgt_vec); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_included_targets, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __pyx_convert__to_py_struct__Date(__pyx_v_date); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_date, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __pyx_convert__to_py_struct__Time(__pyx_v_departure_time); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_transfers, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "PyPTRouter.pyx":71 + * del self.raptor_ptr + * + * def construct_query( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.construct_query", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_inc_src); + __Pyx_XDECREF(__pyx_v_inc_tgt); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":121 + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + * + * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1, "PyPTRouter.return_pt_journeys_1to1(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the best public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); +static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1 = {"return_pt_journeys_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1}; +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_included_sources = 0; + PyObject *__pyx_v_included_targets = 0; + int __pyx_v_max_transfers; + bool __pyx_v_detailed; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("return_pt_journeys_1to1 (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, 1); __PYX_ERR(0, 121, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, 2); __PYX_ERR(0, 121, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_detailed); + if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "return_pt_journeys_1to1") < 0)) __PYX_ERR(0, 121, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_arrival_datetime = values[0]; + __pyx_v_included_sources = ((PyObject*)values[1]); + __pyx_v_included_targets = ((PyObject*)values[2]); + if (values[3]) { + __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 124, __pyx_L3_error) + } else { + __pyx_v_max_transfers = ((int)-1); + } + if (values[4]) { + __pyx_v_detailed = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_detailed == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 125, __pyx_L3_error) + } else { + + /* "PyPTRouter.pyx":125 + * arrival_datetime, + * list included_sources, list included_targets, int max_transfers=-1, + * bool detailed=False, # <<<<<<<<<<<<<< + * ): + * """Find the best public transport journey from source to target + */ + __pyx_v_detailed = ((bool)0); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, __pyx_nargs); __PYX_ERR(0, 121, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_pt_journeys_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 124, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 124, __pyx_L1_error) + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); + + /* "PyPTRouter.pyx":121 + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + * + * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { + PyObject *__pyx_v_query = NULL; + std::vector __pyx_v_journeys; + PyObject *__pyx_v_journeys_list = NULL; + std::vector ::size_type __pyx_v_i; + PyObject *__pyx_v_journey_dict = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + unsigned int __pyx_t_6; + struct Query __pyx_t_7; + std::vector ::size_type __pyx_t_8; + std::vector ::size_type __pyx_t_9; + std::vector ::size_type __pyx_t_10; + int __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("return_pt_journeys_1to1", 1); + + /* "PyPTRouter.pyx":144 + * - duration: Total journey duration in seconds + * """ + * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + */ + __pyx_t_1 = (__pyx_v_self->raptor_ptr == NULL); + if (unlikely(__pyx_t_1)) { + + /* "PyPTRouter.pyx":145 + * """ + * if self.raptor_ptr == NULL: + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< + * + * query = self.construct_query( + */ + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 145, __pyx_L1_error) + + /* "PyPTRouter.pyx":144 + * - duration: Total journey duration in seconds + * """ + * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + */ + } + + /* "PyPTRouter.pyx":147 + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + * query = self.construct_query( # <<<<<<<<<<<<<< + * arrival_datetime, included_sources, included_targets, max_transfers, + * ) + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "PyPTRouter.pyx":148 + * + * query = self.construct_query( + * arrival_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_query = __pyx_t_2; + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":152 + * + * # Set query and find journeys + * self.raptor_ptr.setQuery(query) # <<<<<<<<<<<<<< + * cdef vector[Journey] journeys = self.raptor_ptr.findJourneys() + * + */ + __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 152, __pyx_L1_error) + __pyx_v_self->raptor_ptr->setQuery(__pyx_t_7); + + /* "PyPTRouter.pyx":153 + * # Set query and find journeys + * self.raptor_ptr.setQuery(query) + * cdef vector[Journey] journeys = self.raptor_ptr.findJourneys() # <<<<<<<<<<<<<< + * + * # Check if any journeys were found + */ + __pyx_v_journeys = __pyx_v_self->raptor_ptr->findJourneys(); + + /* "PyPTRouter.pyx":156 + * + * # Check if any journeys were found + * if journeys.size() == 0: # <<<<<<<<<<<<<< + * return None + * + */ + __pyx_t_1 = (__pyx_v_journeys.size() == 0); + if (__pyx_t_1) { + + /* "PyPTRouter.pyx":157 + * # Check if any journeys were found + * if journeys.size() == 0: + * return None # <<<<<<<<<<<<<< + * + * # Convert all journeys to Python list of dictionaries + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "PyPTRouter.pyx":156 + * + * # Check if any journeys were found + * if journeys.size() == 0: # <<<<<<<<<<<<<< + * return None + * + */ + } + + /* "PyPTRouter.pyx":160 + * + * # Convert all journeys to Python list of dictionaries + * journeys_list = [] # <<<<<<<<<<<<<< + * for i in range(journeys.size()): + * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) + */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 160, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_journeys_list = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":161 + * # Convert all journeys to Python list of dictionaries + * journeys_list = [] + * for i in range(journeys.size()): # <<<<<<<<<<<<<< + * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) + * journeys_list.append(journey_dict) + */ + __pyx_t_8 = __pyx_v_journeys.size(); + __pyx_t_9 = __pyx_t_8; + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { + __pyx_v_i = __pyx_t_10; + + /* "PyPTRouter.pyx":162 + * journeys_list = [] + * for i in range(journeys.size()): + * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) # <<<<<<<<<<<<<< + * journeys_list.append(journey_dict) + * + */ + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, (__pyx_v_journeys[__pyx_v_i]), __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XDECREF_SET(__pyx_v_journey_dict, __pyx_t_2); + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":163 + * for i in range(journeys.size()): + * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) + * journeys_list.append(journey_dict) # <<<<<<<<<<<<<< + * + * return journeys_list + */ + __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_journeys_list, __pyx_v_journey_dict); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 163, __pyx_L1_error) + } + + /* "PyPTRouter.pyx":165 + * journeys_list.append(journey_dict) + * + * return journeys_list # <<<<<<<<<<<<<< + * + * def return_fastest_pt_journey_1to1( + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_journeys_list); + __pyx_r = __pyx_v_journeys_list; + goto __pyx_L0; + + /* "PyPTRouter.pyx":121 + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + * + * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_pt_journeys_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_query); + __Pyx_XDECREF(__pyx_v_journeys_list); + __Pyx_XDECREF(__pyx_v_journey_dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":167 + * return journeys_list + * + * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1, "PyPTRouter.return_fastest_pt_journey_1to1(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the fastest public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); +static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1 = {"return_fastest_pt_journey_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1}; +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_included_sources = 0; + PyObject *__pyx_v_included_targets = 0; + int __pyx_v_max_transfers; + bool __pyx_v_detailed; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[5] = {0,0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("return_fastest_pt_journey_1to1 (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, 1); __PYX_ERR(0, 167, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) + else { + __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, 2); __PYX_ERR(0, 167, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); + if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_detailed); + if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "return_fastest_pt_journey_1to1") < 0)) __PYX_ERR(0, 167, __pyx_L3_error) + } + } else { + switch (__pyx_nargs) { + case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); + values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_arrival_datetime = values[0]; + __pyx_v_included_sources = ((PyObject*)values[1]); + __pyx_v_included_targets = ((PyObject*)values[2]); + if (values[3]) { + __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 170, __pyx_L3_error) + } else { + __pyx_v_max_transfers = ((int)-1); + } + if (values[4]) { + __pyx_v_detailed = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_detailed == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 171, __pyx_L3_error) + } else { + + /* "PyPTRouter.pyx":171 + * arrival_datetime, + * list included_sources, list included_targets, int max_transfers=-1, + * bool detailed=False, # <<<<<<<<<<<<<< + * ): + * """Find the fastest public transport journey from source to target + */ + __pyx_v_detailed = ((bool)0); + } + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, __pyx_nargs); __PYX_ERR(0, 167, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_fastest_pt_journey_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 170, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 170, __pyx_L1_error) + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); + + /* "PyPTRouter.pyx":167 + * return journeys_list + * + * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { + PyObject *__pyx_v_query = NULL; + std::optional __pyx_v_journey_opt; + struct Journey __pyx_v_journey; + PyObject *__pyx_v_journey_dict = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + unsigned int __pyx_t_6; + struct Query __pyx_t_7; + __Pyx_FakeReference __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("return_fastest_pt_journey_1to1", 1); + + /* "PyPTRouter.pyx":190 + * - duration: Total journey duration in seconds + * """ + * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + */ + __pyx_t_1 = (__pyx_v_self->raptor_ptr == NULL); + if (unlikely(__pyx_t_1)) { + + /* "PyPTRouter.pyx":191 + * """ + * if self.raptor_ptr == NULL: + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< + * + * query = self.construct_query( + */ + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 191, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 191, __pyx_L1_error) + + /* "PyPTRouter.pyx":190 + * - duration: Total journey duration in seconds + * """ + * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + */ + } + + /* "PyPTRouter.pyx":193 + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + * + * query = self.construct_query( # <<<<<<<<<<<<<< + * arrival_datetime, included_sources, included_targets, max_transfers, + * ) + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "PyPTRouter.pyx":194 + * + * query = self.construct_query( + * arrival_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< + * ) + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 194, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + #if CYTHON_UNPACK_METHODS + if (likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #endif + { + PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; + __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __pyx_v_query = __pyx_t_2; + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":198 + * + * # Set query and find journeys + * self.raptor_ptr.setQuery(query) # <<<<<<<<<<<<<< + * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() + * + */ + __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 198, __pyx_L1_error) + __pyx_v_self->raptor_ptr->setQuery(__pyx_t_7); + + /* "PyPTRouter.pyx":199 + * # Set query and find journeys + * self.raptor_ptr.setQuery(query) + * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() # <<<<<<<<<<<<<< + * + * # Check if journey was found + */ + __pyx_v_journey_opt = __pyx_v_self->raptor_ptr->findOptimalJourney(); + + /* "PyPTRouter.pyx":202 + * + * # Check if journey was found + * if not journey_opt.has_value(): # <<<<<<<<<<<<<< + * return None + * + */ + __pyx_t_1 = (!(__pyx_v_journey_opt.has_value() != 0)); + if (__pyx_t_1) { + + /* "PyPTRouter.pyx":203 + * # Check if journey was found + * if not journey_opt.has_value(): + * return None # <<<<<<<<<<<<<< + * + * # Get the actual journey from optional + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "PyPTRouter.pyx":202 + * + * # Check if journey was found + * if not journey_opt.has_value(): # <<<<<<<<<<<<<< + * return None + * + */ + } + + /* "PyPTRouter.pyx":206 + * + * # Get the actual journey from optional + * cdef Journey journey = journey_opt.value() # <<<<<<<<<<<<<< + * + * # Convert journey to Python dictionary + */ + try { + __pyx_t_8 = __pyx_v_journey_opt.value(); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 206, __pyx_L1_error) + } + __pyx_v_journey = __pyx_t_8; + + /* "PyPTRouter.pyx":209 + * + * # Convert journey to Python dictionary + * journey_dict = self._convert_journey_to_dict(journey, detailed) # <<<<<<<<<<<<<< + * + * return journey_dict + */ + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, __pyx_v_journey, __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 209, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_journey_dict = __pyx_t_2; + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":211 + * journey_dict = self._convert_journey_to_dict(journey, detailed) + * + * return journey_dict # <<<<<<<<<<<<<< + * + * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_journey_dict); + __pyx_r = __pyx_v_journey_dict; + goto __pyx_L0; + + /* "PyPTRouter.pyx":167 + * return journeys_list + * + * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_fastest_pt_journey_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_query); + __Pyx_XDECREF(__pyx_v_journey_dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":213 + * return journey_dict + * + * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< + * """Convert a Journey object to a Python dictionary + * + */ + +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct Journey __pyx_v_journey, bool __pyx_v_detailed) { + PyObject *__pyx_v_journey_dict = NULL; + std::vector ::size_type __pyx_v_i; + PyObject *__pyx_v_step_dict = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + std::vector ::size_type __pyx_t_4; + std::vector ::size_type __pyx_t_5; + std::vector ::size_type __pyx_t_6; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_convert_journey_to_dict", 1); + + /* "PyPTRouter.pyx":228 + * journey_dict = { + * # Overall journey information + * "duration": journey.duration, # <<<<<<<<<<<<<< + * "source_transfer_time": journey.source_transfer_time, + * "waiting_time": journey.waiting_time, + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.duration); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_duration, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":229 + * # Overall journey information + * "duration": journey.duration, + * "source_transfer_time": journey.source_transfer_time, # <<<<<<<<<<<<<< + * "waiting_time": journey.waiting_time, + * "trip_time": journey.trip_time, + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 229, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":230 + * "duration": journey.duration, + * "source_transfer_time": journey.source_transfer_time, + * "waiting_time": journey.waiting_time, # <<<<<<<<<<<<<< + * "trip_time": journey.trip_time, + * "num_transfers": journey.num_transfers, + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.waiting_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_waiting_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":231 + * "source_transfer_time": journey.source_transfer_time, + * "waiting_time": journey.waiting_time, + * "trip_time": journey.trip_time, # <<<<<<<<<<<<<< + * "num_transfers": journey.num_transfers, + * + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.trip_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_trip_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":232 + * "waiting_time": journey.waiting_time, + * "trip_time": journey.trip_time, + * "num_transfers": journey.num_transfers, # <<<<<<<<<<<<<< + * + * # Departure information + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.num_transfers); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_num_transfers, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":235 + * + * # Departure information + * "departure_time": journey.departure_secs, # <<<<<<<<<<<<<< + * "departure_day": self._day_to_str(journey.departure_day), + * + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.departure_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_departure_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":236 + * # Departure information + * "departure_time": journey.departure_secs, + * "departure_day": self._day_to_str(journey.departure_day), # <<<<<<<<<<<<<< + * + * # Arrival information + */ + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.departure_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_departure_day, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":239 + * + * # Arrival information + * "arrival_time": journey.arrival_secs, # <<<<<<<<<<<<<< + * "arrival_day": self._day_to_str(journey.arrival_day), + * + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.arrival_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_arrival_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":240 + * # Arrival information + * "arrival_time": journey.arrival_secs, + * "arrival_day": self._day_to_str(journey.arrival_day), # <<<<<<<<<<<<<< + * + * # Journey steps + */ + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.arrival_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 240, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_arrival_day, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":243 + * + * # Journey steps + * "steps": [] # <<<<<<<<<<<<<< + * } + * + */ + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_steps, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_journey_dict = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "PyPTRouter.pyx":246 + * } + * + * if not detailed: # <<<<<<<<<<<<<< + * return journey_dict + * + */ + __pyx_t_3 = (!(__pyx_v_detailed != 0)); + if (__pyx_t_3) { + + /* "PyPTRouter.pyx":247 + * + * if not detailed: + * return journey_dict # <<<<<<<<<<<<<< + * + * # Convert each journey step + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_journey_dict); + __pyx_r = __pyx_v_journey_dict; + goto __pyx_L0; + + /* "PyPTRouter.pyx":246 + * } + * + * if not detailed: # <<<<<<<<<<<<<< + * return journey_dict + * + */ + } + + /* "PyPTRouter.pyx":250 + * + * # Convert each journey step + * for i in range(journey.steps.size()): # <<<<<<<<<<<<<< + * step_dict = self._convert_journey_step(journey.steps[i]) + * journey_dict["steps"].append(step_dict) + */ + __pyx_t_4 = __pyx_v_journey.steps.size(); + __pyx_t_5 = __pyx_t_4; + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_i = __pyx_t_6; + + /* "PyPTRouter.pyx":251 + * # Convert each journey step + * for i in range(journey.steps.size()): + * step_dict = self._convert_journey_step(journey.steps[i]) # <<<<<<<<<<<<<< + * journey_dict["steps"].append(step_dict) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_step(__pyx_v_self, (__pyx_v_journey.steps[__pyx_v_i])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_step_dict, __pyx_t_1); + __pyx_t_1 = 0; + + /* "PyPTRouter.pyx":252 + * for i in range(journey.steps.size()): + * step_dict = self._convert_journey_step(journey.steps[i]) + * journey_dict["steps"].append(step_dict) # <<<<<<<<<<<<<< + * + * return journey_dict + */ + __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_journey_dict, __pyx_n_u_steps); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_v_step_dict); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 252, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + + /* "PyPTRouter.pyx":254 + * journey_dict["steps"].append(step_dict) + * + * return journey_dict # <<<<<<<<<<<<<< + * + * cdef str _day_to_str(self, Day day): + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_journey_dict); + __pyx_r = __pyx_v_journey_dict; + goto __pyx_L0; + + /* "PyPTRouter.pyx":213 + * return journey_dict + * + * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< + * """Convert a Journey object to a Python dictionary + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter._convert_journey_to_dict", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_journey_dict); + __Pyx_XDECREF(__pyx_v_step_dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":256 + * return journey_dict + * + * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< + * """Convert Day enum to string""" + * if day == Day.CurrentDay: + */ + +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, __PYX_ENUM_CLASS_DECL Day __pyx_v_day) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("_day_to_str", 1); + + /* "PyPTRouter.pyx":258 + * cdef str _day_to_str(self, Day day): + * """Convert Day enum to string""" + * if day == Day.CurrentDay: # <<<<<<<<<<<<<< + * return "current_day" + * else: + */ + __pyx_t_1 = (__pyx_v_day == Day::CurrentDay); + if (__pyx_t_1) { + + /* "PyPTRouter.pyx":259 + * """Convert Day enum to string""" + * if day == Day.CurrentDay: + * return "current_day" # <<<<<<<<<<<<<< + * else: + * return "next_day" + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_n_u_current_day); + __pyx_r = __pyx_n_u_current_day; + goto __pyx_L0; + + /* "PyPTRouter.pyx":258 + * cdef str _day_to_str(self, Day day): + * """Convert Day enum to string""" + * if day == Day.CurrentDay: # <<<<<<<<<<<<<< + * return "current_day" + * else: + */ + } + + /* "PyPTRouter.pyx":261 + * return "current_day" + * else: + * return "next_day" # <<<<<<<<<<<<<< + * + * cdef _convert_journey_step(self, JourneyStep step): + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_n_u_next_day); + __pyx_r = __pyx_n_u_next_day; + goto __pyx_L0; + } + + /* "PyPTRouter.pyx":256 + * return journey_dict + * + * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< + * """Convert Day enum to string""" + * if day == Day.CurrentDay: + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "PyPTRouter.pyx":263 + * return "next_day" + * + * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< + * """Convert a JourneyStep to Python dictionary""" + * + */ + +static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct JourneyStep __pyx_v_step) { + std::string __pyx_v_stop_id_str; + PyObject *__pyx_v_step_dict = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + std::string __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + __Pyx_FakeReference __pyx_t_5; + __Pyx_FakeReference __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_convert_journey_step", 1); + + /* "PyPTRouter.pyx":266 + * """Convert a JourneyStep to Python dictionary""" + * + * cdef string stop_id_str = string(b"stop_id") # <<<<<<<<<<<<<< + * + * step_dict = { + */ + try { + __pyx_t_1 = std::string(((char const *)"stop_id")); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 266, __pyx_L1_error) + } + __pyx_v_stop_id_str = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_1); + + /* "PyPTRouter.pyx":270 + * step_dict = { + * # Basic information + * "duration": step.duration, # <<<<<<<<<<<<<< + * + * # Time information + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.duration); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_duration, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":273 + * + * # Time information + * "departure_time": step.departure_secs, # <<<<<<<<<<<<<< + * "arrival_time": step.arrival_secs, + * "day": self._day_to_str(step.day), + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.departure_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":274 + * # Time information + * "departure_time": step.departure_secs, + * "arrival_time": step.arrival_secs, # <<<<<<<<<<<<<< + * "day": self._day_to_str(step.day), + * + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.arrival_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 274, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_arrival_time, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":275 + * "departure_time": step.departure_secs, + * "arrival_time": step.arrival_secs, + * "day": self._day_to_str(step.day), # <<<<<<<<<<<<<< + * + * # Stop information + */ + __pyx_t_3 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_step.day); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 275, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_day, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":278 + * + * # Stop information + * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< + * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), + * } + */ + __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.src_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_from_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":279 + * # Stop information + * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), + * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< + * } + * + */ + __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.dest_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 279, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_to_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_step_dict = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":283 + * + * # Handle optional fields + * if step.trip_id.has_value(): # <<<<<<<<<<<<<< + * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') + * else: + */ + __pyx_t_4 = (__pyx_v_step.trip_id.has_value() != 0); + if (__pyx_t_4) { + + /* "PyPTRouter.pyx":284 + * # Handle optional fields + * if step.trip_id.has_value(): + * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') # <<<<<<<<<<<<<< + * else: + * step_dict["trip_id"] = "walking" + */ + try { + __pyx_t_5 = __pyx_v_step.trip_id.value(); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 284, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_5, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 284, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_t_2) < 0))) __PYX_ERR(0, 284, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":283 + * + * # Handle optional fields + * if step.trip_id.has_value(): # <<<<<<<<<<<<<< + * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') + * else: + */ + goto __pyx_L3; + } + + /* "PyPTRouter.pyx":286 + * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') + * else: + * step_dict["trip_id"] = "walking" # <<<<<<<<<<<<<< + * + * if step.agency_name.has_value(): + */ + /*else*/ { + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_n_u_walking) < 0))) __PYX_ERR(0, 286, __pyx_L1_error) + } + __pyx_L3:; + + /* "PyPTRouter.pyx":288 + * step_dict["trip_id"] = "walking" + * + * if step.agency_name.has_value(): # <<<<<<<<<<<<<< + * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') + * else: + */ + __pyx_t_4 = (__pyx_v_step.agency_name.has_value() != 0); + if (__pyx_t_4) { + + /* "PyPTRouter.pyx":289 + * + * if step.agency_name.has_value(): + * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') # <<<<<<<<<<<<<< + * else: + * step_dict["agency_name"] = "Unknown" + */ + try { + __pyx_t_6 = __pyx_v_step.agency_name.value(); + } catch(...) { + __Pyx_CppExn2PyErr(); + __PYX_ERR(0, 289, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_6, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 289, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_t_2) < 0))) __PYX_ERR(0, 289, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":288 + * step_dict["trip_id"] = "walking" + * + * if step.agency_name.has_value(): # <<<<<<<<<<<<<< + * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') + * else: + */ + goto __pyx_L4; + } + + /* "PyPTRouter.pyx":291 + * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') + * else: + * step_dict["agency_name"] = "Unknown" # <<<<<<<<<<<<<< + * + * return step_dict + */ + /*else*/ { + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_n_u_Unknown) < 0))) __PYX_ERR(0, 291, __pyx_L1_error) + } + __pyx_L4:; + + /* "PyPTRouter.pyx":293 + * step_dict["agency_name"] = "Unknown" + * + * return step_dict # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_step_dict); + __pyx_r = __pyx_v_step_dict; + goto __pyx_L0; + + /* "PyPTRouter.pyx":263 + * return "next_day" + * + * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< + * """Convert a JourneyStep to Python dictionary""" + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("PyPTRouter.PyPTRouter._convert_journey_step", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_step_dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__, "PyPTRouter.__reduce_cython__(self)"); +static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_11__reduce_cython__ = {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__}; +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + if (unlikely(__pyx_nargs > 0)) { + __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} + if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 1); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + */ + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__, "PyPTRouter.__setstate_cython__(self, __pyx_state)"); +static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_13__setstate_cython__ = {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__}; +static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__(PyObject *__pyx_v_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[1] = {0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_MACROS + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_state,0}; + if (__pyx_kwds) { + Py_ssize_t kw_args; + switch (__pyx_nargs) { + case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); + switch (__pyx_nargs) { + case 0: + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pyx_state)) != 0)) { + (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); + kw_args--; + } + else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) + } + } else if (unlikely(__pyx_nargs != 1)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); + } + __pyx_v___pyx_state = values[0]; + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v___pyx_state); + + /* function exit code */ + { + Py_ssize_t __pyx_temp; + for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); + } + } + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 1); + + /* "(tree fragment)":4 + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< + */ + __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); + __PYX_ERR(1, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter __pyx_vtable_10PyPTRouter_PyPTRouter; + +static PyObject *__pyx_tp_new_10PyPTRouter_PyPTRouter(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_obj_10PyPTRouter_PyPTRouter *p; + PyObject *o; + #if CYTHON_COMPILING_IN_LIMITED_API + allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); + o = alloc_func(t, 0); + #else + if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + #endif + p = ((struct __pyx_obj_10PyPTRouter_PyPTRouter *)o); + p->__pyx_vtab = __pyx_vtabptr_10PyPTRouter_PyPTRouter; + if (unlikely(__pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_10PyPTRouter_PyPTRouter(PyObject *o) { + #if CYTHON_USE_TP_FINALIZE + if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) { + if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_10PyPTRouter_PyPTRouter) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + } + #endif + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + (*Py_TYPE(o)->tp_free)(o); + #else + { + freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); + if (tp_free) tp_free(o); + } + #endif +} + +static PyMethodDef __pyx_methods_10PyPTRouter_PyPTRouter[] = { + {"construct_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query}, + {"return_pt_journeys_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1}, + {"return_fastest_pt_journey_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1}, + {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__}, + {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__}, + {0, 0, 0, 0} +}; +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_type_10PyPTRouter_PyPTRouter_slots[] = { + {Py_tp_dealloc, (void *)__pyx_tp_dealloc_10PyPTRouter_PyPTRouter}, + {Py_tp_methods, (void *)__pyx_methods_10PyPTRouter_PyPTRouter}, + {Py_tp_new, (void *)__pyx_tp_new_10PyPTRouter_PyPTRouter}, + {0, 0}, +}; +static PyType_Spec __pyx_type_10PyPTRouter_PyPTRouter_spec = { + "PyPTRouter.PyPTRouter", + sizeof(struct __pyx_obj_10PyPTRouter_PyPTRouter), + 0, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, + __pyx_type_10PyPTRouter_PyPTRouter_slots, +}; +#else + +static PyTypeObject __pyx_type_10PyPTRouter_PyPTRouter = { + PyVarObject_HEAD_INIT(0, 0) + "PyPTRouter.""PyPTRouter", /*tp_name*/ + sizeof(struct __pyx_obj_10PyPTRouter_PyPTRouter), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_10PyPTRouter_PyPTRouter, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_10PyPTRouter_PyPTRouter, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + #if !CYTHON_USE_TYPE_SPECS + 0, /*tp_dictoffset*/ + #endif + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_10PyPTRouter_PyPTRouter, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + #if CYTHON_USE_TP_FINALIZE + 0, /*tp_finalize*/ + #else + NULL, /*tp_finalize*/ + #endif + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if __PYX_NEED_TP_PRINT_SLOT == 1 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030C0000 + 0, /*tp_watched*/ + #endif + #if PY_VERSION_HEX >= 0x030d00A4 + 0, /*tp_versions_used*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, /*tp_pypy_flags*/ + #endif +}; +#endif + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif +/* #### Code section: pystring_table ### */ + +static int __Pyx_CreateStringTabAndInitStrings(void) { + __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Expected_string_int_tuple_got, __pyx_k_Expected_string_int_tuple_got, sizeof(__pyx_k_Expected_string_int_tuple_got), 0, 1, 0, 0}, + {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, + {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, + {&__pyx_kp_s_No_value_specified_for_struct_at, __pyx_k_No_value_specified_for_struct_at, sizeof(__pyx_k_No_value_specified_for_struct_at), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_10, __pyx_k_No_value_specified_for_struct_at_10, sizeof(__pyx_k_No_value_specified_for_struct_at_10), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_11, __pyx_k_No_value_specified_for_struct_at_11, sizeof(__pyx_k_No_value_specified_for_struct_at_11), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_12, __pyx_k_No_value_specified_for_struct_at_12, sizeof(__pyx_k_No_value_specified_for_struct_at_12), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_2, __pyx_k_No_value_specified_for_struct_at_2, sizeof(__pyx_k_No_value_specified_for_struct_at_2), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_3, __pyx_k_No_value_specified_for_struct_at_3, sizeof(__pyx_k_No_value_specified_for_struct_at_3), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_4, __pyx_k_No_value_specified_for_struct_at_4, sizeof(__pyx_k_No_value_specified_for_struct_at_4), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_5, __pyx_k_No_value_specified_for_struct_at_5, sizeof(__pyx_k_No_value_specified_for_struct_at_5), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_6, __pyx_k_No_value_specified_for_struct_at_6, sizeof(__pyx_k_No_value_specified_for_struct_at_6), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_7, __pyx_k_No_value_specified_for_struct_at_7, sizeof(__pyx_k_No_value_specified_for_struct_at_7), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_8, __pyx_k_No_value_specified_for_struct_at_8, sizeof(__pyx_k_No_value_specified_for_struct_at_8), 0, 0, 1, 0}, + {&__pyx_kp_s_No_value_specified_for_struct_at_9, __pyx_k_No_value_specified_for_struct_at_9, sizeof(__pyx_k_No_value_specified_for_struct_at_9), 0, 0, 1, 0}, + {&__pyx_n_s_PyPTRouter, __pyx_k_PyPTRouter, sizeof(__pyx_k_PyPTRouter), 0, 0, 1, 1}, + {&__pyx_n_s_PyPTRouter___reduce_cython, __pyx_k_PyPTRouter___reduce_cython, sizeof(__pyx_k_PyPTRouter___reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_PyPTRouter___setstate_cython, __pyx_k_PyPTRouter___setstate_cython, sizeof(__pyx_k_PyPTRouter___setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_PyPTRouter_construct_query, __pyx_k_PyPTRouter_construct_query, sizeof(__pyx_k_PyPTRouter_construct_query), 0, 0, 1, 1}, + {&__pyx_kp_s_PyPTRouter_pyx, __pyx_k_PyPTRouter_pyx, sizeof(__pyx_k_PyPTRouter_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_PyPTRouter_return_fastest_pt_jou, __pyx_k_PyPTRouter_return_fastest_pt_jou, sizeof(__pyx_k_PyPTRouter_return_fastest_pt_jou), 0, 0, 1, 1}, + {&__pyx_n_s_PyPTRouter_return_pt_journeys_1t, __pyx_k_PyPTRouter_return_pt_journeys_1t, sizeof(__pyx_k_PyPTRouter_return_pt_journeys_1t), 0, 0, 1, 1}, + {&__pyx_kp_u_RAPTOR_router_not_initialized_Pl, __pyx_k_RAPTOR_router_not_initialized_Pl, sizeof(__pyx_k_RAPTOR_router_not_initialized_Pl), 0, 1, 0, 0}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_n_u_Unknown, __pyx_k_Unknown, sizeof(__pyx_k_Unknown), 0, 1, 0, 1}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 1}, + {&__pyx_kp_u__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 1, 0, 0}, + {&__pyx_n_s__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 1, 1}, + {&__pyx_n_u_agency_name, __pyx_k_agency_name, sizeof(__pyx_k_agency_name), 0, 1, 0, 1}, + {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1}, + {&__pyx_n_s_arrival_datetime, __pyx_k_arrival_datetime, sizeof(__pyx_k_arrival_datetime), 0, 0, 1, 1}, + {&__pyx_n_u_arrival_day, __pyx_k_arrival_day, sizeof(__pyx_k_arrival_day), 0, 1, 0, 1}, + {&__pyx_n_u_arrival_time, __pyx_k_arrival_time, sizeof(__pyx_k_arrival_time), 0, 1, 0, 1}, + {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_construct_query, __pyx_k_construct_query, sizeof(__pyx_k_construct_query), 0, 0, 1, 1}, + {&__pyx_n_u_current_day, __pyx_k_current_day, sizeof(__pyx_k_current_day), 0, 1, 0, 1}, + {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1}, + {&__pyx_n_s_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 0, 1, 1}, + {&__pyx_n_s_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 0, 1, 1}, + {&__pyx_n_u_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 1, 0, 1}, + {&__pyx_n_u_departure_day, __pyx_k_departure_day, sizeof(__pyx_k_departure_day), 0, 1, 0, 1}, + {&__pyx_n_s_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 0, 1, 1}, + {&__pyx_n_u_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 1, 0, 1}, + {&__pyx_n_s_detailed, __pyx_k_detailed, sizeof(__pyx_k_detailed), 0, 0, 1, 1}, + {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, + {&__pyx_n_u_duration, __pyx_k_duration, sizeof(__pyx_k_duration), 0, 1, 0, 1}, + {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, + {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, + {&__pyx_n_u_from_stop_id, __pyx_k_from_stop_id, sizeof(__pyx_k_from_stop_id), 0, 1, 0, 1}, + {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_n_s_hour, __pyx_k_hour, sizeof(__pyx_k_hour), 0, 0, 1, 1}, + {&__pyx_n_s_hours, __pyx_k_hours, sizeof(__pyx_k_hours), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_inc_src, __pyx_k_inc_src, sizeof(__pyx_k_inc_src), 0, 0, 1, 1}, + {&__pyx_n_s_inc_tgt, __pyx_k_inc_tgt, sizeof(__pyx_k_inc_tgt), 0, 0, 1, 1}, + {&__pyx_n_s_included_sources, __pyx_k_included_sources, sizeof(__pyx_k_included_sources), 0, 0, 1, 1}, + {&__pyx_n_s_included_targets, __pyx_k_included_targets, sizeof(__pyx_k_included_targets), 0, 0, 1, 1}, + {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, + {&__pyx_n_s_input_directory, __pyx_k_input_directory, sizeof(__pyx_k_input_directory), 0, 0, 1, 1}, + {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, + {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, + {&__pyx_n_s_journey, __pyx_k_journey, sizeof(__pyx_k_journey), 0, 0, 1, 1}, + {&__pyx_n_s_journey_dict, __pyx_k_journey_dict, sizeof(__pyx_k_journey_dict), 0, 0, 1, 1}, + {&__pyx_n_s_journey_opt, __pyx_k_journey_opt, sizeof(__pyx_k_journey_opt), 0, 0, 1, 1}, + {&__pyx_n_s_journeys, __pyx_k_journeys, sizeof(__pyx_k_journeys), 0, 0, 1, 1}, + {&__pyx_n_s_journeys_list, __pyx_k_journeys_list, sizeof(__pyx_k_journeys_list), 0, 0, 1, 1}, + {&__pyx_n_s_json, __pyx_k_json, sizeof(__pyx_k_json), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_max_transfers, __pyx_k_max_transfers, sizeof(__pyx_k_max_transfers), 0, 0, 1, 1}, + {&__pyx_n_s_minute, __pyx_k_minute, sizeof(__pyx_k_minute), 0, 0, 1, 1}, + {&__pyx_n_s_minutes, __pyx_k_minutes, sizeof(__pyx_k_minutes), 0, 0, 1, 1}, + {&__pyx_n_s_month, __pyx_k_month, sizeof(__pyx_k_month), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_u_next_day, __pyx_k_next_day, sizeof(__pyx_k_next_day), 0, 1, 0, 1}, + {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, + {&__pyx_n_u_num_transfers, __pyx_k_num_transfers, sizeof(__pyx_k_num_transfers), 0, 1, 0, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, + {&__pyx_n_s_query, __pyx_k_query, sizeof(__pyx_k_query), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_n_s_return_fastest_pt_journey_1to1, __pyx_k_return_fastest_pt_journey_1to1, sizeof(__pyx_k_return_fastest_pt_journey_1to1), 0, 0, 1, 1}, + {&__pyx_n_s_return_pt_journeys_1to1, __pyx_k_return_pt_journeys_1to1, sizeof(__pyx_k_return_pt_journeys_1to1), 0, 0, 1, 1}, + {&__pyx_n_s_second, __pyx_k_second, sizeof(__pyx_k_second), 0, 0, 1, 1}, + {&__pyx_n_s_seconds, __pyx_k_seconds, sizeof(__pyx_k_seconds), 0, 0, 1, 1}, + {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_u_source_transfer_time, __pyx_k_source_transfer_time, sizeof(__pyx_k_source_transfer_time), 0, 1, 0, 1}, + {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, + {&__pyx_n_s_src_vec, __pyx_k_src_vec, sizeof(__pyx_k_src_vec), 0, 0, 1, 1}, + {&__pyx_n_u_steps, __pyx_k_steps, sizeof(__pyx_k_steps), 0, 1, 0, 1}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_tgt_vec, __pyx_k_tgt_vec, sizeof(__pyx_k_tgt_vec), 0, 0, 1, 1}, + {&__pyx_n_u_to_stop_id, __pyx_k_to_stop_id, sizeof(__pyx_k_to_stop_id), 0, 1, 0, 1}, + {&__pyx_n_u_trip_id, __pyx_k_trip_id, sizeof(__pyx_k_trip_id), 0, 1, 0, 1}, + {&__pyx_n_u_trip_time, __pyx_k_trip_time, sizeof(__pyx_k_trip_time), 0, 1, 0, 1}, + {&__pyx_kp_u_utf_8, __pyx_k_utf_8, sizeof(__pyx_k_utf_8), 0, 1, 0, 0}, + {&__pyx_n_u_waiting_time, __pyx_k_waiting_time, sizeof(__pyx_k_waiting_time), 0, 1, 0, 1}, + {&__pyx_n_u_walking, __pyx_k_walking, sizeof(__pyx_k_walking), 0, 1, 0, 1}, + {&__pyx_n_s_weekday, __pyx_k_weekday, sizeof(__pyx_k_weekday), 0, 0, 1, 1}, + {&__pyx_n_s_year, __pyx_k_year, sizeof(__pyx_k_year), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} + }; + return __Pyx_InitStrings(__pyx_string_tab); +} +/* #### Code section: cached_builtins ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 110, __pyx_L1_error) + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 145, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 161, __pyx_L1_error) + __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 68, __pyx_L1_error) + __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(1, 19, __pyx_L1_error) + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 20, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cached_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "FromPyStructUtility":20 + * value = obj['year'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'year'") # <<<<<<<<<<<<<< + * result.year = value + * try: + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "FromPyStructUtility":25 + * value = obj['month'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'month'") # <<<<<<<<<<<<<< + * result.month = value + * try: + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_2); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "FromPyStructUtility":30 + * value = obj['day'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'day'") # <<<<<<<<<<<<<< + * result.day = value + * try: + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_3); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "FromPyStructUtility":35 + * value = obj['weekday'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'weekday'") # <<<<<<<<<<<<<< + * result.weekday = value + * return result + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_4); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "FromPyStructUtility":20 + * value = obj['hours'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'hours'") # <<<<<<<<<<<<<< + * result.hours = value + * try: + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_5); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "FromPyStructUtility":25 + * value = obj['minutes'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'minutes'") # <<<<<<<<<<<<<< + * result.minutes = value + * try: + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_6); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "FromPyStructUtility":30 + * value = obj['seconds'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'seconds'") # <<<<<<<<<<<<<< + * result.seconds = value + * return result + */ + __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_7); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + + /* "FromPyStructUtility":20 + * value = obj['included_sources'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_sources'") # <<<<<<<<<<<<<< + * result.included_sources = value + * try: + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_8); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "FromPyStructUtility":25 + * value = obj['included_targets'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'included_targets'") # <<<<<<<<<<<<<< + * result.included_targets = value + * try: + */ + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_9); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + + /* "FromPyStructUtility":30 + * value = obj['date'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'date'") # <<<<<<<<<<<<<< + * result.date = value + * try: + */ + __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_10); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(1, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + + /* "FromPyStructUtility":35 + * value = obj['departure_time'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'departure_time'") # <<<<<<<<<<<<<< + * result.departure_time = value + * try: + */ + __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_11); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(1, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__11); + __Pyx_GIVEREF(__pyx_tuple__11); + + /* "FromPyStructUtility":40 + * value = obj['max_transfers'] + * except KeyError: + * raise ValueError("No value specified for struct attribute 'max_transfers'") # <<<<<<<<<<<<<< + * result.max_transfers = value + * return result + */ + __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_12); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + + /* "PyPTRouter.pyx":145 + * """ + * if self.raptor_ptr == NULL: + * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< + * + * query = self.construct_query( + */ + __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_RAPTOR_router_not_initialized_Pl); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + + /* "PyPTRouter.pyx":71 + * del self.raptor_ptr + * + * def construct_query( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_tuple__16 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_year, __pyx_n_s_month, __pyx_n_s_day, __pyx_n_s_weekday, __pyx_n_s_hours, __pyx_n_s_minutes, __pyx_n_s_seconds, __pyx_n_s_date, __pyx_n_s_departure_time, __pyx_n_s_query, __pyx_n_s_src_vec, __pyx_n_s_tgt_vec, __pyx_n_s_inc_src, __pyx_n_s_inc_tgt); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__16); + __Pyx_GIVEREF(__pyx_tuple__16); + __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_construct_query, 71, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) __PYX_ERR(0, 71, __pyx_L1_error) + __pyx_tuple__18 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__18); + __Pyx_GIVEREF(__pyx_tuple__18); + + /* "PyPTRouter.pyx":121 + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + * + * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_tuple__19 = PyTuple_Pack(11, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journeys, __pyx_n_s_journeys_list, __pyx_n_s_i, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__19); + __Pyx_GIVEREF(__pyx_tuple__19); + __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_pt_journeys_1to1, 121, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 121, __pyx_L1_error) + __pyx_tuple__21 = PyTuple_Pack(2, __pyx_int_neg_1, Py_False); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__21); + __Pyx_GIVEREF(__pyx_tuple__21); + + /* "PyPTRouter.pyx":167 + * return journeys_list + * + * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_tuple__22 = PyTuple_Pack(10, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journey_opt, __pyx_n_s_journey, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__22); + __Pyx_GIVEREF(__pyx_tuple__22); + __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_fastest_pt_journey_1to1, 167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 167, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_tuple__24 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__24); + __Pyx_GIVEREF(__pyx_tuple__24); + __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) __PYX_ERR(1, 1, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + */ + __pyx_tuple__26 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__26); + __Pyx_GIVEREF(__pyx_tuple__26); + __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) __PYX_ERR(1, 3, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { + if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_globals ### */ + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + return 0; +} +/* #### Code section: init_module ### */ + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __pyx_vtabptr_10PyPTRouter_PyPTRouter = &__pyx_vtable_10PyPTRouter_PyPTRouter; + __pyx_vtable_10PyPTRouter_PyPTRouter._convert_journey_to_dict = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct Journey, bool))__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict; + __pyx_vtable_10PyPTRouter_PyPTRouter._day_to_str = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, __PYX_ENUM_CLASS_DECL Day))__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str; + __pyx_vtable_10PyPTRouter_PyPTRouter._convert_journey_step = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct JourneyStep))__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step; + #if CYTHON_USE_TYPE_SPECS + __pyx_ptype_10PyPTRouter_PyPTRouter = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_10PyPTRouter_PyPTRouter_spec, NULL); if (unlikely(!__pyx_ptype_10PyPTRouter_PyPTRouter)) __PYX_ERR(0, 10, __pyx_L1_error) + if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_10PyPTRouter_PyPTRouter_spec, __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #else + __pyx_ptype_10PyPTRouter_PyPTRouter = &__pyx_type_10PyPTRouter_PyPTRouter; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + #endif + #if !CYTHON_USE_TYPE_SPECS + if (__Pyx_PyType_Ready(__pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #endif + #if PY_MAJOR_VERSION < 3 + __pyx_ptype_10PyPTRouter_PyPTRouter->tp_print = 0; + #endif + #if !CYTHON_COMPILING_IN_LIMITED_API + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_10PyPTRouter_PyPTRouter->tp_dictoffset && __pyx_ptype_10PyPTRouter_PyPTRouter->tp_getattro == PyObject_GenericGetAttr)) { + __pyx_ptype_10PyPTRouter_PyPTRouter->tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #endif + if (__Pyx_SetVtable(__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_vtabptr_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_MergeVtables(__pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #endif + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_PyPTRouter, (PyObject *) __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #if !CYTHON_COMPILING_IN_LIMITED_API + if (__Pyx_setup_reduce((PyObject *) __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_PyPTRouter(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_PyPTRouter}, + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "PyPTRouter", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #elif CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstate), /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif +#endif + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initPyPTRouter(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initPyPTRouter(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) +#else +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +#endif +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { +#if CYTHON_COMPILING_IN_LIMITED_API + result = PyModule_AddObject(module, to_name, value); +#else + result = PyDict_SetItemString(moddict, to_name, value); +#endif + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + moddict = module; +#else + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; +#endif + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_PyPTRouter(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'PyPTRouter' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("PyPTRouter", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #elif CYTHON_USE_MODULE_STATE + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + { + int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "PyPTRouter" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #endif + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void)", 0); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_PyPTRouter) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "PyPTRouter")) { + if (unlikely((PyDict_SetItemString(modules, "PyPTRouter", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "PyPTRouter.pyx":7 + * from libcpp.utility cimport pair + * from libcpp.optional cimport optional + * import json # <<<<<<<<<<<<<< + * from datetime import datetime + * + */ + __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_json, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_json, __pyx_t_2) < 0) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":8 + * from libcpp.optional cimport optional + * import json + * from datetime import datetime # <<<<<<<<<<<<<< + * + * cdef class PyPTRouter: + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_datetime); + __Pyx_GIVEREF(__pyx_n_s_datetime); + if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_datetime)) __PYX_ERR(0, 8, __pyx_L1_error); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_datetime, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_datetime); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":71 + * del self.raptor_ptr + * + * def construct_query( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_construct_query, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__17)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__18); + if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_construct_query, __pyx_t_3) < 0) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); + + /* "PyPTRouter.pyx":121 + * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + * + * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_pt_journeys_1t, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__20)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__21); + if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_return_pt_journeys_1to1, __pyx_t_3) < 0) __PYX_ERR(0, 121, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); + + /* "PyPTRouter.pyx":167 + * return journeys_list + * + * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< + * self, + * arrival_datetime, + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_fastest_pt_jou, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__21); + if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_return_fastest_pt_journey_1to1, __pyx_t_3) < 0) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter___reduce_cython, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__25)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_3) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter___setstate_cython, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__27)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_3) < 0) __PYX_ERR(1, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "PyPTRouter.pyx":1 + * # cython: language_level=3 # <<<<<<<<<<<<<< + * from libcpp.string cimport string + * from libcpp.vector cimport vector + */ + __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_3) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + if (__pyx_m) { + if (__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init PyPTRouter", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init PyPTRouter"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* DictGetItem */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + if (unlikely(PyTuple_Check(key))) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) { + PyErr_SetObject(PyExc_KeyError, args); + Py_DECREF(args); + } + } else { + PyErr_SetObject(PyExc_KeyError, key); + } + } + return NULL; + } + Py_INCREF(value); + return value; +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + PyObject *exc_value = exc_info->exc_value; + if (exc_value == NULL || exc_value == Py_None) { + *value = NULL; + *type = NULL; + *tb = NULL; + } else { + *value = exc_value; + Py_INCREF(*value); + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + *tb = PyException_GetTraceback(exc_value); + } + #elif CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); + #endif +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *tmp_value = exc_info->exc_value; + exc_info->exc_value = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); + #else + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); + #endif +} +#endif + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type = NULL, *local_value, *local_tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030C00A6 + local_value = tstate->current_exception; + tstate->current_exception = 0; + if (likely(local_value)) { + local_type = (PyObject*) Py_TYPE(local_value); + Py_INCREF(local_type); + local_tb = PyException_GetTraceback(local_value); + } + #else + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + #endif +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 + if (unlikely(tstate->current_exception)) +#elif CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + #if PY_VERSION_HEX >= 0x030B00a4 + tmp_value = exc_info->exc_value; + exc_info->exc_value = local_value; + tmp_type = NULL; + tmp_tb = NULL; + Py_XDECREF(local_type); + Py_XDECREF(local_tb); + #else + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + #endif + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + __Pyx_PyThreadState_declare + CYTHON_UNUSED_VAR(cause); + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { + #if PY_VERSION_HEX >= 0x030C00A6 + PyException_SetTraceback(value, tb); + #elif CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* TupleAndListFromArray */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + Py_INCREF(__pyx_empty_tuple); + return __pyx_empty_tuple; + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) + { + if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); + PyObject *dict; + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; i= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject *const *kwvalues, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); + while (1) { + Py_XDECREF(key); key = NULL; + Py_XDECREF(value); value = NULL; + if (kwds_is_tuple) { + Py_ssize_t size; +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(kwds); +#else + size = PyTuple_Size(kwds); + if (size < 0) goto bad; +#endif + if (pos >= size) break; +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); + if (!key) goto bad; +#elif CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kwds, pos); +#else + key = PyTuple_GetItem(kwds, pos); + if (!key) goto bad; +#endif + value = kwvalues[pos]; + pos++; + } + else + { + if (!PyDict_Next(kwds, &pos, &key, &value)) break; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + } + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(value); + Py_DECREF(key); +#endif + key = NULL; + value = NULL; + continue; + } +#if !CYTHON_AVOID_BORROWED_REFS + Py_INCREF(key); +#endif + Py_INCREF(value); + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = ( + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key) + ); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; +#if CYTHON_AVOID_BORROWED_REFS + value = NULL; +#endif + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + Py_XDECREF(key); + Py_XDECREF(value); + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + type_name = __Pyx_PyType_GetName(type); + obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { + return NULL; + } + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { + return NULL; + } + #endif + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + #if PY_MAJOR_VERSION < 3 + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + #else + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + #endif + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + #if PY_VERSION_HEX < 0x030800B1 + #if CYTHON_FAST_PYCCALL + if (PyCFunction_Check(func)) { + if (kwargs) { + return _PyCFunction_FastCallDict(func, args, nargs, kwargs); + } else { + return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); + } + } + #if PY_VERSION_HEX >= 0x030700A1 + if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { + return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); + } + #endif + #endif + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); + } + #endif + #endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if PY_VERSION_HEX < 0x03090000 + vectorcallfunc f = _PyVectorcall_Function(func); + #else + vectorcallfunc f = PyVectorcall_Function(func); + #endif + if (f) { + return f(func, args, (size_t)nargs, NULL); + } + #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL + if (__Pyx_CyFunction_CheckExact(func)) { + __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); + if (f) return f(func, args, (size_t)nargs, NULL); + } + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (unlikely(!j)) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; + PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; + if (mm && mm->mp_subscript) { + PyObject *r, *key = PyInt_FromSsize_t(i); + if (unlikely(!key)) return NULL; + r = mm->mp_subscript(o, key); + Py_DECREF(key); + return r; + } + if (likely(sm && sm->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { + Py_ssize_t l = sm->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return sm->sq_item(o, i); + } + } +#else + if (is_list || !PyMapping_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* PyObjectCallOneArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCall2Args */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#elif PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2) +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +#endif +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { +#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2 + PyObject *args[2] = {obj, arg}; + (void) __Pyx_PyObject_GetMethod; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_Call2Args; + return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +#endif +} + +/* append */ +static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { + if (likely(PyList_CheckExact(L))) { + if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; + } else { + PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x); + if (unlikely(!retval)) + return -1; + Py_DECREF(retval); + } + return 0; +} + +/* decode_c_bytes */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( + const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + if (unlikely((start < 0) | (stop < 0))) { + if (start < 0) { + start += length; + if (start < 0) + start = 0; + } + if (stop < 0) + stop += length; + } + if (stop > length) + stop = length; + if (unlikely(stop <= start)) + return __Pyx_NewRef(__pyx_empty_unicode); + length = stop - start; + cstring += start; + if (decode_func) { + return decode_func(cstring, length, errors); + } else { + return PyUnicode_Decode(cstring, length, encoding, errors); + } +} + +/* KeywordStringCheck */ +static int __Pyx_CheckKeywordStrings( + PyObject *kw, + const char* function_name, + int kw_allowed) +{ + PyObject* key = 0; + Py_ssize_t pos = 0; +#if CYTHON_COMPILING_IN_PYPY + if (!kw_allowed && PyDict_Next(kw, &pos, &key, 0)) + goto invalid_keyword; + return 1; +#else + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kw))) { + Py_ssize_t kwsize; +#if CYTHON_ASSUME_SAFE_MACROS + kwsize = PyTuple_GET_SIZE(kw); +#else + kwsize = PyTuple_Size(kw); + if (kwsize < 0) return 0; +#endif + if (unlikely(kwsize == 0)) + return 1; + if (!kw_allowed) { +#if CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kw, 0); +#else + key = PyTuple_GetItem(kw, pos); + if (!key) return 0; +#endif + goto invalid_keyword; + } +#if PY_VERSION_HEX < 0x03090000 + for (pos = 0; pos < kwsize; pos++) { +#if CYTHON_ASSUME_SAFE_MACROS + key = PyTuple_GET_ITEM(kw, pos); +#else + key = PyTuple_GetItem(kw, pos); + if (!key) return 0; +#endif + if (unlikely(!PyUnicode_Check(key))) + goto invalid_keyword_type; + } +#endif + return 1; + } + while (PyDict_Next(kw, &pos, &key, 0)) { + #if PY_MAJOR_VERSION < 3 + if (unlikely(!PyString_Check(key))) + #endif + if (unlikely(!PyUnicode_Check(key))) + goto invalid_keyword_type; + } + if (!kw_allowed && unlikely(key)) + goto invalid_keyword; + return 1; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + return 0; +#endif +invalid_keyword: + #if PY_MAJOR_VERSION < 3 + PyErr_Format(PyExc_TypeError, + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif + return 0; +} + +/* FixUpExtensionType */ +#if CYTHON_USE_TYPE_SPECS +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); +#else + const PyType_Slot *slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { + int changed = 0; +#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) + const +#endif + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { +#if PY_VERSION_HEX < 0x030900b1 + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); +#if PY_VERSION_HEX >= 0x030800b4 + type->tp_vectorcall_offset = memb->offset; +#else + type->tp_print = (printfunc) memb->offset; +#endif + changed = 1; + } +#endif +#else + if ((0)); +#endif +#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { + Py_DECREF(descr); + return -1; + } + Py_DECREF(descr); + changed = 1; + } +#endif + } + memb++; + } + if (changed) + PyType_Modified(type); + } +#endif + return 0; +} +#endif + +/* PyObjectCallNoArg */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* ValidateBasesTuple */ +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS +static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { + Py_ssize_t i, n; +#if CYTHON_ASSUME_SAFE_MACROS + n = PyTuple_GET_SIZE(bases); +#else + n = PyTuple_Size(bases); + if (n < 0) return -1; +#endif + for (i = 1; i < n; i++) + { +#if CYTHON_AVOID_BORROWED_REFS + PyObject *b0 = PySequence_GetItem(bases, i); + if (!b0) return -1; +#elif CYTHON_ASSUME_SAFE_MACROS + PyObject *b0 = PyTuple_GET_ITEM(bases, i); +#else + PyObject *b0 = PyTuple_GetItem(bases, i); + if (!b0) return -1; +#endif + PyTypeObject *b; +#if PY_MAJOR_VERSION < 3 + if (PyClass_Check(b0)) + { + PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", + PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } +#endif + b = (PyTypeObject*) b0; + if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); + __Pyx_DECREF_TypeName(b_name); +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + if (dictoffset == 0) + { + Py_ssize_t b_dictoffset = 0; +#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY + b_dictoffset = b->tp_dictoffset; +#else + PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); + if (!py_b_dictoffset) goto dictoffset_return; + b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); + Py_DECREF(py_b_dictoffset); + if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; +#endif + if (b_dictoffset) { + { + __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); + PyErr_Format(PyExc_TypeError, + "extension type '%.200s' has no __dict__ slot, " + "but base type '" __Pyx_FMT_TYPENAME "' has: " + "either add 'cdef dict __dict__' to the extension type " + "or add '__slots__ = [...]' to the base type", + type_name, b_name); + __Pyx_DECREF_TypeName(b_name); + } +#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) + dictoffset_return: +#endif +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + return -1; + } + } +#if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(b0); +#endif + } + return 0; +} +#endif + +/* PyType_Ready */ +static int __Pyx_PyType_Ready(PyTypeObject *t) { +#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) + (void)__Pyx_PyObject_CallMethod0; +#if CYTHON_USE_TYPE_SPECS + (void)__Pyx_validate_bases_tuple; +#endif + return PyType_Ready(t); +#else + int r; + PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); + if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) + return -1; +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + { + int gc_was_enabled; + #if PY_VERSION_HEX >= 0x030A00b1 + gc_was_enabled = PyGC_Disable(); + (void)__Pyx_PyObject_CallMethod0; + #else + PyObject *ret, *py_status; + PyObject *gc = NULL; + #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) + gc = PyImport_GetModule(__pyx_kp_u_gc); + #endif + if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); + if (unlikely(!gc)) return -1; + py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); + if (unlikely(!py_status)) { + Py_DECREF(gc); + return -1; + } + gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); + Py_DECREF(py_status); + if (gc_was_enabled > 0) { + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); + if (unlikely(!ret)) { + Py_DECREF(gc); + return -1; + } + Py_DECREF(ret); + } else if (unlikely(gc_was_enabled == -1)) { + Py_DECREF(gc); + return -1; + } + #endif + t->tp_flags |= Py_TPFLAGS_HEAPTYPE; +#if PY_VERSION_HEX >= 0x030A0000 + t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; +#endif +#else + (void)__Pyx_PyObject_CallMethod0; +#endif + r = PyType_Ready(t); +#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) + t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + #if PY_VERSION_HEX >= 0x030A00b1 + if (gc_was_enabled) + PyGC_Enable(); + #else + if (gc_was_enabled) { + PyObject *tp, *v, *tb; + PyErr_Fetch(&tp, &v, &tb); + ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); + if (likely(ret || r == -1)) { + Py_XDECREF(ret); + PyErr_Restore(tp, v, tb); + } else { + Py_XDECREF(tp); + Py_XDECREF(v); + Py_XDECREF(tb); + r = -1; + } + } + Py_DECREF(gc); + #endif + } +#endif + return r; +#endif +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, attr_name); +#else + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", + type_name, PyString_AS_STRING(attr_name)); +#endif + __Pyx_DECREF_TypeName(type_name); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PyObject_GenericGetAttr */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); + } + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +} +#endif + +/* SetVTable */ +static int __Pyx_SetVtable(PyTypeObject *type, void *vtable) { + PyObject *ob = PyCapsule_New(vtable, 0, 0); + if (unlikely(!ob)) + goto bad; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(PyObject_SetAttr((PyObject *) type, __pyx_n_s_pyx_vtable, ob) < 0)) +#else + if (unlikely(PyDict_SetItem(type->tp_dict, __pyx_n_s_pyx_vtable, ob) < 0)) +#endif + goto bad; + Py_DECREF(ob); + return 0; +bad: + Py_XDECREF(ob); + return -1; +} + +/* GetVTable */ +static void* __Pyx_GetVtable(PyTypeObject *type) { + void* ptr; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *ob = PyObject_GetAttr((PyObject *)type, __pyx_n_s_pyx_vtable); +#else + PyObject *ob = PyObject_GetItem(type->tp_dict, __pyx_n_s_pyx_vtable); +#endif + if (!ob) + goto bad; + ptr = PyCapsule_GetPointer(ob, 0); + if (!ptr && !PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type"); + Py_DECREF(ob); + return ptr; +bad: + Py_XDECREF(ob); + return NULL; +} + +/* MergeVTables */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_MergeVtables(PyTypeObject *type) { + int i; + void** base_vtables; + __Pyx_TypeName tp_base_name; + __Pyx_TypeName base_name; + void* unknown = (void*)-1; + PyObject* bases = type->tp_bases; + int base_depth = 0; + { + PyTypeObject* base = type->tp_base; + while (base) { + base_depth += 1; + base = base->tp_base; + } + } + base_vtables = (void**) malloc(sizeof(void*) * (size_t)(base_depth + 1)); + base_vtables[0] = unknown; + for (i = 1; i < PyTuple_GET_SIZE(bases); i++) { + void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i))); + if (base_vtable != NULL) { + int j; + PyTypeObject* base = type->tp_base; + for (j = 0; j < base_depth; j++) { + if (base_vtables[j] == unknown) { + base_vtables[j] = __Pyx_GetVtable(base); + base_vtables[j + 1] = unknown; + } + if (base_vtables[j] == base_vtable) { + break; + } else if (base_vtables[j] == NULL) { + goto bad; + } + base = base->tp_base; + } + } + } + PyErr_Clear(); + free(base_vtables); + return 0; +bad: + tp_base_name = __Pyx_PyType_GetName(type->tp_base); + base_name = __Pyx_PyType_GetName((PyTypeObject*)PyTuple_GET_ITEM(bases, i)); + PyErr_Format(PyExc_TypeError, + "multiple bases have vtable conflict: '" __Pyx_FMT_TYPENAME "' and '" __Pyx_FMT_TYPENAME "'", tp_base_name, base_name); + __Pyx_DECREF_TypeName(tp_base_name); + __Pyx_DECREF_TypeName(base_name); + free(base_vtables); + return -1; +} +#endif + +/* SetupReduce */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, __pyx_n_s_name); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; +} +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_getstate = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; + PyObject *getstate = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); +#else + getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); + if (!getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } +#endif + if (getstate) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); +#else + object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); + if (!object_getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } +#endif + if (object_getstate != getstate) { + goto __PYX_GOOD; + } + } +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; + } + } + PyType_Modified((PyTypeObject*)type_obj); + } + } + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) { + __Pyx_TypeName type_obj_name = + __Pyx_PyType_GetName((PyTypeObject*)type_obj); + PyErr_Format(PyExc_RuntimeError, + "Unable to initialize pickling for " __Pyx_FMT_TYPENAME, type_obj_name); + __Pyx_DECREF_TypeName(type_obj_name); + } + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); + Py_XDECREF(object_getstate); + Py_XDECREF(getstate); +#endif + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; +} +#endif + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *empty_list = 0; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (unlikely(!py_import)) + goto bad; + if (!from_list) { + empty_list = PyList_New(0); + if (unlikely(!empty_list)) + goto bad; + from_list = empty_list; + } + #endif + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, 1); + if (unlikely(!module)) { + if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (unlikely(!py_level)) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, __pyx_d, empty_dict, from_list, level); + #endif + } + } +bad: + Py_XDECREF(empty_dict); + Py_XDECREF(empty_list); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + return module; +} + +/* ImportDottedModule */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { + PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; + if (unlikely(PyErr_Occurred())) { + PyErr_Clear(); + } + if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { + partial_name = name; + } else { + slice = PySequence_GetSlice(parts_tuple, 0, count); + if (unlikely(!slice)) + goto bad; + sep = PyUnicode_FromStringAndSize(".", 1); + if (unlikely(!sep)) + goto bad; + partial_name = PyUnicode_Join(sep, slice); + } + PyErr_Format( +#if PY_MAJOR_VERSION < 3 + PyExc_ImportError, + "No module named '%s'", PyString_AS_STRING(partial_name)); +#else +#if PY_VERSION_HEX >= 0x030600B1 + PyExc_ModuleNotFoundError, +#else + PyExc_ImportError, +#endif + "No module named '%U'", partial_name); +#endif +bad: + Py_XDECREF(sep); + Py_XDECREF(slice); + Py_XDECREF(partial_name); + return NULL; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { + PyObject *imported_module; +#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + return NULL; + imported_module = __Pyx_PyDict_GetItemStr(modules, name); + Py_XINCREF(imported_module); +#else + imported_module = PyImport_GetModule(name); +#endif + return imported_module; +} +#endif +#if PY_MAJOR_VERSION >= 3 +static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { + Py_ssize_t i, nparts; + nparts = PyTuple_GET_SIZE(parts_tuple); + for (i=1; i < nparts && module; i++) { + PyObject *part, *submodule; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + part = PyTuple_GET_ITEM(parts_tuple, i); +#else + part = PySequence_ITEM(parts_tuple, i); +#endif + submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(part); +#endif + Py_DECREF(module); + module = submodule; + } + if (unlikely(!module)) { + return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); + } + return module; +} +#endif +static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if PY_MAJOR_VERSION < 3 + PyObject *module, *from_list, *star = __pyx_n_s__14; + CYTHON_UNUSED_VAR(parts_tuple); + from_list = PyList_New(1); + if (unlikely(!from_list)) + return NULL; + Py_INCREF(star); + PyList_SET_ITEM(from_list, 0, star); + module = __Pyx_Import(name, from_list, 0); + Py_DECREF(from_list); + return module; +#else + PyObject *imported_module; + PyObject *module = __Pyx_Import(name, NULL, 0); + if (!parts_tuple || unlikely(!module)) + return module; + imported_module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(imported_module)) { + Py_DECREF(module); + return imported_module; + } + PyErr_Clear(); + return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); +#endif +} +static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 + PyObject *module = __Pyx__ImportDottedModule_Lookup(name); + if (likely(module)) { + PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); + if (likely(spec)) { + PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); + if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { + Py_DECREF(spec); + spec = NULL; + } + Py_XDECREF(unsafe); + } + if (likely(!spec)) { + PyErr_Clear(); + return module; + } + Py_DECREF(spec); + Py_DECREF(module); + } else if (PyErr_Occurred()) { + PyErr_Clear(); + } +#endif + return __Pyx__ImportDottedModule(name, parts_tuple); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__15); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* FetchSharedCythonModule */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType */ +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t basicsize, + Py_ssize_t expected_basicsize) { + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +#if !CYTHON_USE_TYPE_SPECS +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* abi_module; + const char* object_name; + PyTypeObject *cached_type = NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + object_name = strrchr(type->tp_name, '.'); + object_name = object_name ? object_name+1 : type->tp_name; + cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + if (__Pyx_VerifyCachedType( + (PyObject *)cached_type, + object_name, + cached_type->tp_basicsize, + type->tp_basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; +done: + Py_DECREF(abi_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#else +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module, *cached_type = NULL; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) return NULL; + cached_type = PyObject_GetAttrString(abi_module, object_name); + if (cached_type) { + Py_ssize_t basicsize; +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; +#else + basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; +#endif + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + basicsize, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + CYTHON_UNUSED_VAR(module); + cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; +done: + Py_DECREF(abi_module); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} +#endif + +/* PyVectorcallFastCallDict */ +#if CYTHON_METH_FASTCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i, pos; + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (PyDict_Next(kw, &pos, &key, &value)) { + keys_are_strings &= Py_TYPE(key)->tp_flags; + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(kwnames, i, key); + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { + return vc(func, args, nargs, NULL); + } + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) +{ + CYTHON_UNUSED_VAR(closure); + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#elif PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_name, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->func_dict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_tuple; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->defaults_kwdict; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = op->func_annotations; + CYTHON_UNUSED_VAR(context); + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + int is_coroutine; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; +#if PY_VERSION_HEX >= 0x03050000 + if (is_coroutine) { + PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(marker); + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(op->func_is_coroutine)) { + return __Pyx_NewRef(op->func_is_coroutine); + } +ignore: + PyErr_Clear(); + } +#endif + op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); + return __Pyx_NewRef(op->func_is_coroutine); +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if CYTHON_USE_TYPE_SPECS + {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#if CYTHON_METH_FASTCALL +#if CYTHON_BACKPORT_VECTORCALL + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else +#if !CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#endif +#endif +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + CYTHON_UNUSED_VAR(args); +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API +#if PY_VERSION_HEX < 0x030900B1 + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); +#endif + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_is_coroutine); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyObject *py_name = NULL; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_MACROS + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, + "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, size); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); +#endif + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } +#if CYTHON_COMPILING_IN_LIMITED_API + py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); + if (!py_name) return NULL; + PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", + py_name); + Py_DECREF(py_name); +#else + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); +#endif + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_MACROS + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(!argc) < 0) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); +#if PY_MAJOR_VERSION > 2 + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); +#else + PyErr_SetString(PyExc_TypeError, + "unbound method needs an argument"); +#endif + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", + ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + def->ml_name, nargs); + return NULL; + } + return def->ml_meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); +#if CYTHON_BACKPORT_VECTORCALL + Py_ssize_t nargs = (Py_ssize_t)nargsf; +#else + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); +#endif + PyObject *self; + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: + self = ((PyCFunctionObject*)cyfunc)->m_self; + break; + default: + return NULL; + } + return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); +} +#endif +#if CYTHON_USE_TYPE_SPECS +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +#else +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, +#if !CYTHON_METH_FASTCALL + 0, +#elif CYTHON_BACKPORT_VECTORCALL + (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), +#else + offsetof(PyCFunctionObject, vectorcall), +#endif + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_PyMethod_New, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if __PYX_NEED_TP_PRINT_SLOT + 0, +#endif +#if PY_VERSION_HEX >= 0x030C0000 + 0, +#endif +#if PY_VERSION_HEX >= 0x030d00A4 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 + 0, +#endif +}; +#endif +static int __pyx_CyFunction_init(PyObject *module) { +#if CYTHON_USE_TYPE_SPECS + __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); +#else + CYTHON_UNUSED_VAR(module); + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); +#endif + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +#if !CYTHON_COMPILING_IN_LIMITED_API +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} +#endif + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result; + result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + #if __PYX_LIMITED_VERSION_HEX < 0x030780000 + { + PyObject *compiled = NULL, *result = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; + compiled = Py_CompileString( + "out = type(code)(\n" + " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" + " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" + " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" + " code.co_lnotab)\n", "", Py_file_input); + if (!compiled) return NULL; + result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); + Py_DECREF(compiled); + if (!result) PyErr_Print(); + Py_DECREF(result); + result = PyDict_GetItemString(scratch_dict, "out"); + if (result) Py_INCREF(result); + return result; + } + #else + return NULL; + #endif +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + (void) __pyx_cfilenm; + (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + py_funcname = PyUnicode_FromString(funcname); + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +static PyObject* __pyx_convert__to_py_struct__Date(struct Date s) { + PyObject* res; + PyObject* member; + res = __Pyx_PyDict_NewPresized(4); if (unlikely(!res)) return NULL; + member = __Pyx_PyInt_From_int(s.year); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_year, member) < 0)) goto bad; + Py_DECREF(member); + member = __Pyx_PyInt_From_int(s.month); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_month, member) < 0)) goto bad; + Py_DECREF(member); + member = __Pyx_PyInt_From_int(s.day); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_day, member) < 0)) goto bad; + Py_DECREF(member); + member = __Pyx_PyInt_From_int(s.weekday); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_weekday, member) < 0)) goto bad; + Py_DECREF(member); + return res; + bad: + Py_XDECREF(member); + Py_DECREF(res); + return NULL; +} +static PyObject* __pyx_convert__to_py_struct__Time(struct Time s) { + PyObject* res; + PyObject* member; + res = __Pyx_PyDict_NewPresized(3); if (unlikely(!res)) return NULL; + member = __Pyx_PyInt_From_int(s.hours); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_hours, member) < 0)) goto bad; + Py_DECREF(member); + member = __Pyx_PyInt_From_int(s.minutes); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_minutes, member) < 0)) goto bad; + Py_DECREF(member); + member = __Pyx_PyInt_From_int(s.seconds); if (unlikely(!member)) goto bad; + if (unlikely(PyDict_SetItem(res, __pyx_n_s_seconds, member) < 0)) goto bad; + Py_DECREF(member); + return res; + bad: + Py_XDECREF(member); + Py_DECREF(res); + return NULL; +} +/* RaiseUnexpectedTypeError */ +static int +__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) +{ + __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, + expected, obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(int) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } +#endif + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL; + PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + arg_tuple = PyTuple_Pack(2, py_bytes, order_str); + if (!arg_tuple) goto limited_bad; + if (!is_unsigned) { + kwds = PyDict_New(); + if (!kwds) goto limited_bad; + if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; + } + result = PyObject_Call(from_bytes, arg_tuple, kwds); + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(arg_tuple); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPy */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(size_t) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (size_t) val; + } + } +#endif + if (unlikely(!PyLong_Check(x))) { + size_t val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (size_t) -1; + val = __Pyx_PyInt_As_size_t(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(size_t, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(size_t) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) >= 2 * PyLong_SHIFT)) { + return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(size_t) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) >= 3 * PyLong_SHIFT)) { + return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(size_t) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) >= 4 * PyLong_SHIFT)) { + return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (size_t) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(size_t) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(size_t, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { + return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(size_t) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { + return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { + return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(size_t) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { + return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT)) { + return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(size_t) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT)) { + return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(size_t) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(size_t) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + size_t val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (size_t) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (size_t) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (size_t) -1; + } else { + stepval = v; + } + v = NULL; + val = (size_t) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(size_t) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((size_t) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(size_t) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((size_t) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((size_t) 1) << (sizeof(size_t) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (size_t) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to size_t"); + return (size_t) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; +} + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API +static __Pyx_TypeName +__Pyx_PyType_GetName(PyTypeObject* tp) +{ + PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_n_s_name); + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { + PyErr_Clear(); + Py_XDECREF(name); + name = __Pyx_NewRef(__pyx_n_s__28); + } + return name; +} +#endif + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if ((sizeof(long) < sizeof(long))) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } +#endif + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i= 0x030B00A4 + return Py_Version & ~0xFFUL; +#else + const char* rt_version = Py_GetVersion(); + unsigned long version = 0; + unsigned long factor = 0x01000000UL; + unsigned int digit = 0; + int i = 0; + while (factor) { + while ('0' <= rt_version[i] && rt_version[i] <= '9') { + digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); + ++i; + } + version += factor * digit; + if (rt_version[i] != '.') + break; + digit = 0; + factor >>= 8; + ++i; + } + return version; +#endif +} +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* InitStrings */ +#if PY_MAJOR_VERSION >= 3 +static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { + if (t.is_unicode | t.is_str) { + if (t.intern) { + *str = PyUnicode_InternFromString(t.s); + } else if (t.encoding) { + *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); + } else { + *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); + } + } else { + *str = PyBytes_FromStringAndSize(t.s, t.n - 1); + } + if (!*str) + return -1; + if (PyObject_Hash(*str) == -1) + return -1; + return 0; +} +#endif +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION >= 3 + __Pyx_InitString(*t, t->p); + #else + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + #endif + ++t; + } + return 0; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", + type_name, type_name, result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd b/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd new file mode 100644 index 00000000..a9a5fec8 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd @@ -0,0 +1,121 @@ +# cython: language_level=3 +from libcpp.string cimport string +from libcpp.vector cimport vector +from libcpp.unordered_map cimport unordered_map +from libcpp.utility cimport pair +from libcpp.optional cimport optional +from libcpp cimport bool + +cdef extern from "DateTime.h": + cdef enum class Day: + CurrentDay + NextDay + + cdef struct Date: + int year + int month + int day + int weekday + + cdef struct Time: + int hours + int minutes + int seconds + +cdef extern from "NetworkObjects/DataStructures.h": + cdef struct pair_hash: + pass + + cdef struct nested_pair_hash: + pass + + cdef struct Query: + vector[pair[string, int]] included_sources + vector[pair[string, int]] included_targets + Date date + Time departure_time + int max_transfers + + cdef struct StopInfo: + optional[int] arrival_seconds + optional[string] parent_trip_id + optional[string] parent_stop_id + optional[Day] day + + cdef struct JourneyStep: + optional[string] trip_id + optional[string] agency_name + Stop* src_stop + Stop* dest_stop + int departure_secs + Day day + int duration + int arrival_secs + + cdef struct Journey: + vector[JourneyStep] steps + int departure_secs + Day departure_day + int arrival_secs + Day arrival_day + int duration + int source_transfer_time + int waiting_time + int trip_time + int num_transfers + +cdef extern from "NetworkObjects/GTFSObjects/GTFSObject.h": + cdef cppclass GTFSObject: + void setField(const string& field, const string& value) + string getField(const string& field) const + const unordered_map[string, string]& getFields() const + bool hasField(const string& field) const + +cdef extern from "NetworkObjects/GTFSObjects/Stop.h": + cdef cppclass Stop(GTFSObject): + void addRouteKey(const pair[string, string]& route_key) + void addFootpath(const string& target_id, int duration) + const unordered_map[string, int]& getFootpaths() const + int getFootpathTime(const string& target_id) const + bool hasFootpath(const string& target_id) const + +cdef extern from "NetworkObjects/GTFSObjects/Agency.h": + cdef cppclass Agency(GTFSObject): + pass + +cdef extern from "NetworkObjects/GTFSObjects/Service.h": + cdef cppclass Service(GTFSObject): + pass + +cdef extern from "NetworkObjects/GTFSObjects/Route.h": + cdef cppclass Route(GTFSObject): + pass + +cdef extern from "NetworkObjects/GTFSObjects/Trip.h": + cdef cppclass Trip(GTFSObject): + pass + +cdef extern from "Parser.h": + cdef cppclass Parser: + Parser(string directory) + unordered_map[string, Agency] getAgencies() + unordered_map[string, Service] getServices() + unordered_map[string, Stop] getStops() + unordered_map[pair[string, string], Route, pair_hash] getRoutes() + unordered_map[string, Trip] getTrips() + +cdef extern from "Raptor.h": + cdef cppclass Raptor: + Raptor() + Raptor(const unordered_map[string, Agency]& agencies_, + const unordered_map[string, Service]& services_, + const unordered_map[string, Stop]& stops, + const unordered_map[pair[string, string], Route, pair_hash]& routes, + const unordered_map[string, Trip]& trips) + void setQuery(const Query& query) + vector[Journey] findJourneys() + optional[Journey] findOptimalJourney() + @staticmethod + void showJourney(const Journey& journey) + const unordered_map[string, Stop]& getStops() const + bool isValidJourney(Journey journey) const \ No newline at end of file diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx b/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx new file mode 100644 index 00000000..d8ea267d --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx @@ -0,0 +1,293 @@ +# cython: language_level=3 +from libcpp.string cimport string +from libcpp.vector cimport vector +from libcpp.unordered_map cimport unordered_map +from libcpp.utility cimport pair +from libcpp.optional cimport optional +import json +from datetime import datetime + +cdef class PyPTRouter: + cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping + + def __cinit__(self, str input_directory): + """Initialize the RAPTOR router + + This is a Cython-specific constructor that is called first during object creation. + It initializes the C++ RAPTOR router by loading and processing input data. + + Args: + input_directory (str): Directory path containing GTFS data. + The directory should contain necessary GTFS files + (e.g., stops.txt, routes.txt, etc.) + + Notes: + - This method is automatically called during object creation + - If raptor_ptr already exists, it will be deleted before creating a new instance + - The input path will be converted to UTF-8 encoded C++ string + """ + # Convert Python string to C++ string + cdef string cpp_directory = input_directory.encode('utf-8') + + # Initialize data containers for GTFS data + cdef unordered_map[string, Agency] agencies + cdef unordered_map[string, Service] services + cdef unordered_map[string, Trip] trips + cdef unordered_map[pair[string, string], Route, pair_hash] routes + cdef unordered_map[string, Stop] stops + + # Process directory + cdef Parser* parser = new Parser(cpp_directory) + + agencies = parser.getAgencies() + services = parser.getServices() + trips = parser.getTrips() + routes = parser.getRoutes() + stops = parser.getStops() + + del parser + + # Clean up existing instance if any + if self.raptor_ptr != NULL: + del self.raptor_ptr + + # Create new RAPTOR instance with data + self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) + + def __dealloc__(self): + """Deallocate the RAPTOR router + + This is a Cython-specific destructor that is called when the object is garbage collected. + It ensures proper cleanup of C++ resources to prevent memory leaks. + + Notes: + - Automatically called during garbage collection + - Safely deletes the C++ Raptor object if it exists + - Sets raptor_ptr to NULL after deletion is handled by C++ + """ + if self.raptor_ptr != NULL: + del self.raptor_ptr + + def construct_query( + self, + arrival_datetime, + list included_sources, list included_targets, int max_transfers=-1, + ): + """Construct query information. + + Args: + arrival_datetime (datetime): Arrival datetime at the source station + included_sources (list): List of source stop IDs and their station stop transfer times + included_targets (list): List of target stop IDs and their station stop transfer times + max_transfers (int): Maximum number of transfers allowed + + Returns: + query (Query) + """ + # Calculate day of week using Python's datetime + cdef int year = arrival_datetime.year + cdef int month = arrival_datetime.month + cdef int day = arrival_datetime.day + cdef int weekday = arrival_datetime.weekday() + cdef int hours = arrival_datetime.hour + cdef int minutes = arrival_datetime.minute + cdef int seconds = arrival_datetime.second + + # Create date, time objects for C++ + cdef Date date = Date(year, month, day, weekday) + cdef Time departure_time = Time(hours, minutes, seconds) + + cdef Query query + + cdef vector[pair[string, int]] src_vec + cdef vector[pair[string, int]] tgt_vec + + src_vec = vector[pair[string, int]]() + for inc_src in included_sources: + if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): + src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) + else: + raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") + + tgt_vec = vector[pair[string, int]]() + for inc_tgt in included_targets: + if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): + tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) + else: + raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") + + return Query(src_vec, tgt_vec, date, departure_time, max_transfers) + + def return_pt_journeys_1to1( + self, + arrival_datetime, + list included_sources, list included_targets, int max_transfers=-1, + bool detailed=False, + ): + """Find the best public transport journey from source to target + + This method queries the RAPTOR router to find the optimal journey between two stops + at a specified departure time. + + Args: + arrival_datetime (datetime): Arrival datetime at the source station + included_sources (list): List of source stop IDs and their station stop transfer times + included_targets (list): List of target stop IDs and their station stop transfer times + max_transfers (int): Maximum number of transfers allowed (-1 for unlimited) + detailed (bool): Whether to return the detailed journey plan. + + Returns: + dict: A dictionary containing journey details, or None if no journey is found. + The dictionary includes: + - duration: Total journey duration in seconds + """ + if self.raptor_ptr == NULL: + raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + + query = self.construct_query( + arrival_datetime, included_sources, included_targets, max_transfers, + ) + + # Set query and find journeys + self.raptor_ptr.setQuery(query) + cdef vector[Journey] journeys = self.raptor_ptr.findJourneys() + + # Check if any journeys were found + if journeys.size() == 0: + return None + + # Convert all journeys to Python list of dictionaries + journeys_list = [] + for i in range(journeys.size()): + journey_dict = self._convert_journey_to_dict(journeys[i], detailed) + journeys_list.append(journey_dict) + + return journeys_list + + def return_fastest_pt_journey_1to1( + self, + arrival_datetime, + list included_sources, list included_targets, int max_transfers=-1, + bool detailed=False, + ): + """Find the fastest public transport journey from source to target + + This method queries the RAPTOR router to find the optimal journey between two stops + at a specified departure time. + + Args: + arrival_datetime (datetime): Arrival datetime at the source station + included_sources (list): List of source stop IDs and their station stop transfer times + included_targets (list): List of target stop IDs and their station stop transfer times + max_transfers (int): Maximum number of transfers allowed (-1 for unlimited) + detailed (bool): Whether to return the detailed journey plan. + + Returns: + dict: A dictionary containing journey details, or None if no journey is found. + The dictionary includes: + - duration: Total journey duration in seconds + """ + if self.raptor_ptr == NULL: + raise RuntimeError("RAPTOR router not initialized. Please initialize first.") + + query = self.construct_query( + arrival_datetime, included_sources, included_targets, max_transfers, + ) + + # Set query and find journeys + self.raptor_ptr.setQuery(query) + cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() + + # Check if journey was found + if not journey_opt.has_value(): + return None + + # Get the actual journey from optional + cdef Journey journey = journey_opt.value() + + # Convert journey to Python dictionary + journey_dict = self._convert_journey_to_dict(journey, detailed) + + return journey_dict + + cdef _convert_journey_to_dict(self, Journey journey, bool detailed): + """Convert a Journey object to a Python dictionary + + This method takes a C++ Journey object and converts it to a Python dictionary + with all the relevant journey information. + + Args: + journey (Journey): The C++ Journey object to convert + detailed (bool): Whether to include the detailed journey plan + + Returns: + dict: A dictionary containing journey details + """ + journey_dict = { + # Overall journey information + "duration": journey.duration, + "source_transfer_time": journey.source_transfer_time, + "waiting_time": journey.waiting_time, + "trip_time": journey.trip_time, + "num_transfers": journey.num_transfers, + + # Departure information + "departure_time": journey.departure_secs, + "departure_day": self._day_to_str(journey.departure_day), + + # Arrival information + "arrival_time": journey.arrival_secs, + "arrival_day": self._day_to_str(journey.arrival_day), + + # Journey steps + "steps": [] + } + + if not detailed: + return journey_dict + + # Convert each journey step + for i in range(journey.steps.size()): + step_dict = self._convert_journey_step(journey.steps[i]) + journey_dict["steps"].append(step_dict) + + return journey_dict + + cdef str _day_to_str(self, Day day): + """Convert Day enum to string""" + if day == Day.CurrentDay: + return "current_day" + else: + return "next_day" + + cdef _convert_journey_step(self, JourneyStep step): + """Convert a JourneyStep to Python dictionary""" + + cdef string stop_id_str = string(b"stop_id") + + step_dict = { + # Basic information + "duration": step.duration, + + # Time information + "departure_time": step.departure_secs, + "arrival_time": step.arrival_secs, + "day": self._day_to_str(step.day), + + # Stop information + "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), + "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), + } + + # Handle optional fields + if step.trip_id.has_value(): + step_dict["trip_id"] = step.trip_id.value().decode('utf-8') + else: + step_dict["trip_id"] = "walking" + + if step.agency_name.has_value(): + step_dict["agency_name"] = step.agency_name.value().decode('utf-8') + else: + step_dict["agency_name"] = "Unknown" + + return step_dict \ No newline at end of file diff --git a/src/routing/pt/cpp_raptor_router/Raptor.cpp b/src/routing/pt/cpp_raptor_router/Raptor.cpp new file mode 100644 index 00000000..69311fac --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Raptor.cpp @@ -0,0 +1,544 @@ +/** + * @file Raptor.cpp + * @brief Raptor class implementation + * + * This file contains the implementation of the Raptor class, which represents + * the Round-Based Public Transit Routing algorithm, for journey planning. + * + * @author Maria + * @date 10/28/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Raptor.h" + +Raptor::Raptor(const std::unordered_map &agencies, + const std::unordered_map &services, + const std::unordered_map &stops, + const std::unordered_map, Route, pair_hash> &routes, + const std::unordered_map &trips) + : agencies_(agencies), services_(services), stops_(stops), routes_(routes), trips_(trips) { + k = 1; + + // TODO: Remove this part + std::cout << "CPP PT Router: " + << "Raptor initialized with " + << agencies_.size() << " agencies, " + << services_.size() << " services, " + << stops.size() << " stops, " + << routes.size() << " routes, and " + << trips.size() << " trips." << std::endl; +} + +void Raptor::setQuery(const Query &query) { + query_ = query; + + max_transfers_ = (query_.max_transfers < 0) ? std::numeric_limits::max() : query_.max_transfers; + + included_source_ids_.clear(); + included_target_ids_.clear(); + + for (const auto &source : query_.included_sources) { + // Only include stops that are in stops_ + if (stops_.find(source.first) != stops_.end()) { + included_source_ids_.insert(source.first); + } + } + + for (const auto &target : query_.included_targets) { + // Only include stops that are in stops_ + if (stops_.find(target.first) != stops_.end()) { + included_target_ids_.insert(target.first); + } + } + + if (included_source_ids_.empty() || included_target_ids_.empty()) { + throw std::runtime_error("No included source or target stops found"); + } +} + +void Raptor::initializeAlgorithm() { + // Initialize data structures + arrivals_.clear(); + prev_marked_stops.clear(); + marked_stops.clear(); + + // Initialize arrival times for all stops for each k + StopInfo default_info = {std::nullopt, std::nullopt, std::nullopt, std::nullopt}; + arrivals_.reserve(stops_.size()); + for (const auto &[stop_id, stop]: stops_) { + arrivals_.emplace(stop_id, std::vector(max_transfers_+2, default_info)); // +2 for k=0 and k=max_transfers_+1 + } + + // Initialize the round 0 + k = 0; + int departure_time = Utils::timeToSeconds(query_.departure_time); + // Mark all included source stops that are in included_source_ids_ + for (const auto &source : query_.included_sources) { + if (included_source_ids_.find(source.first) == included_source_ids_.end()) continue; + int station_stop_transfer_time = source.second; + int arrival_time = departure_time + station_stop_transfer_time; + markStop(source.first, arrival_time, std::nullopt, std::nullopt); + } + + k++; // k=1 + + // Fill active trips for current and next day + fillActiveTrips(Day::CurrentDay); + fillActiveTrips(Day::NextDay); +} + +void Raptor::markStop( + const std::string &stop_id, + int arrival, + const std::optional &parent_trip_id, + const std::optional &parent_stop_id +) { + Day day = arrival > MIDNIGHT ? Day::NextDay : Day::CurrentDay; + setMinArrivalTime(stop_id, {arrival, parent_trip_id, parent_stop_id, day}); + marked_stops.insert(stop_id); +} + +void Raptor::setMinArrivalTime( + const std::string &stop_id, + StopInfo stop_info + ) { + arrivals_[stop_id][k] = std::move(stop_info); // Only keep one stop info per stop per round +} + +void Raptor::fillActiveTrips(Day day) { + Date target_date = (day == Day::CurrentDay) ? query_.date : Utils::addOneDay(query_.date); + int target_date_int = Utils::dateToInt(target_date); + + // Check if the active_trips_by_day_ map already has the trips for the target date + if (current_date_int_ == target_date_int) { + return; + } + + // Iterates over all trips + for (auto &[trip_id, trip]: trips_) { + // Get service calendar for the trip + const Service &service = services_.at(trip.getField("service_id")); + + if (service.isActive(target_date)) { + trip.setActive(day, true); + } else { + trip.setActive(day, false); + } + } +} + +std::vector Raptor::findJourneys() { + + std::vector journeys; + + initializeAlgorithm(); + + while (true) { + // std::cout << std::endl << "Round " << k << std::endl; + + // Use the minimum arrival time from the previous round as the base for the current round + setUpperBound(); + + prev_marked_stops = marked_stops; + marked_stops.clear(); + + // Accumulate routes serving marked stops from previous round --> routes_stops_set: ((route_id, direction_id), stop_id) + std::unordered_set, std::string>, nested_pair_hash> routes_stops_set = accumulateRoutesServingStops(); + // std::cout << "Accumulated " << routes_stops_set.size() << " routes serving stops." << std::endl; + + // Traverse each route --> find earliest trip on each route --> traverse trip --> update arrival times + traverseRoutes(routes_stops_set); + // std::cout << "Traversed routes. " << marked_stops.size() << " stop(s) improved." << std::endl; + + // Look for footpaths --> find possible walking connections of marked stops --> update arrival times + handleFootpaths(); + // std::cout << "Handled footpaths. " << marked_stops.size() << " stop(s) improved." << std::endl; + + // Stopping criterion: if no stops are marked, then stop + if (marked_stops.empty()) break; + + // Check if any included target stop has been improved + for (const auto& [target_id, station_stop_transfer_time] : query_.included_targets) { + if (marked_stops.find(target_id) != marked_stops.end()) { + Journey journey = reconstructJourney(target_id, station_stop_transfer_time); + + if (isValidJourney(journey)) { + journeys.push_back(journey); + } + } + } + + // Check if the maximum number of transfers is reached + if (k > max_transfers_) { + // std::cout << "Reached maximum number of transfers (" << max_transfers_ << "). Stopping searching." << std::endl; + break; + } + + k++; + } + return journeys; +} + +std::optional Raptor::findOptimalJourney() { + Journey optimal_journey; + int optimal_arrival_secs = std::numeric_limits::max(); + + initializeAlgorithm(); + + while (true) { + // std::cout << std::endl << "Round " << k << std::endl; + + // Use the minimum arrival time from the previous round as the base for the current round + setUpperBound(); + + prev_marked_stops = marked_stops; + marked_stops.clear(); + + // Accumulate routes serving marked stops from previous round --> routes_stops_set: ((route_id, direction_id), stop_id) + std::unordered_set, std::string>, nested_pair_hash> routes_stops_set = accumulateRoutesServingStops(); + // std::cout << "Accumulated " << routes_stops_set.size() << " routes serving stops." << std::endl; + + // Traverse each route --> find earliest trip on each route --> traverse trip --> update arrival times + traverseRoutes(routes_stops_set); + // std::cout << "Traversed routes. " << marked_stops.size() << " stop(s) improved." << std::endl; + + // Look for footpaths --> find possible walking connections of marked stops --> update arrival times + handleFootpaths(); + // std::cout << "Handled footpaths. " << marked_stops.size() << " stop(s) improved." << std::endl; + + // Stopping criterion: if no stops are marked, then stop + if (marked_stops.empty()) break; + + for (const auto& [target_id, station_stop_transfer_time] : query_.included_targets) { + if (marked_stops.find(target_id) != marked_stops.end()) { + int arrival_secs = arrivals_[target_id][k].arrival_seconds.value(); + if (arrival_secs < optimal_arrival_secs) { + Journey possible_journey = reconstructJourney(target_id, station_stop_transfer_time); + if (isValidJourney(possible_journey)) { + optimal_arrival_secs = arrival_secs; + optimal_journey = possible_journey; + } + } + } + } + + // Check if the maximum number of transfers is reached + if (k > max_transfers_) { + // std::cout << "Reached maximum number of transfers (" << max_transfers_ << "). Stopping searching." << std::endl; + break; + } + + k++; + } + return optimal_journey; +} + +void Raptor::setUpperBound() { + for (const auto &[stop_id, stop]: stops_) + setMinArrivalTime(stop_id, arrivals_[stop_id][k - 1]); +} + +std::unordered_set, std::string>, nested_pair_hash> +Raptor::accumulateRoutesServingStops() { + std::unordered_set, std::string>, nested_pair_hash> routes_stops_set; + + // For each previously marked stop p + for (const auto &marked_stop_id: prev_marked_stops) { + // If the stop is one of the included target stops, skip it + if (included_target_ids_.find(marked_stop_id) != included_target_ids_.end()) continue; + + // For each route r serving p: Route key: (route_id, direction_id) + for (const auto &route_key: stops_[marked_stop_id].getRouteKeys()) { + routes_stops_set.insert({route_key, marked_stop_id}); + } + } + return routes_stops_set; +} + +void Raptor::traverseRoutes( + std::unordered_set, std::string>, nested_pair_hash> routes_stops_set +) { + while (!routes_stops_set.empty()) { + auto route_stop = routes_stops_set.begin(); + const auto &[route_key, p_stop_id] = *route_stop; + + try { + auto et = findEarliestTrip(p_stop_id, route_key); + + if (et.has_value()) { + try { + std::string et_id = et.value().first; + Day et_day = et.value().second; + traverseTrip(et_id, et_day, p_stop_id); + } catch (const std::exception& e) { + std::cerr << "Exception while processing trip: " << e.what() << std::endl; + } + } + } catch (const std::exception& e) { + std::cerr << "Exception in findEarliestTrip for stop " << p_stop_id << " and route " << route_key.first << ": " << e.what() << std::endl; + } + + routes_stops_set.erase(route_stop); + } +} + +std::optional> Raptor::findEarliestTrip( + const std::string &p_stop_id, + const std::pair &route_key +) { + // Get all trips of the route + const auto& route = routes_.at(route_key); + const auto& trips = route.getTripsIds(); + + // Get earliest trip on current day + for (const auto& trip_id: trips) { + if (trips_[trip_id].isActive(Day::CurrentDay)) { + // Get departure time of the trip at p_stop_id + const auto& stop_time_record = trips_[trip_id].getStopTimeRecord(p_stop_id); + if (!stop_time_record) continue; + const int& departure_seconds = stop_time_record->departure_seconds; + if (isValidTrip(p_stop_id, departure_seconds)) + return std::make_pair(trip_id, Day::CurrentDay); + } + } + + // Get earliest trip on next day + for (const auto& trip_id: trips) { + if (trips_[trip_id].isActive(Day::NextDay)) { + // Get departure time of the trip at p_stop_id + const auto& stop_time_record = trips_[trip_id].getStopTimeRecord(p_stop_id); + if (!stop_time_record) continue; + const int& departure_seconds = stop_time_record->departure_seconds + MIDNIGHT; + if (isValidTrip(p_stop_id, departure_seconds)) + return std::make_pair(trip_id, Day::NextDay); + } + } + + return std::nullopt; +} + +bool Raptor::isValidTrip( + const std::string &p_stop_id, + const int &departure_seconds +) { + std::optional stop_prev_arrival_seconds = arrivals_[p_stop_id][k - 1].arrival_seconds; + + if (earlier(departure_seconds, stop_prev_arrival_seconds)) return false; + + // Check if the target stop's arrival time is earlier than the departure time + for (const auto &target_id : included_target_ids_) { + std::optional target_arrival_seconds = arrivals_[target_id][k].arrival_seconds; + if (earlier(departure_seconds, target_arrival_seconds)) + return true; + } + + return false; +} + +void Raptor::traverseTrip( + const std::string &et_id, + const Day &et_day, + const std::string &p_stop_id +) { + Trip et = trips_[et_id]; + + // Find all stop time records of the trip after p_stop_id + const auto& stop_time_records = et.getStopTimeRecordsAfter(p_stop_id); + + // Traverse remaining stops on the trip to update arrival times + for (const auto& stop_time_record: stop_time_records) { + const auto& next_stop_arrival_seconds = stop_time_record.arrival_seconds; + + // Access arrival seconds at next_stop_id for trip et_id, according to the day + int arr_secs = et_day == Day::CurrentDay ? next_stop_arrival_seconds + : next_stop_arrival_seconds + MIDNIGHT; + + // If arrival time can be improved, update Tk(pj) using et + if (improvesArrivalTime(arr_secs, stop_time_record.stop_id)) + markStop(stop_time_record.stop_id, arr_secs, et_id, p_stop_id); + } +} + +bool Raptor::earlier( + int secondsA, + std::optional secondsB +) { + if (!secondsB.has_value()) return true; // if still not set, then any value is better + return secondsA < secondsB.value(); +} + +bool Raptor::improvesArrivalTime( + int arrival, + const std::string &dest_id +) { + // Check if the arrival time at the destination stop can be improved + if (!earlier(arrival, arrivals_[dest_id][k].arrival_seconds)) + return false; + + // Check if the arrival time at any included target stop can be improved + for (const auto &target_id : included_target_ids_) { + if (earlier(arrival, arrivals_[target_id][k].arrival_seconds)) + return true; + } + // If no improvement was found for any target, return false + return false; +} + +void Raptor::handleFootpaths() { + // Copy the marked stops + auto current_marked_stops = marked_stops; + + // For each stop p that is marked by methods traverseTrip() + while (!current_marked_stops.empty()) { + auto it = current_marked_stops.begin(); + std::string stop_id = *it; + current_marked_stops.erase(it); + + try { + // If parent step in the previous round is a footpath, skip it to avoid chaining footpaths + if (isFootpath(arrivals_[stop_id][k - 1])) continue; + + // If parent step in the current round is from a footpath, skip it to avoid chaining footpaths + if (isFootpath(arrivals_[stop_id][k])) continue; + + // If the stop is one of the included target stops, skip it + if (included_target_ids_.find(stop_id) != included_target_ids_.end()) continue; + + // Get the arrival time at the marked stop in this round + int p_arrival = arrivals_[stop_id][k].arrival_seconds.value(); + + // For each footpath (p, p') + for (const auto &[dest_id, duration]: stops_[stop_id].getFootpaths()) { + int new_arrival = p_arrival + duration; + if (improvesArrivalTime(new_arrival, dest_id)) { + markStop(dest_id, new_arrival, std::nullopt, stop_id); + } + } // end each footpath (p, p') + } catch (const std::exception& e) { + std::cerr << "Exception in handleFootpaths for stop " << stop_id << ": " << e.what() << std::endl; + } + } // end each marked stop p +} + +bool Raptor::isFootpath(const StopInfo &stop_info) { + return stop_info.parent_stop_id.has_value() && !stop_info.parent_trip_id.has_value(); +} + +Journey Raptor::reconstructJourney( + const std::string &target_id, + const int station_stop_transfer_time + ) { + Journey journey; + std::string current_stop_id = target_id; + + try { + while (true) { + const std::optional parent_trip_id_opt = arrivals_[current_stop_id][k].parent_trip_id; + // TODO: add agency info into journey step + const std::optional parent_agency_name_opt = std::nullopt; + + const std::optional parent_stop_id_opt = arrivals_[current_stop_id][k].parent_stop_id; + + if (!parent_stop_id_opt.has_value()) break; // No parent stop means it is a source stop + const std::string &parent_stop_id = parent_stop_id_opt.value(); + + int departure_seconds, duration, arrival_seconds; + if (!parent_trip_id_opt.has_value()) { // Walking leg + arrival_seconds = arrivals_[current_stop_id][k].arrival_seconds.value(); + + const auto& footpaths = stops_[parent_stop_id].getFootpaths(); + duration = footpaths.at(current_stop_id); + departure_seconds = arrival_seconds - duration; + } else { // PT leg + const std::string &parent_trip_id = parent_trip_id_opt.value(); + + std::string route_id = trips_[parent_trip_id].getField("route_id"); + + bool found_route = false; + for (const auto &[key, route]: routes_) { + if (key.first == route_id) { + found_route = true; + break; + } + } + + if (!found_route) { + break; + } + + // Get departure time of the trip at parent_stop_id + const auto& stop_time_record = trips_[parent_trip_id].getStopTimeRecord(parent_stop_id); + departure_seconds = stop_time_record->departure_seconds; + + arrival_seconds = arrivals_[current_stop_id][k].arrival_seconds.value(); + duration = arrival_seconds - departure_seconds; + } + + Day day = arrival_seconds > MIDNIGHT ? Day::NextDay : Day::CurrentDay; + JourneyStep step = {parent_trip_id_opt, parent_agency_name_opt, &stops_[parent_stop_id], &stops_[current_stop_id], + departure_seconds, day, duration, arrival_seconds}; + + journey.steps.push_back(step); + + // Update to the previous stop boarded + current_stop_id = parent_stop_id; + } + + // Reverse the journey to obtain the correct sequence + std::reverse(journey.steps.begin(), journey.steps.end()); + + // If no steps are found, return an empty journey + if (journey.steps.empty()) { + return journey; + } + + // Set journey departure time and day + journey.departure_secs = Utils::timeToSeconds(query_.departure_time); + journey.departure_day = Day::CurrentDay; + + // Set journey arrival time and day + journey.arrival_secs = journey.steps.back().arrival_secs + station_stop_transfer_time; + journey.arrival_day = journey.steps.back().day; + + // Set journey duration, source transfer time, waiting time, trip time and transfer numbers + journey.duration = journey.arrival_secs - journey.departure_secs; + + // Get station stop transfer time from Query + Stop src_stop = *journey.steps.front().src_stop; + for (const auto &source : query_.included_sources) { + if (source.first == src_stop.getField("stop_id")) { + journey.source_transfer_time = source.second; + break; + } + } + + journey.waiting_time = journey.steps.front().departure_secs - journey.departure_secs - journey.source_transfer_time; + journey.trip_time = journey.duration - journey.waiting_time; + journey.num_transfers = static_cast(journey.steps.size()) - 1; + } catch (const std::exception& e) { + std::cerr << "Exception in reconstructJourney: " << e.what() << std::endl; + } + + return journey; +} + +bool Raptor::isValidJourney(Journey journey) const { + // TODO: add more checks? + + if (journey.steps.empty()) + return false; + + // Get the starting stop ID of the journey + std::string start_stop_id = journey.steps.front().src_stop->getField("stop_id"); + + // Check if the starting stop is one of the included source IDs + if (included_source_ids_.find(start_stop_id) == included_source_ids_.end()) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/routing/pt/cpp_raptor_router/Raptor.h b/src/routing/pt/cpp_raptor_router/Raptor.h new file mode 100644 index 00000000..b26a8e6e --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Raptor.h @@ -0,0 +1,272 @@ +/** + * @file Raptor.h + * @brief Defines the Raptor class for finding Pareto-optimal journeys in a transit network. + * + * This header file declares the Raptor class, which implements the + * Round-Based Public Transit Routing algorithm. + * + * The main method involve finding journeys. + * + * The class also contains several private methods for initializing the algorithm, + * traversing routes, and reconstructing journeys. + * + * @author Maria + * @date 10/28/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_RAPTOR_H +#define RAPTOR_RAPTOR_H + +#include +#include +#include // for setw +#include "Parser.h" +#include "Utils.h" + +/** + * @class Raptor + * @brief Implements the RAPTOR algorithm for finding Pareto-optimal journeys. + * + * The Raptor class provides methods to set a query, find Pareto-optimal journeys, + * and print journey steps. It uses various data structures to store information + * about agencies, calendars, stops, routes, trips, and stop times. + */ +class Raptor { +public: + + /** + * @brief Default constructor for the Raptor class. + * + * Initializes the Raptor object with empty data structures. + */ + Raptor() = default; + + /** + * @brief Parameterized constructor for Raptor. + * + * Initializes the Raptor object with provided agency, calendar, stop, route, trip, and stop time data. + * + * @param[in] agencies_ A map of agency IDs to Agency objects. + * @param[in] services_ A map of service IDs to Service objects. + * @param[in] stops A map of stop IDs to Stop objects. + * @param[in] routes A map of pairs of route IDs and direction IDs to Route objects. + * @param[in] trips A map of trip IDs to Trip objects. + */ + Raptor(const std::unordered_map &agencies_, + const std::unordered_map &services_, + const std::unordered_map &stops, + const std::unordered_map, Route, pair_hash> &routes, + const std::unordered_map &trips); + + /** + * @brief Sets the query for the Raptor algorithm. + * + * @param[in] query The query containing the parameters for journey search. + */ + void setQuery(const Query &query); + + /** + * @brief Finds all Pareto-optimal journeys. + * + * This function uses the RAPTOR algorithm to compute all optimal journeys based on the provided query. + * + * @return A vector of Journey objects representing the Pareto-optimal journeys. + */ + std::vector findJourneys(); + + /** + * @brief Finds the journey with the earliest arrival time. + * + * @return A Journey object representing the journey with the earliest arrival time. + */ + std::optional findOptimalJourney(); + + /** + * @brief Validates if the given journey is valid. + * + * Checks whether the given journey meets the required criteria. + * + * @param[in] journey The Journey object to be validated. + * @return True if the journey is valid, false otherwise. + */ + bool isValidJourney(Journey journey) const; + +private: + + std::unordered_map agencies_; ///< Map of agency IDs to Agency objects. + std::unordered_map services_; ///< Map of service IDs to Service objects. + std::unordered_map stops_; ///< Map of stop IDs to Stop objects. + std::unordered_map, Route, pair_hash> routes_; ///< Map of route keys to Route objects. + std::unordered_map trips_; ///< Map of trip IDs to Trip objects. + int current_date_int_; ///< The current date as an integer. + + Query query_; ///< The current query for the RAPTOR algorithm. + int max_transfers_; ///< The maximum number of transfers allowed in a journey. + std::unordered_set included_source_ids_; ///< Set of included source stop IDs. + std::unordered_set included_target_ids_; ///< Set of included target stop IDs. + std::unordered_map> arrivals_; ///< Map of stop IDs to vectors of StopInfo for each k. + std::unordered_set prev_marked_stops; ///< Set of previously marked stops. + std::unordered_set marked_stops; ///< Set of currently marked stops. + int k{}; ///< The current round of the algorithm. + + /** + * @brief Initializes the algorithm by setting required parameters. + */ + void initializeAlgorithm(); + + // TODO: Remove this function + /** + * @brief Sets the minimum arrival time for a given stop. + * + * @param[in] stop_id The ID of the stop. + * @param[in] stop_info The stop info containing the arrival time, parent trip ID, and parent stop ID. + * + * @deprecated This function is deprecated and will be removed in the future. + */ + void setMinArrivalTime(const std::string &stop_id, StopInfo stop_info); + + /** + * @brief Fills the active trips for a given day. + * + * @param[in] day The day for which trips are being filled. + */ + void fillActiveTrips(Day day); + + /** + * @brief Sets the upper bound for the search, based on previous round. + */ + void setUpperBound(); + + /** + * @brief Accumulates routes serving each stop. + * + * @return A set of routes that serve stops. + */ + std::unordered_set, std::string>, nested_pair_hash> + accumulateRoutesServingStops(); + + /** + * @brief Traverses the routes serving each stop. + * + * @param[in] routes_stops_set The set of routes and stops to be traversed. + */ + void traverseRoutes( + std::unordered_set, std::string>, nested_pair_hash> routes_stops_set + ); + + /** + * @brief Finds the earliest trip for a given stop and route. + * + * @param[in] pi_stop_id The ID of the stop. + * @param[in] route_key The key consisting of route and direction. + * @return An optional pair of trip ID and day if found. + */ + std::optional> findEarliestTrip( + const std::string &pi_stop_id, + const std::pair &route_key + ); + + /** + * @brief Checks if a trip is valid based on the route and stop time. + * + * @param[in] p_stop_id The stop ID. + * @param[in] departure_seconds The departure time in seconds. + * @return True if the trip is valid, false otherwise. + */ + bool isValidTrip( + const std::string &p_stop_id, + const int &departure_seconds + ); + + /** + * @brief Checks if the service is active based on the calendar and date. + * + * @param[in] service The service object containing service dates. + * @param[in] date The date to check. + * @return True if the service is active on the given date, false otherwise. + */ + static bool isServiceActive(const Service &service, const Date &date); + + /** + * @brief Traverses a specific trip. + * + * @param[in] et_id The trip ID. + * @param[in] et_day The day of travel. + * @param[in] p_stop_id The stop ID for the trip. + */ + void traverseTrip( + const std::string &et_id, + const Day &et_day, + const std::string &p_stop_id + ); + + /** + * @brief Compares two arrival times to determine which is earlier. + * + * @param[in] secondsA The first arrival time in seconds. + * @param[in] secondsB The second arrival time in seconds. + * @return True if the first arrival time is earlier, false otherwise. + */ + static bool earlier(int secondsA, std::optional secondsB); + + /** + * @brief Checks if a step improves the arrival time for a destination. + * + * @param[in] arrival The arrival time. + * @param[in] dest_id The destination stop ID. + * @return True if the arrival time improves, false otherwise. + */ + bool improvesArrivalTime(int arrival, const std::string &dest_id); + + /** + * @brief Marks a stop with the arrival time, parent trip, and parent stop. + * + * @param[in] stop_id The ID of the stop. + * @param[in] arrival The arrival time at the stop. + * @param[in] parent_trip_id The ID of the parent trip. + * @param[in] parent_stop_id The ID of the parent stop. + */ + void markStop( + const std::string &stop_id, + int arrival, + const std::optional &parent_trip_id, + const std::optional &parent_stop_id + ); + + // TODO: Remove this function + /** + * @brief Handles footpath logic during traversal. + * + * @deprecated This function is deprecated and will be removed in the future. + */ + void handleFootpaths(); + + // TODO: Remove this function + /** + * @brief Checks if the given stop info represents a footpath. + * + * @param[in] stop_info The stop info to be checked. + * @return True if the stop is a footpath, false otherwise. + * + * @deprecated This function is deprecated and will be removed in the future. + */ + static bool isFootpath(const StopInfo &stop_info); + + /** + * @brief Reconstructs the journey from a given stop. + * + * @param[in] target_id The ID of the target stop for the journey. + * @param[in] station_stop_transfer_time The target station stop transfer time for the journey. + * @return A Journey object representing the reconstructed journey. + */ + Journey reconstructJourney( + const std::string &target_id, + const int station_stop_transfer_time + ); +}; + +#endif //RAPTOR_RAPTOR_H diff --git a/src/routing/pt/cpp_raptor_router/Utils.cpp b/src/routing/pt/cpp_raptor_router/Utils.cpp new file mode 100644 index 00000000..95963ec2 --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Utils.cpp @@ -0,0 +1,130 @@ +/** + * @file Utils.cpp + * @brief Provides utility functions for the RAPTOR application. + * + * This file contains utility functions for the RAPTOR application, + * including functions for calculating distances, durations, and time conversions. + * + * @author Maria + * @date 10/28/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#include "Utils.h" + +std::string Utils::secondsToTime(std::optional seconds) { + + if (!seconds.has_value()) return "INF"; + + int seconds_value = seconds.value(); + + int hours = seconds_value / 3600 % 24; + int minutes = (seconds_value % 3600) / 60; + int secs = seconds_value % 60; + + std::ostringstream oss; + oss << std::setw(2) << std::setfill('0') << hours << ":" + << std::setw(2) << std::setfill('0') << minutes << ":" + << std::setw(2) << std::setfill('0') << secs; + return oss.str(); +} + +int Utils::timeToSeconds(const std::string &timeStr) { + int hours, minutes, seconds; + char colon; + + std::istringstream iss(timeStr); + iss >> hours >> colon >> minutes >> colon >> seconds; + + return hours * 3600 + minutes * 60 + seconds; +} + +int Utils::timeToSeconds(const Time &time) { + return time.hours * 3600 + time.minutes * 60 + time.seconds; +} + +int Utils::dateToInt(const Date &date) { + return date.year * 10000 + date.month * 100 + date.day; +} + +std::vector Utils::split(const std::string &str, char delimiter) { + std::vector tokens; + std::string token; + std::istringstream tokenStream(str); + + while (std::getline(tokenStream, token, delimiter)) { + tokens.push_back(token); + } + + if (str.back() == delimiter) { + tokens.emplace_back(""); // Add empty token if the last character is the delimiter + } + + return tokens; +} + + +std::string Utils::getFirstWord(const std::string &str) { + return str.substr(0, str.find(' ')); +} + +void Utils::clean(std::string &input) { + size_t first = input.find_first_not_of(" \t\n\r"); + size_t last = input.find_last_not_of(" \t\n\r"); + input = (first == std::string::npos) ? "" : input.substr(first, (last - first + 1)); +} + + +bool Utils::isNumber(const std::string &str) { + return !str.empty() && std::all_of(str.begin(), str.end(), [](char c) { return std::isdigit(c); }); +} + +int Utils::daysInMonth(int year, int month) { + static const int daysInMonths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { + return 29; // February in a leap year + } + return daysInMonths[month - 1]; +} + +bool Utils::dateWithinRange(const Date &date, const std::string &start_date, const std::string &end_date) { + // Convert strings YYYYMMDD to Date objects + Date start = {std::stoi(start_date.substr(0, 4)), std::stoi(start_date.substr(4, 2)), + std::stoi(start_date.substr(6, 2))}; + Date end = {std::stoi(end_date.substr(0, 4)), std::stoi(end_date.substr(4, 2)), std::stoi(end_date.substr(6, 2))}; + + // Check if the date is earlier than the start date + if ((date.year < start.year) + || (date.year == start.year && date.month < start.month) + || (date.year == start.year && date.month == start.month && date.day < start.day)) + return false; + + // Check if the date is later than the end date + if ((date.year > end.year) + || (date.year == end.year && date.month > end.month) + || (date.year == end.year && date.month == end.month && date.day > end.day)) + return false; + + return true; +} + +Date Utils::addOneDay(Date date) { + std::tm time_info = {}; + time_info.tm_year = date.year - 1900; + time_info.tm_mon = date.month - 1; + time_info.tm_mday = date.day + 1; // Add one day + int date_weekday = (time_info.tm_wday == 0) ? 6 : time_info.tm_wday - 1; // 0-6, 0 = Monday, 6 = Sunday + + std::mktime(&time_info); // Normalize the date + Date new_date = {time_info.tm_year + 1900, time_info.tm_mon + 1, time_info.tm_mday, date_weekday}; + + return new_date; // Get the next day +} + +std::string Utils::dayToString(Day day) { + return (day == Day::CurrentDay) ? "current" : "next"; +} + diff --git a/src/routing/pt/cpp_raptor_router/Utils.h b/src/routing/pt/cpp_raptor_router/Utils.h new file mode 100644 index 00000000..4dd81c4b --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/Utils.h @@ -0,0 +1,164 @@ +/** + * @file Utils.h + * @brief Provides utility functions for the RAPTOR application. + * + * This header file declares utility functions for the RAPTOR application, + * including functions for calculating distances, durations, and time conversions. + * + * @author Maria + * @date 10/28/2024 + * + * @version fleetpy-1.0 + * @author Chenhao Ding + * @date 12/12/2025 + */ + +#ifndef RAPTOR_UTILS_H +#define RAPTOR_UTILS_H + +#include +#include +#include +#include // for std::pair +#include +#include + +#include "DateTime.h" + +/** + * @class Utils + * @brief A utility class providing various helper functions. + * + * This class contains static utility methods to handle mathematical calculations, time conversions, + * string manipulations, and date operations. These methods are used throughout the RAPTOR project + * to simplify code and provide common functionality. + */ +class Utils { +public: + + /** + * @brief Converts a time in seconds to a string format (HH:MM:SS). + * + * This method converts a given time in seconds into a formatted string representing the time + * in the "HH:MM:SS" format. + * + * @param[in] seconds The time in seconds. + * @return A string representation of the time in "HH:MM:SS" format. + */ + static std::string secondsToTime(std::optional seconds); + + /** + * @brief Converts a time string to the equivalent number of seconds. + * + * This method converts a time string (e.g., "12:30:00") to the total number of seconds. + * + * @param[in] timeStr A time string in the "HH:MM:SS" format. + * @return The total time in seconds. + */ + static int timeToSeconds(const std::string &timeStr); + + /** + * @brief Converts a Time object to the equivalent number of seconds. + * + * This method converts a Time object to the total number of seconds since midnight. + * + * @param[in] time A Time object representing a specific time. + * @return The total time in seconds. + */ + static int timeToSeconds(const Time &time); + + /** + * @brief Converts a date to an integer format (YYYYMMDD). + * + * This method converts a Date object to an integer representation in the format "YYYYMMDD". + * + * @param[in] date The Date object to be converted. + * @return An integer representation of the date in the format "YYYYMMDD". + */ + static int dateToInt(const Date &date); + + /** + * @brief Splits a string into a vector of substrings based on a delimiter. + * + * This method splits a string into parts wherever a specified delimiter appears. + * + * @param[in] str The input string to be split. + * @param[in] delimiter The delimiter character to split the string by. + * @return A vector of substrings split from the input string. + */ + static std::vector split(const std::string &str, char delimiter); + + /** + * @brief Retrieves the first word in a string. + * + * This method extracts and returns the first word from a given string, stopping at the first space. + * + * @param[in] str The input string. + * @return The first word in the string. + */ + static std::string getFirstWord(const std::string &str); + + /** + * @brief Trims leading and trailing whitespace from a string. + * + * This method removes any leading or trailing whitespace from the given string. + * + * @param[in,out] line The line to be cleaned. + */ + static void clean(std::string &input); + + /** + * @brief Checks if a string represents a valid number. + * + * This method checks whether the input string can be interpreted as a valid numerical value. + * + * @param[in] str The input string to be checked. + * @return True if the string is a valid number, false otherwise. + */ + static bool isNumber(const std::string &str); + + /** + * @brief Retrieves the number of days in a specific month of a specific year. + * + * This method returns the number of days in a given month, accounting for leap years if applicable. + * + * @param[in] year The year of interest. + * @param[in] month The month of interest (1-12). + * @return The number of days in the specified month of the specified year. + */ + static int daysInMonth(int year, int month); + + /** + * @brief Checks if a date is within a specified date range. + * + * This method checks whether a given date falls within the specified range of start and end dates. + * + * @param[in] date The date to be checked. + * @param[in] start_date The start of the date range (in string format). + * @param[in] end_date The end of the date range (in string format). + * @return True if the date is within the range, false otherwise. + */ + static bool dateWithinRange(const Date &date, const std::string &start_date, const std::string &end_date); + + /** + * @brief Adds one day to a given date. + * + * This method increments the given date by one day. + * + * @param[in] date The date to which one day should be added. + * @return The resulting date after adding one day. + */ + static Date addOneDay(Date date); + + /** + * @brief Converts a Day enum to a string representation. + * + * This method converts a Day enum (Current or Next) to its string representation. + * + * @param[in] day The Day enum to be converted. + * @return The string representation of the specified day. + */ + static std::string dayToString(Day day); +}; + +#endif //RAPTOR_UTILS_H diff --git a/src/routing/pt/cpp_raptor_router/setup.py b/src/routing/pt/cpp_raptor_router/setup.py new file mode 100644 index 00000000..fe65848a --- /dev/null +++ b/src/routing/pt/cpp_raptor_router/setup.py @@ -0,0 +1,36 @@ +from setuptools import Extension, setup +from Cython.Build import cythonize +import os +import platform + +# Automatically collect all C++ source files +def get_cpp_sources(): + sources = [] + for root, dirs, files in os.walk("."): + for file in files: + if file.endswith(".cpp") and file != "PyPTRouter.cpp": + sources.append(os.path.join(root, file)) + return sources + +# Create a simple extension module +ext = Extension( + name="PyPTRouter", # Module name for import + sources=[ + "PyPTRouter.pyx", # Cython source file + *get_cpp_sources() # All C++ source files + ], + include_dirs=["."], # Directory containing header files + language="c++", + extra_compile_args=["-std=c++20"] if platform.system() != "Windows" else ["/std:c++20"], +) + +# Configure the setup +setup( + ext_modules=cythonize( + ext, + compiler_directives={ + "language_level": 3, + "embedsignature": True, + }, + ), +) \ No newline at end of file From 799e14e9e620da25d51167438607b0b44143a669 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 11 Dec 2025 21:44:18 +0100 Subject: [PATCH 03/31] feat(raptor): introduce RaptorRouterCpp and optimize journey calculation This commit introduces several improvements and fixes to the routing logic: 1. Fix(cpp_raptor_counter): Correct transfer counting bug by ignoring walking legs during calculation. 2. Perf(cpp_raptor_counter): Optimize best journey lookup logic. Now prioritizes arrival time at the target station (parent) rather than the specific stop. 3. Feat: Add `RaptorRouterCpp` class to query the fastest travel plan between two pt stations. 4. Test: Add example GTFS files for the example network to facilitate testing. --- .gitignore | 1 + .../example_gtfs/matched/agency_fp.txt | 2 + .../example_gtfs/matched/calendar_fp.txt | 2 + .../example_gtfs/matched/routes_fp.txt | 3 + .../example_gtfs/matched/stations_fp.txt | 18 + .../example_gtfs/matched/stop_times_fp.txt | 559 ++++++++++++++++++ .../example_gtfs/matched/stops_fp.txt | 39 ++ .../matched/street_station_transfers_fp.txt | 29 + .../example_gtfs/matched/transfers_fp.txt | 55 ++ .../example_gtfs/matched/trips_fp.txt | 94 +++ src/routing/pt/RaptorRouterCpp.py | 178 ++++++ .../NetworkObjects/DataStructures.h | 19 +- .../pt/cpp_raptor_router/PyPTRouter.cpp | 522 ++++++++-------- .../pt/cpp_raptor_router/PyPTRouter.pxd | 11 +- .../pt/cpp_raptor_router/PyPTRouter.pyx | 48 +- src/routing/pt/cpp_raptor_router/Raptor.cpp | 65 +- 16 files changed, 1339 insertions(+), 306 deletions(-) create mode 100644 data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt create mode 100644 data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt create mode 100644 src/routing/pt/RaptorRouterCpp.py diff --git a/.gitignore b/.gitignore index 9234f785..46ec7886 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ data/networks/example_network/ch_graph/* data/networks/example_network/base/*.graph data/pubtrans/* !data/pubtrans/route_193 +!data/pubtrans/example_network data/vehicles/* !data/vehicles/default_vehtype.csv !data/vehicles/low_range_vehtype.csv diff --git a/data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt new file mode 100644 index 00000000..d51e0d61 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt @@ -0,0 +1,2 @@ +agency_id,agency_name +pt,FleetPy PT Operator diff --git a/data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt new file mode 100644 index 00000000..6acf3d08 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt @@ -0,0 +1,2 @@ +service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date +0,1,1,1,1,1,1,1,20000101,20991231 \ No newline at end of file diff --git a/data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt new file mode 100644 index 00000000..f34cea08 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt @@ -0,0 +1,3 @@ +route_id,route_short_name,route_desc +196,196,Bus +U5,U5,U-Bahn \ No newline at end of file diff --git a/data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt new file mode 100644 index 00000000..1c3025c8 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt @@ -0,0 +1,18 @@ +station_id,station_name,station_lat,station_lon,stops_included,station_stop_transfer_times,num_stops_included +s1,Neuperlach Zentrum,48.1011253,11.64650495,"['1-0', '1-1', '1-2', '1-3']","[1, 1, 1, 1]",4 +s2,Jakob-Kaiser-Straße,48.10435272,11.64040539,"['2-0', '2-1']","[1, 1]",2 +s3,Holzwiesenstraße,48.10307497,11.63659653,"['3-0', '3-1']","[1, 1]",2 +s4,Wilhelm-Hoegner-Straße,48.09887559,11.6363989,"['4-0', '4-1']","[1, 1]",2 +s5,Wolframstraße,48.09486185,11.63579703,"['5-0', '5-1']","[1, 1]",2 +s6,Perlach Bahnhof,48.09355387,11.63056883,"['6-0', '6-1']","[1, 1]",2 +s7,Weidener Straße,48.09252186,11.62810745,"['7-0', '7-1']","[1, 1]",2 +s8,Bayerwaldstraße,48.08847762,11.62821525,"['8-0', '8-1']","[1, 1]",2 +s9,Nailastraße,48.08860963,11.63358717,"['9-0', '9-1']","[1, 1]",2 +s10,Rudolf-Zorn-Straße,48.0908898,11.63481786,"['10-0', '10-1']","[1, 1]",2 +s11,Hermann-Pünder-Straße,48.08844762,11.63584194,"['11-0', '11-1']","[1, 1]",2 +s12,Ludwig-Linsert-Straße,48.08627536,11.63483583,"['12-0', '12-1']","[1, 1]",2 +s13,Ludwig-Erhard-Allee,48.0852372,11.63944419,"['13-0', '13-1']","[1, 1]",2 +s14,Curd-Jürgens-Straße,48.08536922,11.64292067,"['14-0', '14-1']","[1, 1]",2 +s15,Neuperlach Süd,48.0893717,11.6446095,"['15-0', '15-1', '15-2', '15-3']","[1, 1, 1, 1]",4 +s16,Therese-Giehse-Allee,48.09477185,11.64277694,"['16-2', '16-3']","[1, 1]",2 +s17,Thomas-Dehler-Straße,48.09735172,11.64436696,"['17-2', '17-3']","[1, 1]",2 \ No newline at end of file diff --git a/data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt new file mode 100644 index 00000000..f03aa90f --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt @@ -0,0 +1,559 @@ +trip_id,arrival_time,departure_time,stop_id,stop_sequence +196-0-0,0:00:00,0:00:00,1-0,1 +196-0-0,0:02:00,0:02:00,2-0,2 +196-0-0,0:03:30,0:03:30,3-0,3 +196-0-0,0:04:30,0:04:30,4-0,4 +196-0-0,0:05:30,0:05:30,5-0,5 +196-0-0,0:06:30,0:06:30,6-0,6 +196-0-0,0:07:30,0:07:30,7-0,7 +196-0-0,0:09:30,0:09:30,8-0,8 +196-0-0,0:10:30,0:10:30,9-0,9 +196-0-0,0:12:30,0:12:30,10-0,10 +196-0-0,0:14:30,0:14:30,11-0,11 +196-0-0,0:15:30,0:15:30,12-0,12 +196-0-0,0:17:00,0:17:00,13-0,13 +196-0-0,0:18:00,0:18:00,14-0,14 +196-0-0,0:20:00,0:20:00,15-0,15 +196-1-0,0:20:00,0:20:00,1-0,1 +196-1-0,0:22:00,0:22:00,2-0,2 +196-1-0,0:23:30,0:23:30,3-0,3 +196-1-0,0:24:30,0:24:30,4-0,4 +196-1-0,0:25:30,0:25:30,5-0,5 +196-1-0,0:26:30,0:26:30,6-0,6 +196-1-0,0:27:30,0:27:30,7-0,7 +196-1-0,0:29:30,0:29:30,8-0,8 +196-1-0,0:30:30,0:30:30,9-0,9 +196-1-0,0:32:30,0:32:30,10-0,10 +196-1-0,0:34:30,0:34:30,11-0,11 +196-1-0,0:35:30,0:35:30,12-0,12 +196-1-0,0:37:00,0:37:00,13-0,13 +196-1-0,0:38:00,0:38:00,14-0,14 +196-1-0,0:40:00,0:40:00,15-0,15 +196-2-0,0:40:00,0:40:00,1-0,1 +196-2-0,0:42:00,0:42:00,2-0,2 +196-2-0,0:43:30,0:43:30,3-0,3 +196-2-0,0:44:30,0:44:30,4-0,4 +196-2-0,0:45:30,0:45:30,5-0,5 +196-2-0,0:46:30,0:46:30,6-0,6 +196-2-0,0:47:30,0:47:30,7-0,7 +196-2-0,0:49:30,0:49:30,8-0,8 +196-2-0,0:50:30,0:50:30,9-0,9 +196-2-0,0:52:30,0:52:30,10-0,10 +196-2-0,0:54:30,0:54:30,11-0,11 +196-2-0,0:55:30,0:55:30,12-0,12 +196-2-0,0:57:00,0:57:00,13-0,13 +196-2-0,0:58:00,0:58:00,14-0,14 +196-2-0,1:00:00,1:00:00,15-0,15 +196-3-0,1:00:00,1:00:00,1-0,1 +196-3-0,1:02:00,1:02:00,2-0,2 +196-3-0,1:03:30,1:03:30,3-0,3 +196-3-0,1:04:30,1:04:30,4-0,4 +196-3-0,1:05:30,1:05:30,5-0,5 +196-3-0,1:06:30,1:06:30,6-0,6 +196-3-0,1:07:30,1:07:30,7-0,7 +196-3-0,1:09:30,1:09:30,8-0,8 +196-3-0,1:10:30,1:10:30,9-0,9 +196-3-0,1:12:30,1:12:30,10-0,10 +196-3-0,1:14:30,1:14:30,11-0,11 +196-3-0,1:15:30,1:15:30,12-0,12 +196-3-0,1:17:00,1:17:00,13-0,13 +196-3-0,1:18:00,1:18:00,14-0,14 +196-3-0,1:20:00,1:20:00,15-0,15 +196-4-0,1:20:00,1:20:00,1-0,1 +196-4-0,1:22:00,1:22:00,2-0,2 +196-4-0,1:23:30,1:23:30,3-0,3 +196-4-0,1:24:30,1:24:30,4-0,4 +196-4-0,1:25:30,1:25:30,5-0,5 +196-4-0,1:26:30,1:26:30,6-0,6 +196-4-0,1:27:30,1:27:30,7-0,7 +196-4-0,1:29:30,1:29:30,8-0,8 +196-4-0,1:30:30,1:30:30,9-0,9 +196-4-0,1:32:30,1:32:30,10-0,10 +196-4-0,1:34:30,1:34:30,11-0,11 +196-4-0,1:35:30,1:35:30,12-0,12 +196-4-0,1:37:00,1:37:00,13-0,13 +196-4-0,1:38:00,1:38:00,14-0,14 +196-4-0,1:40:00,1:40:00,15-0,15 +196-5-0,1:40:00,1:40:00,1-0,1 +196-5-0,1:42:00,1:42:00,2-0,2 +196-5-0,1:43:30,1:43:30,3-0,3 +196-5-0,1:44:30,1:44:30,4-0,4 +196-5-0,1:45:30,1:45:30,5-0,5 +196-5-0,1:46:30,1:46:30,6-0,6 +196-5-0,1:47:30,1:47:30,7-0,7 +196-5-0,1:49:30,1:49:30,8-0,8 +196-5-0,1:50:30,1:50:30,9-0,9 +196-5-0,1:52:30,1:52:30,10-0,10 +196-5-0,1:54:30,1:54:30,11-0,11 +196-5-0,1:55:30,1:55:30,12-0,12 +196-5-0,1:57:00,1:57:00,13-0,13 +196-5-0,1:58:00,1:58:00,14-0,14 +196-5-0,2:00:00,2:00:00,15-0,15 +196-6-0,2:00:00,2:00:00,1-0,1 +196-6-0,2:02:00,2:02:00,2-0,2 +196-6-0,2:03:30,2:03:30,3-0,3 +196-6-0,2:04:30,2:04:30,4-0,4 +196-6-0,2:05:30,2:05:30,5-0,5 +196-6-0,2:06:30,2:06:30,6-0,6 +196-6-0,2:07:30,2:07:30,7-0,7 +196-6-0,2:09:30,2:09:30,8-0,8 +196-6-0,2:10:30,2:10:30,9-0,9 +196-6-0,2:12:30,2:12:30,10-0,10 +196-6-0,2:14:30,2:14:30,11-0,11 +196-6-0,2:15:30,2:15:30,12-0,12 +196-6-0,2:17:00,2:17:00,13-0,13 +196-6-0,2:18:00,2:18:00,14-0,14 +196-6-0,2:20:00,2:20:00,15-0,15 +196-7-0,2:20:00,2:20:00,1-0,1 +196-7-0,2:22:00,2:22:00,2-0,2 +196-7-0,2:23:30,2:23:30,3-0,3 +196-7-0,2:24:30,2:24:30,4-0,4 +196-7-0,2:25:30,2:25:30,5-0,5 +196-7-0,2:26:30,2:26:30,6-0,6 +196-7-0,2:27:30,2:27:30,7-0,7 +196-7-0,2:29:30,2:29:30,8-0,8 +196-7-0,2:30:30,2:30:30,9-0,9 +196-7-0,2:32:30,2:32:30,10-0,10 +196-7-0,2:34:30,2:34:30,11-0,11 +196-7-0,2:35:30,2:35:30,12-0,12 +196-7-0,2:37:00,2:37:00,13-0,13 +196-7-0,2:38:00,2:38:00,14-0,14 +196-7-0,2:40:00,2:40:00,15-0,15 +196-8-0,2:40:00,2:40:00,1-0,1 +196-8-0,2:42:00,2:42:00,2-0,2 +196-8-0,2:43:30,2:43:30,3-0,3 +196-8-0,2:44:30,2:44:30,4-0,4 +196-8-0,2:45:30,2:45:30,5-0,5 +196-8-0,2:46:30,2:46:30,6-0,6 +196-8-0,2:47:30,2:47:30,7-0,7 +196-8-0,2:49:30,2:49:30,8-0,8 +196-8-0,2:50:30,2:50:30,9-0,9 +196-8-0,2:52:30,2:52:30,10-0,10 +196-8-0,2:54:30,2:54:30,11-0,11 +196-8-0,2:55:30,2:55:30,12-0,12 +196-8-0,2:57:00,2:57:00,13-0,13 +196-8-0,2:58:00,2:58:00,14-0,14 +196-8-0,3:00:00,3:00:00,15-0,15 +196-0-1,0:00:00,0:00:00,15-1,1 +196-0-1,0:02:00,0:02:00,14-1,2 +196-0-1,0:03:30,0:03:30,13-1,3 +196-0-1,0:04:30,0:04:30,12-1,4 +196-0-1,0:05:30,0:05:30,11-1,5 +196-0-1,0:06:30,0:06:30,10-1,6 +196-0-1,0:07:30,0:07:30,9-1,7 +196-0-1,0:09:30,0:09:30,8-1,8 +196-0-1,0:10:30,0:10:30,7-1,9 +196-0-1,0:12:30,0:12:30,6-1,10 +196-0-1,0:14:30,0:14:30,5-1,11 +196-0-1,0:15:30,0:15:30,4-1,12 +196-0-1,0:17:00,0:17:00,3-1,13 +196-0-1,0:18:00,0:18:00,2-1,14 +196-0-1,0:20:00,0:20:00,1-1,15 +196-1-1,0:20:00,0:20:00,15-1,1 +196-1-1,0:22:00,0:22:00,14-1,2 +196-1-1,0:23:30,0:23:30,13-1,3 +196-1-1,0:24:30,0:24:30,12-1,4 +196-1-1,0:25:30,0:25:30,11-1,5 +196-1-1,0:26:30,0:26:30,10-1,6 +196-1-1,0:27:30,0:27:30,9-1,7 +196-1-1,0:29:30,0:29:30,8-1,8 +196-1-1,0:30:30,0:30:30,7-1,9 +196-1-1,0:32:30,0:32:30,6-1,10 +196-1-1,0:34:30,0:34:30,5-1,11 +196-1-1,0:35:30,0:35:30,4-1,12 +196-1-1,0:37:00,0:37:00,3-1,13 +196-1-1,0:38:00,0:38:00,2-1,14 +196-1-1,0:40:00,0:40:00,1-1,15 +196-2-1,0:40:00,0:40:00,15-1,1 +196-2-1,0:42:00,0:42:00,14-1,2 +196-2-1,0:43:30,0:43:30,13-1,3 +196-2-1,0:44:30,0:44:30,12-1,4 +196-2-1,0:45:30,0:45:30,11-1,5 +196-2-1,0:46:30,0:46:30,10-1,6 +196-2-1,0:47:30,0:47:30,9-1,7 +196-2-1,0:49:30,0:49:30,8-1,8 +196-2-1,0:50:30,0:50:30,7-1,9 +196-2-1,0:52:30,0:52:30,6-1,10 +196-2-1,0:54:30,0:54:30,5-1,11 +196-2-1,0:55:30,0:55:30,4-1,12 +196-2-1,0:57:00,0:57:00,3-1,13 +196-2-1,0:58:00,0:58:00,2-1,14 +196-2-1,1:00:00,1:00:00,1-1,15 +196-3-1,1:00:00,1:00:00,15-1,1 +196-3-1,1:02:00,1:02:00,14-1,2 +196-3-1,1:03:30,1:03:30,13-1,3 +196-3-1,1:04:30,1:04:30,12-1,4 +196-3-1,1:05:30,1:05:30,11-1,5 +196-3-1,1:06:30,1:06:30,10-1,6 +196-3-1,1:07:30,1:07:30,9-1,7 +196-3-1,1:09:30,1:09:30,8-1,8 +196-3-1,1:10:30,1:10:30,7-1,9 +196-3-1,1:12:30,1:12:30,6-1,10 +196-3-1,1:14:30,1:14:30,5-1,11 +196-3-1,1:15:30,1:15:30,4-1,12 +196-3-1,1:17:00,1:17:00,3-1,13 +196-3-1,1:18:00,1:18:00,2-1,14 +196-3-1,1:20:00,1:20:00,1-1,15 +196-4-1,1:20:00,1:20:00,15-1,1 +196-4-1,1:22:00,1:22:00,14-1,2 +196-4-1,1:23:30,1:23:30,13-1,3 +196-4-1,1:24:30,1:24:30,12-1,4 +196-4-1,1:25:30,1:25:30,11-1,5 +196-4-1,1:26:30,1:26:30,10-1,6 +196-4-1,1:27:30,1:27:30,9-1,7 +196-4-1,1:29:30,1:29:30,8-1,8 +196-4-1,1:30:30,1:30:30,7-1,9 +196-4-1,1:32:30,1:32:30,6-1,10 +196-4-1,1:34:30,1:34:30,5-1,11 +196-4-1,1:35:30,1:35:30,4-1,12 +196-4-1,1:37:00,1:37:00,3-1,13 +196-4-1,1:38:00,1:38:00,2-1,14 +196-4-1,1:40:00,1:40:00,1-1,15 +196-5-1,1:40:00,1:40:00,15-1,1 +196-5-1,1:42:00,1:42:00,14-1,2 +196-5-1,1:43:30,1:43:30,13-1,3 +196-5-1,1:44:30,1:44:30,12-1,4 +196-5-1,1:45:30,1:45:30,11-1,5 +196-5-1,1:46:30,1:46:30,10-1,6 +196-5-1,1:47:30,1:47:30,9-1,7 +196-5-1,1:49:30,1:49:30,8-1,8 +196-5-1,1:50:30,1:50:30,7-1,9 +196-5-1,1:52:30,1:52:30,6-1,10 +196-5-1,1:54:30,1:54:30,5-1,11 +196-5-1,1:55:30,1:55:30,4-1,12 +196-5-1,1:57:00,1:57:00,3-1,13 +196-5-1,1:58:00,1:58:00,2-1,14 +196-5-1,2:00:00,2:00:00,1-1,15 +196-6-1,2:00:00,2:00:00,15-1,1 +196-6-1,2:02:00,2:02:00,14-1,2 +196-6-1,2:03:30,2:03:30,13-1,3 +196-6-1,2:04:30,2:04:30,12-1,4 +196-6-1,2:05:30,2:05:30,11-1,5 +196-6-1,2:06:30,2:06:30,10-1,6 +196-6-1,2:07:30,2:07:30,9-1,7 +196-6-1,2:09:30,2:09:30,8-1,8 +196-6-1,2:10:30,2:10:30,7-1,9 +196-6-1,2:12:30,2:12:30,6-1,10 +196-6-1,2:14:30,2:14:30,5-1,11 +196-6-1,2:15:30,2:15:30,4-1,12 +196-6-1,2:17:00,2:17:00,3-1,13 +196-6-1,2:18:00,2:18:00,2-1,14 +196-6-1,2:20:00,2:20:00,1-1,15 +196-7-1,2:20:00,2:20:00,15-1,1 +196-7-1,2:22:00,2:22:00,14-1,2 +196-7-1,2:23:30,2:23:30,13-1,3 +196-7-1,2:24:30,2:24:30,12-1,4 +196-7-1,2:25:30,2:25:30,11-1,5 +196-7-1,2:26:30,2:26:30,10-1,6 +196-7-1,2:27:30,2:27:30,9-1,7 +196-7-1,2:29:30,2:29:30,8-1,8 +196-7-1,2:30:30,2:30:30,7-1,9 +196-7-1,2:32:30,2:32:30,6-1,10 +196-7-1,2:34:30,2:34:30,5-1,11 +196-7-1,2:35:30,2:35:30,4-1,12 +196-7-1,2:37:00,2:37:00,3-1,13 +196-7-1,2:38:00,2:38:00,2-1,14 +196-7-1,2:40:00,2:40:00,1-1,15 +196-8-1,2:40:00,2:40:00,15-1,1 +196-8-1,2:42:00,2:42:00,14-1,2 +196-8-1,2:43:30,2:43:30,13-1,3 +196-8-1,2:44:30,2:44:30,12-1,4 +196-8-1,2:45:30,2:45:30,11-1,5 +196-8-1,2:46:30,2:46:30,10-1,6 +196-8-1,2:47:30,2:47:30,9-1,7 +196-8-1,2:49:30,2:49:30,8-1,8 +196-8-1,2:50:30,2:50:30,7-1,9 +196-8-1,2:52:30,2:52:30,6-1,10 +196-8-1,2:54:30,2:54:30,5-1,11 +196-8-1,2:55:30,2:55:30,4-1,12 +196-8-1,2:57:00,2:57:00,3-1,13 +196-8-1,2:58:00,2:58:00,2-1,14 +196-8-1,3:00:00,3:00:00,1-1,15 +U5-0-0,0:00:00,0:00:00,1-2,1 +U5-0-0,0:01:00,0:01:00,17-2,2 +U5-0-0,0:02:00,0:02:00,16-2,3 +U5-0-0,0:03:00,0:03:00,15-2,4 +U5-1-0,0:05:00,0:05:00,1-2,1 +U5-1-0,0:06:00,0:06:00,17-2,2 +U5-1-0,0:07:00,0:07:00,16-2,3 +U5-1-0,0:08:00,0:08:00,15-2,4 +U5-2-0,0:10:00,0:10:00,1-2,1 +U5-2-0,0:11:00,0:11:00,17-2,2 +U5-2-0,0:12:00,0:12:00,16-2,3 +U5-2-0,0:13:00,0:13:00,15-2,4 +U5-3-0,0:15:00,0:15:00,1-2,1 +U5-3-0,0:16:00,0:16:00,17-2,2 +U5-3-0,0:17:00,0:17:00,16-2,3 +U5-3-0,0:18:00,0:18:00,15-2,4 +U5-4-0,0:20:00,0:20:00,1-2,1 +U5-4-0,0:21:00,0:21:00,17-2,2 +U5-4-0,0:22:00,0:22:00,16-2,3 +U5-4-0,0:23:00,0:23:00,15-2,4 +U5-5-0,0:25:00,0:25:00,1-2,1 +U5-5-0,0:26:00,0:26:00,17-2,2 +U5-5-0,0:27:00,0:27:00,16-2,3 +U5-5-0,0:28:00,0:28:00,15-2,4 +U5-6-0,0:30:00,0:30:00,1-2,1 +U5-6-0,0:31:00,0:31:00,17-2,2 +U5-6-0,0:32:00,0:32:00,16-2,3 +U5-6-0,0:33:00,0:33:00,15-2,4 +U5-7-0,0:35:00,0:35:00,1-2,1 +U5-7-0,0:36:00,0:36:00,17-2,2 +U5-7-0,0:37:00,0:37:00,16-2,3 +U5-7-0,0:38:00,0:38:00,15-2,4 +U5-8-0,0:40:00,0:40:00,1-2,1 +U5-8-0,0:41:00,0:41:00,17-2,2 +U5-8-0,0:42:00,0:42:00,16-2,3 +U5-8-0,0:43:00,0:43:00,15-2,4 +U5-9-0,0:45:00,0:45:00,1-2,1 +U5-9-0,0:46:00,0:46:00,17-2,2 +U5-9-0,0:47:00,0:47:00,16-2,3 +U5-9-0,0:48:00,0:48:00,15-2,4 +U5-10-0,0:50:00,0:50:00,1-2,1 +U5-10-0,0:51:00,0:51:00,17-2,2 +U5-10-0,0:52:00,0:52:00,16-2,3 +U5-10-0,0:53:00,0:53:00,15-2,4 +U5-11-0,0:55:00,0:55:00,1-2,1 +U5-11-0,0:56:00,0:56:00,17-2,2 +U5-11-0,0:57:00,0:57:00,16-2,3 +U5-11-0,0:58:00,0:58:00,15-2,4 +U5-12-0,1:00:00,1:00:00,1-2,1 +U5-12-0,1:01:00,1:01:00,17-2,2 +U5-12-0,1:02:00,1:02:00,16-2,3 +U5-12-0,1:03:00,1:03:00,15-2,4 +U5-13-0,1:05:00,1:05:00,1-2,1 +U5-13-0,1:06:00,1:06:00,17-2,2 +U5-13-0,1:07:00,1:07:00,16-2,3 +U5-13-0,1:08:00,1:08:00,15-2,4 +U5-14-0,1:10:00,1:10:00,1-2,1 +U5-14-0,1:11:00,1:11:00,17-2,2 +U5-14-0,1:12:00,1:12:00,16-2,3 +U5-14-0,1:13:00,1:13:00,15-2,4 +U5-15-0,1:15:00,1:15:00,1-2,1 +U5-15-0,1:16:00,1:16:00,17-2,2 +U5-15-0,1:17:00,1:17:00,16-2,3 +U5-15-0,1:18:00,1:18:00,15-2,4 +U5-16-0,1:20:00,1:20:00,1-2,1 +U5-16-0,1:21:00,1:21:00,17-2,2 +U5-16-0,1:22:00,1:22:00,16-2,3 +U5-16-0,1:23:00,1:23:00,15-2,4 +U5-17-0,1:25:00,1:25:00,1-2,1 +U5-17-0,1:26:00,1:26:00,17-2,2 +U5-17-0,1:27:00,1:27:00,16-2,3 +U5-17-0,1:28:00,1:28:00,15-2,4 +U5-18-0,1:30:00,1:30:00,1-2,1 +U5-18-0,1:31:00,1:31:00,17-2,2 +U5-18-0,1:32:00,1:32:00,16-2,3 +U5-18-0,1:33:00,1:33:00,15-2,4 +U5-19-0,1:35:00,1:35:00,1-2,1 +U5-19-0,1:36:00,1:36:00,17-2,2 +U5-19-0,1:37:00,1:37:00,16-2,3 +U5-19-0,1:38:00,1:38:00,15-2,4 +U5-20-0,1:40:00,1:40:00,1-2,1 +U5-20-0,1:41:00,1:41:00,17-2,2 +U5-20-0,1:42:00,1:42:00,16-2,3 +U5-20-0,1:43:00,1:43:00,15-2,4 +U5-21-0,1:45:00,1:45:00,1-2,1 +U5-21-0,1:46:00,1:46:00,17-2,2 +U5-21-0,1:47:00,1:47:00,16-2,3 +U5-21-0,1:48:00,1:48:00,15-2,4 +U5-22-0,1:50:00,1:50:00,1-2,1 +U5-22-0,1:51:00,1:51:00,17-2,2 +U5-22-0,1:52:00,1:52:00,16-2,3 +U5-22-0,1:53:00,1:53:00,15-2,4 +U5-23-0,1:55:00,1:55:00,1-2,1 +U5-23-0,1:56:00,1:56:00,17-2,2 +U5-23-0,1:57:00,1:57:00,16-2,3 +U5-23-0,1:58:00,1:58:00,15-2,4 +U5-24-0,2:00:00,2:00:00,1-2,1 +U5-24-0,2:01:00,2:01:00,17-2,2 +U5-24-0,2:02:00,2:02:00,16-2,3 +U5-24-0,2:03:00,2:03:00,15-2,4 +U5-25-0,2:05:00,2:05:00,1-2,1 +U5-25-0,2:06:00,2:06:00,17-2,2 +U5-25-0,2:07:00,2:07:00,16-2,3 +U5-25-0,2:08:00,2:08:00,15-2,4 +U5-26-0,2:10:00,2:10:00,1-2,1 +U5-26-0,2:11:00,2:11:00,17-2,2 +U5-26-0,2:12:00,2:12:00,16-2,3 +U5-26-0,2:13:00,2:13:00,15-2,4 +U5-27-0,2:15:00,2:15:00,1-2,1 +U5-27-0,2:16:00,2:16:00,17-2,2 +U5-27-0,2:17:00,2:17:00,16-2,3 +U5-27-0,2:18:00,2:18:00,15-2,4 +U5-28-0,2:20:00,2:20:00,1-2,1 +U5-28-0,2:21:00,2:21:00,17-2,2 +U5-28-0,2:22:00,2:22:00,16-2,3 +U5-28-0,2:23:00,2:23:00,15-2,4 +U5-29-0,2:25:00,2:25:00,1-2,1 +U5-29-0,2:26:00,2:26:00,17-2,2 +U5-29-0,2:27:00,2:27:00,16-2,3 +U5-29-0,2:28:00,2:28:00,15-2,4 +U5-30-0,2:30:00,2:30:00,1-2,1 +U5-30-0,2:31:00,2:31:00,17-2,2 +U5-30-0,2:32:00,2:32:00,16-2,3 +U5-30-0,2:33:00,2:33:00,15-2,4 +U5-31-0,2:35:00,2:35:00,1-2,1 +U5-31-0,2:36:00,2:36:00,17-2,2 +U5-31-0,2:37:00,2:37:00,16-2,3 +U5-31-0,2:38:00,2:38:00,15-2,4 +U5-32-0,2:40:00,2:40:00,1-2,1 +U5-32-0,2:41:00,2:41:00,17-2,2 +U5-32-0,2:42:00,2:42:00,16-2,3 +U5-32-0,2:43:00,2:43:00,15-2,4 +U5-33-0,2:45:00,2:45:00,1-2,1 +U5-33-0,2:46:00,2:46:00,17-2,2 +U5-33-0,2:47:00,2:47:00,16-2,3 +U5-33-0,2:48:00,2:48:00,15-2,4 +U5-34-0,2:50:00,2:50:00,1-2,1 +U5-34-0,2:51:00,2:51:00,17-2,2 +U5-34-0,2:52:00,2:52:00,16-2,3 +U5-34-0,2:53:00,2:53:00,15-2,4 +U5-35-0,2:55:00,2:55:00,1-2,1 +U5-35-0,2:56:00,2:56:00,17-2,2 +U5-35-0,2:57:00,2:57:00,16-2,3 +U5-35-0,2:58:00,2:58:00,15-2,4 +U5-0-1,0:00:00,0:00:00,15-3,1 +U5-0-1,0:01:00,0:01:00,16-3,2 +U5-0-1,0:02:00,0:02:00,17-3,3 +U5-0-1,0:03:00,0:03:00,1-3,4 +U5-1-1,0:05:00,0:05:00,15-3,1 +U5-1-1,0:06:00,0:06:00,16-3,2 +U5-1-1,0:07:00,0:07:00,17-3,3 +U5-1-1,0:08:00,0:08:00,1-3,4 +U5-2-1,0:10:00,0:10:00,15-3,1 +U5-2-1,0:11:00,0:11:00,16-3,2 +U5-2-1,0:12:00,0:12:00,17-3,3 +U5-2-1,0:13:00,0:13:00,1-3,4 +U5-3-1,0:15:00,0:15:00,15-3,1 +U5-3-1,0:16:00,0:16:00,16-3,2 +U5-3-1,0:17:00,0:17:00,17-3,3 +U5-3-1,0:18:00,0:18:00,1-3,4 +U5-4-1,0:20:00,0:20:00,15-3,1 +U5-4-1,0:21:00,0:21:00,16-3,2 +U5-4-1,0:22:00,0:22:00,17-3,3 +U5-4-1,0:23:00,0:23:00,1-3,4 +U5-5-1,0:25:00,0:25:00,15-3,1 +U5-5-1,0:26:00,0:26:00,16-3,2 +U5-5-1,0:27:00,0:27:00,17-3,3 +U5-5-1,0:28:00,0:28:00,1-3,4 +U5-6-1,0:30:00,0:30:00,15-3,1 +U5-6-1,0:31:00,0:31:00,16-3,2 +U5-6-1,0:32:00,0:32:00,17-3,3 +U5-6-1,0:33:00,0:33:00,1-3,4 +U5-7-1,0:35:00,0:35:00,15-3,1 +U5-7-1,0:36:00,0:36:00,16-3,2 +U5-7-1,0:37:00,0:37:00,17-3,3 +U5-7-1,0:38:00,0:38:00,1-3,4 +U5-8-1,0:40:00,0:40:00,15-3,1 +U5-8-1,0:41:00,0:41:00,16-3,2 +U5-8-1,0:42:00,0:42:00,17-3,3 +U5-8-1,0:43:00,0:43:00,1-3,4 +U5-9-1,0:45:00,0:45:00,15-3,1 +U5-9-1,0:46:00,0:46:00,16-3,2 +U5-9-1,0:47:00,0:47:00,17-3,3 +U5-9-1,0:48:00,0:48:00,1-3,4 +U5-10-1,0:50:00,0:50:00,15-3,1 +U5-10-1,0:51:00,0:51:00,16-3,2 +U5-10-1,0:52:00,0:52:00,17-3,3 +U5-10-1,0:53:00,0:53:00,1-3,4 +U5-11-1,0:55:00,0:55:00,15-3,1 +U5-11-1,0:56:00,0:56:00,16-3,2 +U5-11-1,0:57:00,0:57:00,17-3,3 +U5-11-1,0:58:00,0:58:00,1-3,4 +U5-12-1,1:00:00,1:00:00,15-3,1 +U5-12-1,1:01:00,1:01:00,16-3,2 +U5-12-1,1:02:00,1:02:00,17-3,3 +U5-12-1,1:03:00,1:03:00,1-3,4 +U5-13-1,1:05:00,1:05:00,15-3,1 +U5-13-1,1:06:00,1:06:00,16-3,2 +U5-13-1,1:07:00,1:07:00,17-3,3 +U5-13-1,1:08:00,1:08:00,1-3,4 +U5-14-1,1:10:00,1:10:00,15-3,1 +U5-14-1,1:11:00,1:11:00,16-3,2 +U5-14-1,1:12:00,1:12:00,17-3,3 +U5-14-1,1:13:00,1:13:00,1-3,4 +U5-15-1,1:15:00,1:15:00,15-3,1 +U5-15-1,1:16:00,1:16:00,16-3,2 +U5-15-1,1:17:00,1:17:00,17-3,3 +U5-15-1,1:18:00,1:18:00,1-3,4 +U5-16-1,1:20:00,1:20:00,15-3,1 +U5-16-1,1:21:00,1:21:00,16-3,2 +U5-16-1,1:22:00,1:22:00,17-3,3 +U5-16-1,1:23:00,1:23:00,1-3,4 +U5-17-1,1:25:00,1:25:00,15-3,1 +U5-17-1,1:26:00,1:26:00,16-3,2 +U5-17-1,1:27:00,1:27:00,17-3,3 +U5-17-1,1:28:00,1:28:00,1-3,4 +U5-18-1,1:30:00,1:30:00,15-3,1 +U5-18-1,1:31:00,1:31:00,16-3,2 +U5-18-1,1:32:00,1:32:00,17-3,3 +U5-18-1,1:33:00,1:33:00,1-3,4 +U5-19-1,1:35:00,1:35:00,15-3,1 +U5-19-1,1:36:00,1:36:00,16-3,2 +U5-19-1,1:37:00,1:37:00,17-3,3 +U5-19-1,1:38:00,1:38:00,1-3,4 +U5-20-1,1:40:00,1:40:00,15-3,1 +U5-20-1,1:41:00,1:41:00,16-3,2 +U5-20-1,1:42:00,1:42:00,17-3,3 +U5-20-1,1:43:00,1:43:00,1-3,4 +U5-21-1,1:45:00,1:45:00,15-3,1 +U5-21-1,1:46:00,1:46:00,16-3,2 +U5-21-1,1:47:00,1:47:00,17-3,3 +U5-21-1,1:48:00,1:48:00,1-3,4 +U5-22-1,1:50:00,1:50:00,15-3,1 +U5-22-1,1:51:00,1:51:00,16-3,2 +U5-22-1,1:52:00,1:52:00,17-3,3 +U5-22-1,1:53:00,1:53:00,1-3,4 +U5-23-1,1:55:00,1:55:00,15-3,1 +U5-23-1,1:56:00,1:56:00,16-3,2 +U5-23-1,1:57:00,1:57:00,17-3,3 +U5-23-1,1:58:00,1:58:00,1-3,4 +U5-24-1,2:00:00,2:00:00,15-3,1 +U5-24-1,2:01:00,2:01:00,16-3,2 +U5-24-1,2:02:00,2:02:00,17-3,3 +U5-24-1,2:03:00,2:03:00,1-3,4 +U5-25-1,2:05:00,2:05:00,15-3,1 +U5-25-1,2:06:00,2:06:00,16-3,2 +U5-25-1,2:07:00,2:07:00,17-3,3 +U5-25-1,2:08:00,2:08:00,1-3,4 +U5-26-1,2:10:00,2:10:00,15-3,1 +U5-26-1,2:11:00,2:11:00,16-3,2 +U5-26-1,2:12:00,2:12:00,17-3,3 +U5-26-1,2:13:00,2:13:00,1-3,4 +U5-27-1,2:15:00,2:15:00,15-3,1 +U5-27-1,2:16:00,2:16:00,16-3,2 +U5-27-1,2:17:00,2:17:00,17-3,3 +U5-27-1,2:18:00,2:18:00,1-3,4 +U5-28-1,2:20:00,2:20:00,15-3,1 +U5-28-1,2:21:00,2:21:00,16-3,2 +U5-28-1,2:22:00,2:22:00,17-3,3 +U5-28-1,2:23:00,2:23:00,1-3,4 +U5-29-1,2:25:00,2:25:00,15-3,1 +U5-29-1,2:26:00,2:26:00,16-3,2 +U5-29-1,2:27:00,2:27:00,17-3,3 +U5-29-1,2:28:00,2:28:00,1-3,4 +U5-30-1,2:30:00,2:30:00,15-3,1 +U5-30-1,2:31:00,2:31:00,16-3,2 +U5-30-1,2:32:00,2:32:00,17-3,3 +U5-30-1,2:33:00,2:33:00,1-3,4 +U5-31-1,2:35:00,2:35:00,15-3,1 +U5-31-1,2:36:00,2:36:00,16-3,2 +U5-31-1,2:37:00,2:37:00,17-3,3 +U5-31-1,2:38:00,2:38:00,1-3,4 +U5-32-1,2:40:00,2:40:00,15-3,1 +U5-32-1,2:41:00,2:41:00,16-3,2 +U5-32-1,2:42:00,2:42:00,17-3,3 +U5-32-1,2:43:00,2:43:00,1-3,4 +U5-33-1,2:45:00,2:45:00,15-3,1 +U5-33-1,2:46:00,2:46:00,16-3,2 +U5-33-1,2:47:00,2:47:00,17-3,3 +U5-33-1,2:48:00,2:48:00,1-3,4 +U5-34-1,2:50:00,2:50:00,15-3,1 +U5-34-1,2:51:00,2:51:00,16-3,2 +U5-34-1,2:52:00,2:52:00,17-3,3 +U5-34-1,2:53:00,2:53:00,1-3,4 +U5-35-1,2:55:00,2:55:00,15-3,1 +U5-35-1,2:56:00,2:56:00,16-3,2 +U5-35-1,2:57:00,2:57:00,17-3,3 +U5-35-1,2:58:00,2:58:00,1-3,4 diff --git a/data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt new file mode 100644 index 00000000..0c9db8bd --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt @@ -0,0 +1,39 @@ +stop_id +1-0 +1-1 +1-2 +1-3 +2-0 +2-1 +3-0 +3-1 +4-0 +4-1 +5-0 +5-1 +6-0 +6-1 +7-0 +7-1 +8-0 +8-1 +9-0 +9-1 +10-0 +10-1 +11-0 +11-1 +12-0 +12-1 +13-0 +13-1 +14-0 +14-1 +15-0 +15-1 +15-2 +15-3 +16-2 +16-3 +17-2 +17-3 diff --git a/data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt new file mode 100644 index 00000000..bdc34d27 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt @@ -0,0 +1,29 @@ +node_id,closest_station_id,street_station_transfer_time +2966,s1,60 +2967,s2,27 +2968,s3,49 +2969,s4,27 +2970,s5,12 +2971,s6,66 +2972,s7,3 +2973,s8,19 +2974,s9,30 +2975,s10,46 +2976,s11,23 +2977,s12,17 +2978,s13,29 +2979,s14,38 +2980,s15,28 +2981,s14,23 +2982,s13,21 +2983,s12,18 +2984,s11,40 +2985,s10,40 +2986,s9,35 +2987,s8,12 +2988,s7,4 +2989,s6,64 +2990,s5,13 +2991,s4,38 +2992,s3,58 +2993,s2,27 diff --git a/data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt new file mode 100644 index 00000000..51a2fa24 --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt @@ -0,0 +1,55 @@ +from_stop_id,to_stop_id,min_transfer_time +1-0,1-1,3 +1-0,1-2,3 +1-0,1-3,3 +1-1,1-0,3 +1-1,1-2,3 +1-1,1-3,3 +1-2,1-0,3 +1-2,1-1,3 +1-2,1-3,3 +1-3,1-0,3 +1-3,1-1,3 +1-3,1-2,3 +2-0,2-1,3 +2-1,2-0,3 +3-0,3-1,3 +3-1,3-0,3 +4-0,4-1,3 +4-1,4-0,3 +5-0,5-1,3 +5-1,5-0,3 +6-0,6-1,3 +6-1,6-0,3 +7-0,7-1,3 +7-1,7-0,3 +8-0,8-1,3 +8-1,8-0,3 +9-0,9-1,3 +9-1,9-0,3 +10-0,10-1,3 +10-1,10-0,3 +11-0,11-1,3 +11-1,11-0,3 +12-0,12-1,3 +12-1,12-0,3 +13-0,13-1,3 +13-1,13-0,3 +14-0,14-1,3 +14-1,14-0,3 +15-0,15-1,3 +15-0,15-2,3 +15-0,15-3,3 +15-1,15-0,3 +15-1,15-2,3 +15-1,15-3,3 +15-2,15-0,3 +15-2,15-1,3 +15-2,15-3,3 +15-3,15-0,3 +15-3,15-1,3 +15-3,15-2,3 +16-2,16-3,3 +16-3,16-2,3 +17-2,17-3,3 +17-3,17-2,3 diff --git a/data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt b/data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt new file mode 100644 index 00000000..a23bc74b --- /dev/null +++ b/data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt @@ -0,0 +1,94 @@ +route_id,trip_id,service_id,direction_id +196,196-0-0,0,0 +196,196-1-0,0,0 +196,196-2-0,0,0 +196,196-3-0,0,0 +196,196-4-0,0,0 +196,196-5-0,0,0 +196,196-6-0,0,0 +196,196-7-0,0,0 +196,196-8-0,0,0 +196,196-0-1,0,1 +196,196-1-1,0,1 +196,196-2-1,0,1 +196,196-3-1,0,1 +196,196-4-1,0,1 +196,196-5-1,0,1 +196,196-6-1,0,1 +196,196-7-1,0,1 +196,196-8-1,0,1 +U5,U5-0-0,0,0 +U5,U5-1-0,0,0 +U5,U5-2-0,0,0 +U5,U5-3-0,0,0 +U5,U5-4-0,0,0 +U5,U5-5-0,0,0 +U5,U5-6-0,0,0 +U5,U5-7-0,0,0 +U5,U5-8-0,0,0 +U5,U5-9-0,0,0 +U5,U5-10-0,0,0 +U5,U5-11-0,0,0 +U5,U5-12-0,0,0 +U5,U5-13-0,0,0 +U5,U5-14-0,0,0 +U5,U5-15-0,0,0 +U5,U5-16-0,0,0 +U5,U5-17-0,0,0 +U5,U5-18-0,0,0 +U5,U5-19-0,0,0 +U5,U5-20-0,0,0 +U5,U5-21-0,0,0 +U5,U5-22-0,0,0 +U5,U5-23-0,0,0 +U5,U5-24-0,0,0 +U5,U5-25-0,0,0 +U5,U5-26-0,0,0 +U5,U5-27-0,0,0 +U5,U5-28-0,0,0 +U5,U5-29-0,0,0 +U5,U5-30-0,0,0 +U5,U5-31-0,0,0 +U5,U5-32-0,0,0 +U5,U5-33-0,0,0 +U5,U5-34-0,0,0 +U5,U5-35-0,0,0 +U5,U5-0-1,0,1 +U5,U5-1-1,0,1 +U5,U5-2-1,0,1 +U5,U5-3-1,0,1 +U5,U5-4-1,0,1 +U5,U5-5-1,0,1 +U5,U5-6-1,0,1 +U5,U5-7-1,0,1 +U5,U5-8-1,0,1 +U5,U5-9-1,0,1 +U5,U5-10-1,0,1 +U5,U5-11-1,0,1 +U5,U5-12-1,0,1 +U5,U5-13-1,0,1 +U5,U5-14-1,0,1 +U5,U5-15-1,0,1 +U5,U5-16-1,0,1 +U5,U5-17-1,0,1 +U5,U5-18-1,0,1 +U5,U5-19-1,0,1 +U5,U5-20-1,0,1 +U5,U5-21-1,0,1 +U5,U5-22-1,0,1 +U5,U5-23-1,0,1 +U5,U5-24-1,0,1 +U5,U5-25-1,0,1 +U5,U5-26-1,0,1 +U5,U5-27-1,0,1 +U5,U5-28-1,0,1 +U5,U5-29-1,0,1 +U5,U5-30-1,0,1 +U5,U5-31-1,0,1 +U5,U5-32-1,0,1 +U5,U5-33-1,0,1 +U5,U5-34-1,0,1 +U5,U5-35-1,0,1 + + + diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py new file mode 100644 index 00000000..1f0bf5fa --- /dev/null +++ b/src/routing/pt/RaptorRouterCpp.py @@ -0,0 +1,178 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import os +import logging +from datetime import datetime +import ast +import typing as tp +import pandas as pd + +# additional module imports (> requirements) +# ------------------------------------------ + +# src imports +# ----------- +from src.routing.pt.cpp_raptor_router.PyPTRouter import PyPTRouter + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) + +INPUT_PARAMETERS_RaptorRouterCpp = { + "doc" : "this class is the PT router class using C++ Raptor implementation", + "inherit" : [], + "input_parameters_mandatory": [], + "input_parameters_optional": [], + "mandatory_modules": [PyPTRouter], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class RaptorRouterCpp(): + def __init__(self, gtfs_dir: str): + """ + Args: + gtfs_dir (str): the directory path where the GTFS files are stored. + """ + # initialize the pt router + self.pt_router = None + self._initialize_pt_router(gtfs_dir) + + # load the stations: used for station-stop mapping + self.stations_fp_df = self._load_stations_from_gtfs(gtfs_dir) + + # load the street-station transfers: used for finding closest station to a street node, or vice versa + self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(gtfs_dir) + + def _initialize_pt_router(self, gtfs_dir: str): + """This method initializes the PT router. + + Args: + gtfs_dir (str): the directory path where the GTFS files are stored. + """ + # check if the directories exist and is all mandatory files present + mandatory_files = [ + "agency_fp.txt", + "stops_fp.txt", + "trips_fp.txt", + "routes_fp.txt", + "calendar_fp.txt", + "stop_times_fp.txt", + "stations_fp.txt", + "transfers_fp.txt" + ] + if not os.path.exists(gtfs_dir): + raise FileNotFoundError(f"The directory {gtfs_dir} does not exist.") + for file in mandatory_files: + if not os.path.exists(os.path.join(gtfs_dir, file)): + raise FileNotFoundError(f"The file {file} does not exist in the directory {gtfs_dir}.") + + # initialize the pt router with the given gtfs data + LOG.debug(f"Initializing the Raptor router (C++) with the given GTFS data in the directory: {gtfs_dir}") + self.pt_router = PyPTRouter(gtfs_dir) + LOG.debug("Raptor router (C++) initialized successfully.") + + def _load_stations_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific stations file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The PT stations data. + """ + dtypes = { + 'station_id': 'str', + 'station_name': 'str', + 'station_lat': 'float', + 'station_lon': 'float', + 'stops_included': 'str', + 'station_stop_transfer_times': 'str', + 'num_stops_included': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "stations_fp.txt"), dtype=dtypes) + + def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific street station transfers file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The transfer data between the street nodes and the PT stations. + """ + dtypes = { + 'node_id': 'int', + 'closest_station_id': 'str', + 'street_transfer_time': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) + + def return_fastest_pt_journey_1to1( + self, + source_station_id: str, + target_station_id: str, + source_station_departure_datetime: datetime, + max_transfers: int=999, + detailed: bool=False, + ) -> tp.Union[tp.Dict[str, tp.Any], None]: + """This method returns the fastest PT journey plan between two PT stations. + A station may consist of multiple stops. + + Args: + source_station_id (str): The id of the source station. + target_station_id (str): The id of the target station. + source_station_departure_datetime (datetime): The departure datetime at the source station. + max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. + detailed (bool): Whether to return the detailed journey plan. + Returns: + tp.Union[tp.Dict[str, tp.Any], None]: The fastest PT journey plan or None if no journey is found. + """ + # get all included stops for the source and target station + included_sources = self._get_included_stops_and_transfer_times(source_station_id) + included_targets = self._get_included_stops_and_transfer_times(target_station_id) + + return self.pt_router.return_fastest_pt_journey_1to1(source_station_departure_datetime, included_sources, included_targets, max_transfers, detailed) + + def _get_included_stops_and_transfer_times(self, station_id: str) -> tp.Tuple[tp.List[str], tp.List[int]]: + """This method returns the included stops and transfer times for a given station. + + Args: + station_id (str): The id of the station. + Returns: + tp.Tuple[tp.List[str], tp.List[int]]: The included stops and transfer times. + """ + station_data = self.stations_fp_df[self.stations_fp_df["station_id"] == station_id] + + if station_data.empty: + raise ValueError(f"Station ID {station_id} not found in the stations data") + + included_ids_str = station_data["stops_included"].iloc[0] + included_ids_str = included_ids_str.replace(';', ',') + included_ids_list = ast.literal_eval(included_ids_str) + + transfer_times_str = station_data["station_stop_transfer_times"].iloc[0] + transfer_times_str = transfer_times_str.replace(';', ',') + transfer_times_list = ast.literal_eval(transfer_times_str) + return [(stop_id, int(transfer_time)) for stop_id, transfer_time in zip(included_ids_list, transfer_times_list)] + + + +if __name__ == "__main__": + # Test the pt router class: python -m src.routing.pt.CppTester + + gtfs_dir = r"data\pubtrans\example_network\example_gtfs\matched" + router = RaptorRouterCpp(gtfs_dir) + + source_station_departure_datetime = datetime(2024, 1, 1, 0, 4, 0) + import time + start_time = time.time() + print(router.return_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=False)) + print(f"Time taken: {time.time() - start_time} seconds") + start_time = time.time() + print(router.return_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=True)) + print(f"Time taken: {time.time() - start_time} seconds") \ No newline at end of file diff --git a/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h b/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h index 4d4a4b45..66fc415a 100644 --- a/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h +++ b/src/routing/pt/cpp_raptor_router/NetworkObjects/DataStructures.h @@ -37,7 +37,7 @@ struct Query { std::vector> included_sources; ///< Stops in the source station with its station_stop_transfer_time (in seconds). std::vector> included_targets; ///< Stops in the target station with its station_stop_transfer_time (in seconds). Date date; ///< Date of the journey (year, month, day). - Time departure_time; ///< Desired departure time in the source station (in seconds from midnight). + Time departure_time; ///< Desired departure time at the source station (in seconds from midnight). int max_transfers; ///< Maximum number of transfers. }; @@ -81,19 +81,22 @@ struct JourneyStep { * * The `Journey` structure contains details about all steps in the journey, * as well as overall departure and arrival times and durations. + * source_station_departure_secs|source_transfer_time|source_waiting_time|trip_time|target_transfer_time|target_station_arrival_secs + * |------------------------------------------------duration-----------------------------------------------------------------------| */ struct Journey { std::vector steps; ///< Steps making up the journey. - int departure_secs; ///< Overall departure time in seconds from midnight of the query day at source station. - Day departure_day; ///< Departure day of the journey at source station. + int source_station_departure_secs; ///< Overall departure time in seconds from midnight of the query day at source station. + Day source_station_departure_day; ///< Departure day of the journey at source station. - int arrival_secs; ///< Overall arrival time in seconds from midnight of the query day at target station. - Day arrival_day; ///< Arrival day of the journey at target station. + int target_station_arrival_secs; ///< Overall arrival time in seconds from midnight of the query day at target station. + Day target_station_arrival_day; ///< Arrival day of the journey at target station. - int duration; ///< Total duration of the journey in seconds. + int duration; ///< Total duration of the journey from source station to target station in seconds. int source_transfer_time; ///< Transfer time from source station to source station stop in seconds. - int waiting_time; ///< Waiting time at the source station in seconds. - int trip_time; ///< Trip time from source station stops to target station in seconds. + int source_waiting_time; ///< Waiting time at the source station in seconds. + int trip_time; ///< Trip time from source station stop to target station stop in seconds. + int target_transfer_time; ///< Transfer time from target station stop to target station in seconds. int num_transfers; ///< Number of transfers in the journey. }; diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp b/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp index 7606e7fb..67d2603f 100644 --- a/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp @@ -2521,7 +2521,6 @@ static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static const char __pyx_k_to_stop_id[] = "to_stop_id"; static const char __pyx_k_MemoryError[] = "MemoryError"; static const char __pyx_k_agency_name[] = "agency_name"; -static const char __pyx_k_arrival_day[] = "arrival_day"; static const char __pyx_k_current_day[] = "current_day"; static const char __pyx_k_journey_opt[] = "journey_opt"; static const char __pyx_k_RuntimeError[] = "RuntimeError"; @@ -2531,8 +2530,6 @@ static const char __pyx_k_initializing[] = "_initializing"; static const char __pyx_k_is_coroutine[] = "_is_coroutine"; static const char __pyx_k_journey_dict[] = "journey_dict"; static const char __pyx_k_stringsource[] = ""; -static const char __pyx_k_waiting_time[] = "waiting_time"; -static const char __pyx_k_departure_day[] = "departure_day"; static const char __pyx_k_journeys_list[] = "journeys_list"; static const char __pyx_k_max_transfers[] = "max_transfers"; static const char __pyx_k_num_transfers[] = "num_transfers"; @@ -2542,23 +2539,29 @@ static const char __pyx_k_departure_time[] = "departure_time"; static const char __pyx_k_construct_query[] = "construct_query"; static const char __pyx_k_input_directory[] = "input_directory"; static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_arrival_datetime[] = "arrival_datetime"; static const char __pyx_k_included_sources[] = "included_sources"; static const char __pyx_k_included_targets[] = "included_targets"; static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_source_waiting_time[] = "source_waiting_time"; static const char __pyx_k_source_transfer_time[] = "source_transfer_time"; +static const char __pyx_k_target_transfer_time[] = "target_transfer_time"; static const char __pyx_k_return_pt_journeys_1to1[] = "return_pt_journeys_1to1"; static const char __pyx_k_PyPTRouter___reduce_cython[] = "PyPTRouter.__reduce_cython__"; static const char __pyx_k_PyPTRouter_construct_query[] = "PyPTRouter.construct_query"; +static const char __pyx_k_target_station_arrival_day[] = "target_station_arrival_day"; +static const char __pyx_k_target_station_arrival_time[] = "target_station_arrival_time"; static const char __pyx_k_PyPTRouter___setstate_cython[] = "PyPTRouter.__setstate_cython__"; +static const char __pyx_k_source_station_departure_day[] = "source_station_departure_day"; static const char __pyx_k_Expected_string_int_tuple_got[] = "Expected (string, int) tuple, got "; +static const char __pyx_k_source_station_departure_time[] = "source_station_departure_time"; static const char __pyx_k_return_fastest_pt_journey_1to1[] = "return_fastest_pt_journey_1to1"; static const char __pyx_k_No_value_specified_for_struct_at[] = "No value specified for struct attribute 'year'"; static const char __pyx_k_PyPTRouter_return_fastest_pt_jou[] = "PyPTRouter.return_fastest_pt_journey_1to1"; static const char __pyx_k_PyPTRouter_return_pt_journeys_1t[] = "PyPTRouter.return_pt_journeys_1to1"; static const char __pyx_k_RAPTOR_router_not_initialized_Pl[] = "RAPTOR router not initialized. Please initialize first."; static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; +static const char __pyx_k_source_station_departure_datetim[] = "source_station_departure_datetime"; static const char __pyx_k_No_value_specified_for_struct_at_2[] = "No value specified for struct attribute 'month'"; static const char __pyx_k_No_value_specified_for_struct_at_3[] = "No value specified for struct attribute 'day'"; static const char __pyx_k_No_value_specified_for_struct_at_4[] = "No value specified for struct attribute 'weekday'"; @@ -2573,9 +2576,9 @@ static const char __pyx_k_No_value_specified_for_struct_at_12[] = "No value spec /* #### Code section: decls ### */ static int __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_input_directory); /* proto */ static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ static PyObject *__pyx_tp_new_10PyPTRouter_PyPTRouter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ @@ -2656,8 +2659,6 @@ typedef struct { PyObject *__pyx_n_s__28; PyObject *__pyx_n_u_agency_name; PyObject *__pyx_n_s_append; - PyObject *__pyx_n_s_arrival_datetime; - PyObject *__pyx_n_u_arrival_day; PyObject *__pyx_n_u_arrival_time; PyObject *__pyx_n_s_asyncio_coroutines; PyObject *__pyx_n_s_cline_in_traceback; @@ -2667,7 +2668,6 @@ typedef struct { PyObject *__pyx_n_s_datetime; PyObject *__pyx_n_s_day; PyObject *__pyx_n_u_day; - PyObject *__pyx_n_u_departure_day; PyObject *__pyx_n_s_departure_time; PyObject *__pyx_n_u_departure_time; PyObject *__pyx_n_s_detailed; @@ -2719,18 +2719,24 @@ typedef struct { PyObject *__pyx_n_s_self; PyObject *__pyx_n_s_setstate; PyObject *__pyx_n_s_setstate_cython; + PyObject *__pyx_n_s_source_station_departure_datetim; + PyObject *__pyx_n_u_source_station_departure_day; + PyObject *__pyx_n_u_source_station_departure_time; PyObject *__pyx_n_u_source_transfer_time; + PyObject *__pyx_n_u_source_waiting_time; PyObject *__pyx_n_s_spec; PyObject *__pyx_n_s_src_vec; PyObject *__pyx_n_u_steps; PyObject *__pyx_kp_s_stringsource; + PyObject *__pyx_n_u_target_station_arrival_day; + PyObject *__pyx_n_u_target_station_arrival_time; + PyObject *__pyx_n_u_target_transfer_time; PyObject *__pyx_n_s_test; PyObject *__pyx_n_s_tgt_vec; PyObject *__pyx_n_u_to_stop_id; PyObject *__pyx_n_u_trip_id; PyObject *__pyx_n_u_trip_time; PyObject *__pyx_kp_u_utf_8; - PyObject *__pyx_n_u_waiting_time; PyObject *__pyx_n_u_walking; PyObject *__pyx_n_s_weekday; PyObject *__pyx_n_s_year; @@ -2836,8 +2842,6 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_n_s__28); Py_CLEAR(clear_module_state->__pyx_n_u_agency_name); Py_CLEAR(clear_module_state->__pyx_n_s_append); - Py_CLEAR(clear_module_state->__pyx_n_s_arrival_datetime); - Py_CLEAR(clear_module_state->__pyx_n_u_arrival_day); Py_CLEAR(clear_module_state->__pyx_n_u_arrival_time); Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); @@ -2847,7 +2851,6 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_n_s_datetime); Py_CLEAR(clear_module_state->__pyx_n_s_day); Py_CLEAR(clear_module_state->__pyx_n_u_day); - Py_CLEAR(clear_module_state->__pyx_n_u_departure_day); Py_CLEAR(clear_module_state->__pyx_n_s_departure_time); Py_CLEAR(clear_module_state->__pyx_n_u_departure_time); Py_CLEAR(clear_module_state->__pyx_n_s_detailed); @@ -2899,18 +2902,24 @@ static int __pyx_m_clear(PyObject *m) { Py_CLEAR(clear_module_state->__pyx_n_s_self); Py_CLEAR(clear_module_state->__pyx_n_s_setstate); Py_CLEAR(clear_module_state->__pyx_n_s_setstate_cython); + Py_CLEAR(clear_module_state->__pyx_n_s_source_station_departure_datetim); + Py_CLEAR(clear_module_state->__pyx_n_u_source_station_departure_day); + Py_CLEAR(clear_module_state->__pyx_n_u_source_station_departure_time); Py_CLEAR(clear_module_state->__pyx_n_u_source_transfer_time); + Py_CLEAR(clear_module_state->__pyx_n_u_source_waiting_time); Py_CLEAR(clear_module_state->__pyx_n_s_spec); Py_CLEAR(clear_module_state->__pyx_n_s_src_vec); Py_CLEAR(clear_module_state->__pyx_n_u_steps); Py_CLEAR(clear_module_state->__pyx_kp_s_stringsource); + Py_CLEAR(clear_module_state->__pyx_n_u_target_station_arrival_day); + Py_CLEAR(clear_module_state->__pyx_n_u_target_station_arrival_time); + Py_CLEAR(clear_module_state->__pyx_n_u_target_transfer_time); Py_CLEAR(clear_module_state->__pyx_n_s_test); Py_CLEAR(clear_module_state->__pyx_n_s_tgt_vec); Py_CLEAR(clear_module_state->__pyx_n_u_to_stop_id); Py_CLEAR(clear_module_state->__pyx_n_u_trip_id); Py_CLEAR(clear_module_state->__pyx_n_u_trip_time); Py_CLEAR(clear_module_state->__pyx_kp_u_utf_8); - Py_CLEAR(clear_module_state->__pyx_n_u_waiting_time); Py_CLEAR(clear_module_state->__pyx_n_u_walking); Py_CLEAR(clear_module_state->__pyx_n_s_weekday); Py_CLEAR(clear_module_state->__pyx_n_s_year); @@ -2994,8 +3003,6 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_n_s__28); Py_VISIT(traverse_module_state->__pyx_n_u_agency_name); Py_VISIT(traverse_module_state->__pyx_n_s_append); - Py_VISIT(traverse_module_state->__pyx_n_s_arrival_datetime); - Py_VISIT(traverse_module_state->__pyx_n_u_arrival_day); Py_VISIT(traverse_module_state->__pyx_n_u_arrival_time); Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); @@ -3005,7 +3012,6 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_n_s_datetime); Py_VISIT(traverse_module_state->__pyx_n_s_day); Py_VISIT(traverse_module_state->__pyx_n_u_day); - Py_VISIT(traverse_module_state->__pyx_n_u_departure_day); Py_VISIT(traverse_module_state->__pyx_n_s_departure_time); Py_VISIT(traverse_module_state->__pyx_n_u_departure_time); Py_VISIT(traverse_module_state->__pyx_n_s_detailed); @@ -3057,18 +3063,24 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(traverse_module_state->__pyx_n_s_self); Py_VISIT(traverse_module_state->__pyx_n_s_setstate); Py_VISIT(traverse_module_state->__pyx_n_s_setstate_cython); + Py_VISIT(traverse_module_state->__pyx_n_s_source_station_departure_datetim); + Py_VISIT(traverse_module_state->__pyx_n_u_source_station_departure_day); + Py_VISIT(traverse_module_state->__pyx_n_u_source_station_departure_time); Py_VISIT(traverse_module_state->__pyx_n_u_source_transfer_time); + Py_VISIT(traverse_module_state->__pyx_n_u_source_waiting_time); Py_VISIT(traverse_module_state->__pyx_n_s_spec); Py_VISIT(traverse_module_state->__pyx_n_s_src_vec); Py_VISIT(traverse_module_state->__pyx_n_u_steps); Py_VISIT(traverse_module_state->__pyx_kp_s_stringsource); + Py_VISIT(traverse_module_state->__pyx_n_u_target_station_arrival_day); + Py_VISIT(traverse_module_state->__pyx_n_u_target_station_arrival_time); + Py_VISIT(traverse_module_state->__pyx_n_u_target_transfer_time); Py_VISIT(traverse_module_state->__pyx_n_s_test); Py_VISIT(traverse_module_state->__pyx_n_s_tgt_vec); Py_VISIT(traverse_module_state->__pyx_n_u_to_stop_id); Py_VISIT(traverse_module_state->__pyx_n_u_trip_id); Py_VISIT(traverse_module_state->__pyx_n_u_trip_time); Py_VISIT(traverse_module_state->__pyx_kp_u_utf_8); - Py_VISIT(traverse_module_state->__pyx_n_u_waiting_time); Py_VISIT(traverse_module_state->__pyx_n_u_walking); Py_VISIT(traverse_module_state->__pyx_n_s_weekday); Py_VISIT(traverse_module_state->__pyx_n_s_year); @@ -3176,8 +3188,6 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_n_s__28 __pyx_mstate_global->__pyx_n_s__28 #define __pyx_n_u_agency_name __pyx_mstate_global->__pyx_n_u_agency_name #define __pyx_n_s_append __pyx_mstate_global->__pyx_n_s_append -#define __pyx_n_s_arrival_datetime __pyx_mstate_global->__pyx_n_s_arrival_datetime -#define __pyx_n_u_arrival_day __pyx_mstate_global->__pyx_n_u_arrival_day #define __pyx_n_u_arrival_time __pyx_mstate_global->__pyx_n_u_arrival_time #define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines #define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback @@ -3187,7 +3197,6 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_n_s_datetime __pyx_mstate_global->__pyx_n_s_datetime #define __pyx_n_s_day __pyx_mstate_global->__pyx_n_s_day #define __pyx_n_u_day __pyx_mstate_global->__pyx_n_u_day -#define __pyx_n_u_departure_day __pyx_mstate_global->__pyx_n_u_departure_day #define __pyx_n_s_departure_time __pyx_mstate_global->__pyx_n_s_departure_time #define __pyx_n_u_departure_time __pyx_mstate_global->__pyx_n_u_departure_time #define __pyx_n_s_detailed __pyx_mstate_global->__pyx_n_s_detailed @@ -3239,18 +3248,24 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { #define __pyx_n_s_self __pyx_mstate_global->__pyx_n_s_self #define __pyx_n_s_setstate __pyx_mstate_global->__pyx_n_s_setstate #define __pyx_n_s_setstate_cython __pyx_mstate_global->__pyx_n_s_setstate_cython +#define __pyx_n_s_source_station_departure_datetim __pyx_mstate_global->__pyx_n_s_source_station_departure_datetim +#define __pyx_n_u_source_station_departure_day __pyx_mstate_global->__pyx_n_u_source_station_departure_day +#define __pyx_n_u_source_station_departure_time __pyx_mstate_global->__pyx_n_u_source_station_departure_time #define __pyx_n_u_source_transfer_time __pyx_mstate_global->__pyx_n_u_source_transfer_time +#define __pyx_n_u_source_waiting_time __pyx_mstate_global->__pyx_n_u_source_waiting_time #define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec #define __pyx_n_s_src_vec __pyx_mstate_global->__pyx_n_s_src_vec #define __pyx_n_u_steps __pyx_mstate_global->__pyx_n_u_steps #define __pyx_kp_s_stringsource __pyx_mstate_global->__pyx_kp_s_stringsource +#define __pyx_n_u_target_station_arrival_day __pyx_mstate_global->__pyx_n_u_target_station_arrival_day +#define __pyx_n_u_target_station_arrival_time __pyx_mstate_global->__pyx_n_u_target_station_arrival_time +#define __pyx_n_u_target_transfer_time __pyx_mstate_global->__pyx_n_u_target_transfer_time #define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test #define __pyx_n_s_tgt_vec __pyx_mstate_global->__pyx_n_s_tgt_vec #define __pyx_n_u_to_stop_id __pyx_mstate_global->__pyx_n_u_to_stop_id #define __pyx_n_u_trip_id __pyx_mstate_global->__pyx_n_u_trip_id #define __pyx_n_u_trip_time __pyx_mstate_global->__pyx_n_u_trip_time #define __pyx_kp_u_utf_8 __pyx_mstate_global->__pyx_kp_u_utf_8 -#define __pyx_n_u_waiting_time __pyx_mstate_global->__pyx_n_u_waiting_time #define __pyx_n_u_walking __pyx_mstate_global->__pyx_n_u_walking #define __pyx_n_s_weekday __pyx_mstate_global->__pyx_n_s_weekday #define __pyx_n_s_year __pyx_mstate_global->__pyx_n_s_year @@ -5852,7 +5867,7 @@ static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10P * * def construct_query( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* Python wrapper */ @@ -5863,7 +5878,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query, "PyPTRouter.construct_query(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1)\nConstruct query information.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed\n\n Returns:\n query (Query)\n "); +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query, "PyPTRouter.construct_query(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1)\nConstruct query information.\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed\n\n Returns:\n query (Query)\n "); static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query = {"construct_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query}; static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query(PyObject *__pyx_v_self, #if CYTHON_METH_FASTCALL @@ -5872,7 +5887,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ) { - PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_source_station_departure_datetime = 0; PyObject *__pyx_v_included_sources = 0; PyObject *__pyx_v_included_targets = 0; int __pyx_v_max_transfers; @@ -5896,7 +5911,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,0}; + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,0}; if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { @@ -5914,7 +5929,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); switch (__pyx_nargs) { case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); kw_args--; } @@ -5963,7 +5978,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds default: goto __pyx_L5_argtuple_error; } } - __pyx_v_arrival_datetime = values[0]; + __pyx_v_source_station_departure_datetime = values[0]; __pyx_v_included_sources = ((PyObject*)values[1]); __pyx_v_included_targets = ((PyObject*)values[2]); if (values[3]) { @@ -5990,7 +6005,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 74, __pyx_L1_error) if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 74, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers); + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers); /* function exit code */ goto __pyx_L0; @@ -6007,7 +6022,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds return __pyx_r; } -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers) { +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers) { int __pyx_v_year; int __pyx_v_month; int __pyx_v_day; @@ -6046,11 +6061,11 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUS /* "PyPTRouter.pyx":88 * """ * # Calculate day of week using Python's datetime - * cdef int year = arrival_datetime.year # <<<<<<<<<<<<<< - * cdef int month = arrival_datetime.month - * cdef int day = arrival_datetime.day + * cdef int year = source_station_departure_datetime.year # <<<<<<<<<<<<<< + * cdef int month = source_station_departure_datetime.month + * cdef int day = source_station_departure_datetime.day */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_year); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_year); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -6058,38 +6073,38 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUS /* "PyPTRouter.pyx":89 * # Calculate day of week using Python's datetime - * cdef int year = arrival_datetime.year - * cdef int month = arrival_datetime.month # <<<<<<<<<<<<<< - * cdef int day = arrival_datetime.day - * cdef int weekday = arrival_datetime.weekday() + * cdef int year = source_station_departure_datetime.year + * cdef int month = source_station_departure_datetime.month # <<<<<<<<<<<<<< + * cdef int day = source_station_departure_datetime.day + * cdef int weekday = source_station_departure_datetime.weekday() */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_month); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_month); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_month = __pyx_t_2; /* "PyPTRouter.pyx":90 - * cdef int year = arrival_datetime.year - * cdef int month = arrival_datetime.month - * cdef int day = arrival_datetime.day # <<<<<<<<<<<<<< - * cdef int weekday = arrival_datetime.weekday() - * cdef int hours = arrival_datetime.hour + * cdef int year = source_station_departure_datetime.year + * cdef int month = source_station_departure_datetime.month + * cdef int day = source_station_departure_datetime.day # <<<<<<<<<<<<<< + * cdef int weekday = source_station_departure_datetime.weekday() + * cdef int hours = source_station_departure_datetime.hour */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_day); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_day); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_day = __pyx_t_2; /* "PyPTRouter.pyx":91 - * cdef int month = arrival_datetime.month - * cdef int day = arrival_datetime.day - * cdef int weekday = arrival_datetime.weekday() # <<<<<<<<<<<<<< - * cdef int hours = arrival_datetime.hour - * cdef int minutes = arrival_datetime.minute + * cdef int month = source_station_departure_datetime.month + * cdef int day = source_station_departure_datetime.day + * cdef int weekday = source_station_departure_datetime.weekday() # <<<<<<<<<<<<<< + * cdef int hours = source_station_departure_datetime.hour + * cdef int minutes = source_station_departure_datetime.minute */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_weekday); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_weekday); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = NULL; __pyx_t_5 = 0; @@ -6118,39 +6133,39 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUS __pyx_v_weekday = __pyx_t_2; /* "PyPTRouter.pyx":92 - * cdef int day = arrival_datetime.day - * cdef int weekday = arrival_datetime.weekday() - * cdef int hours = arrival_datetime.hour # <<<<<<<<<<<<<< - * cdef int minutes = arrival_datetime.minute - * cdef int seconds = arrival_datetime.second + * cdef int day = source_station_departure_datetime.day + * cdef int weekday = source_station_departure_datetime.weekday() + * cdef int hours = source_station_departure_datetime.hour # <<<<<<<<<<<<<< + * cdef int minutes = source_station_departure_datetime.minute + * cdef int seconds = source_station_departure_datetime.second */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_hour); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_hour); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_hours = __pyx_t_2; /* "PyPTRouter.pyx":93 - * cdef int weekday = arrival_datetime.weekday() - * cdef int hours = arrival_datetime.hour - * cdef int minutes = arrival_datetime.minute # <<<<<<<<<<<<<< - * cdef int seconds = arrival_datetime.second + * cdef int weekday = source_station_departure_datetime.weekday() + * cdef int hours = source_station_departure_datetime.hour + * cdef int minutes = source_station_departure_datetime.minute # <<<<<<<<<<<<<< + * cdef int seconds = source_station_departure_datetime.second * */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_minute); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_minute); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_minutes = __pyx_t_2; /* "PyPTRouter.pyx":94 - * cdef int hours = arrival_datetime.hour - * cdef int minutes = arrival_datetime.minute - * cdef int seconds = arrival_datetime.second # <<<<<<<<<<<<<< + * cdef int hours = source_station_departure_datetime.hour + * cdef int minutes = source_station_departure_datetime.minute + * cdef int seconds = source_station_departure_datetime.second # <<<<<<<<<<<<<< * * # Create date, time objects for C++ */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_arrival_datetime, __pyx_n_s_second); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_second); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -6574,7 +6589,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUS * * def construct_query( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* function exit code */ @@ -6598,7 +6613,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUS * * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* Python wrapper */ @@ -6609,7 +6624,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1, "PyPTRouter.return_pt_journeys_1to1(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the best public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1, "PyPTRouter.return_pt_journeys_1to1(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the best public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1 = {"return_pt_journeys_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1}; static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1(PyObject *__pyx_v_self, #if CYTHON_METH_FASTCALL @@ -6618,7 +6633,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ) { - PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_source_station_departure_datetime = 0; PyObject *__pyx_v_included_sources = 0; PyObject *__pyx_v_included_targets = 0; int __pyx_v_max_transfers; @@ -6643,7 +6658,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { @@ -6663,7 +6678,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); switch (__pyx_nargs) { case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); kw_args--; } @@ -6721,7 +6736,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds default: goto __pyx_L5_argtuple_error; } } - __pyx_v_arrival_datetime = values[0]; + __pyx_v_source_station_departure_datetime = values[0]; __pyx_v_included_sources = ((PyObject*)values[1]); __pyx_v_included_targets = ((PyObject*)values[2]); if (values[3]) { @@ -6734,7 +6749,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds } else { /* "PyPTRouter.pyx":125 - * arrival_datetime, + * source_station_departure_datetime, * list included_sources, list included_targets, int max_transfers=-1, * bool detailed=False, # <<<<<<<<<<<<<< * ): @@ -6761,14 +6776,14 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 124, __pyx_L1_error) if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 124, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); /* "PyPTRouter.pyx":121 * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) * * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* function exit code */ @@ -6786,7 +6801,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds return __pyx_r; } -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { PyObject *__pyx_v_query = NULL; std::vector __pyx_v_journeys; PyObject *__pyx_v_journeys_list = NULL; @@ -6846,7 +6861,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(str * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") * * query = self.construct_query( # <<<<<<<<<<<<<< - * arrival_datetime, included_sources, included_targets, max_transfers, + * source_station_departure_datetime, included_sources, included_targets, max_transfers, * ) */ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) @@ -6855,7 +6870,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(str /* "PyPTRouter.pyx":148 * * query = self.construct_query( - * arrival_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< + * source_station_departure_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< * ) * */ @@ -6876,7 +6891,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(str } #endif { - PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; + PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; @@ -6999,7 +7014,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(str * * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* function exit code */ @@ -7024,7 +7039,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(str * * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* Python wrapper */ @@ -7035,7 +7050,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1, "PyPTRouter.return_fastest_pt_journey_1to1(self, arrival_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the fastest public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n arrival_datetime (datetime): Arrival datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); +PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1, "PyPTRouter.return_fastest_pt_journey_1to1(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the fastest public transport journey from source station to target station\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1 = {"return_fastest_pt_journey_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1}; static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1(PyObject *__pyx_v_self, #if CYTHON_METH_FASTCALL @@ -7044,7 +7059,7 @@ PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds PyObject *__pyx_args, PyObject *__pyx_kwds #endif ) { - PyObject *__pyx_v_arrival_datetime = 0; + PyObject *__pyx_v_source_station_departure_datetime = 0; PyObject *__pyx_v_included_sources = 0; PyObject *__pyx_v_included_targets = 0; int __pyx_v_max_transfers; @@ -7069,7 +7084,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arrival_datetime,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; + PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { @@ -7089,7 +7104,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); switch (__pyx_nargs) { case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_arrival_datetime)) != 0)) { + if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); kw_args--; } @@ -7147,7 +7162,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds default: goto __pyx_L5_argtuple_error; } } - __pyx_v_arrival_datetime = values[0]; + __pyx_v_source_station_departure_datetime = values[0]; __pyx_v_included_sources = ((PyObject*)values[1]); __pyx_v_included_targets = ((PyObject*)values[2]); if (values[3]) { @@ -7160,11 +7175,11 @@ PyObject *__pyx_args, PyObject *__pyx_kwds } else { /* "PyPTRouter.pyx":171 - * arrival_datetime, + * source_station_departure_datetime, * list included_sources, list included_targets, int max_transfers=-1, * bool detailed=False, # <<<<<<<<<<<<<< * ): - * """Find the fastest public transport journey from source to target + * """Find the fastest public transport journey from source station to target station */ __pyx_v_detailed = ((bool)0); } @@ -7187,14 +7202,14 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 170, __pyx_L1_error) if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 170, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); + __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); /* "PyPTRouter.pyx":167 * return journeys_list * * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* function exit code */ @@ -7212,7 +7227,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds return __pyx_r; } -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_arrival_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { +static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { PyObject *__pyx_v_query = NULL; std::optional __pyx_v_journey_opt; struct Journey __pyx_v_journey; @@ -7232,7 +7247,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 int __pyx_clineno = 0; __Pyx_RefNannySetupContext("return_fastest_pt_journey_1to1", 1); - /* "PyPTRouter.pyx":190 + /* "PyPTRouter.pyx":187 * - duration: Total journey duration in seconds * """ * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< @@ -7242,20 +7257,20 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 __pyx_t_1 = (__pyx_v_self->raptor_ptr == NULL); if (unlikely(__pyx_t_1)) { - /* "PyPTRouter.pyx":191 + /* "PyPTRouter.pyx":188 * """ * if self.raptor_ptr == NULL: * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< * * query = self.construct_query( */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 191, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 188, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_Raise(__pyx_t_2, 0, 0, 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 191, __pyx_L1_error) + __PYX_ERR(0, 188, __pyx_L1_error) - /* "PyPTRouter.pyx":190 + /* "PyPTRouter.pyx":187 * - duration: Total journey duration in seconds * """ * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< @@ -7264,24 +7279,24 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 */ } - /* "PyPTRouter.pyx":193 + /* "PyPTRouter.pyx":190 * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") * * query = self.construct_query( # <<<<<<<<<<<<<< - * arrival_datetime, included_sources, included_targets, max_transfers, + * source_station_departure_datetime, included_sources, included_targets, max_transfers, * ) */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 193, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 190, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - /* "PyPTRouter.pyx":194 + /* "PyPTRouter.pyx":191 * * query = self.construct_query( - * arrival_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< + * source_station_departure_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< * ) * */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 194, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 191, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = NULL; __pyx_t_6 = 0; @@ -7298,28 +7313,28 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 } #endif { - PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_arrival_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; + PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error) + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 190, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_v_query = __pyx_t_2; __pyx_t_2 = 0; - /* "PyPTRouter.pyx":198 + /* "PyPTRouter.pyx":195 * * # Set query and find journeys * self.raptor_ptr.setQuery(query) # <<<<<<<<<<<<<< * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() * */ - __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 198, __pyx_L1_error) + __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L1_error) __pyx_v_self->raptor_ptr->setQuery(__pyx_t_7); - /* "PyPTRouter.pyx":199 + /* "PyPTRouter.pyx":196 * # Set query and find journeys * self.raptor_ptr.setQuery(query) * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() # <<<<<<<<<<<<<< @@ -7328,7 +7343,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 */ __pyx_v_journey_opt = __pyx_v_self->raptor_ptr->findOptimalJourney(); - /* "PyPTRouter.pyx":202 + /* "PyPTRouter.pyx":199 * * # Check if journey was found * if not journey_opt.has_value(): # <<<<<<<<<<<<<< @@ -7338,7 +7353,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 __pyx_t_1 = (!(__pyx_v_journey_opt.has_value() != 0)); if (__pyx_t_1) { - /* "PyPTRouter.pyx":203 + /* "PyPTRouter.pyx":200 * # Check if journey was found * if not journey_opt.has_value(): * return None # <<<<<<<<<<<<<< @@ -7349,7 +7364,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; - /* "PyPTRouter.pyx":202 + /* "PyPTRouter.pyx":199 * * # Check if journey was found * if not journey_opt.has_value(): # <<<<<<<<<<<<<< @@ -7358,7 +7373,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 */ } - /* "PyPTRouter.pyx":206 + /* "PyPTRouter.pyx":203 * * # Get the actual journey from optional * cdef Journey journey = journey_opt.value() # <<<<<<<<<<<<<< @@ -7369,23 +7384,23 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 __pyx_t_8 = __pyx_v_journey_opt.value(); } catch(...) { __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 206, __pyx_L1_error) + __PYX_ERR(0, 203, __pyx_L1_error) } __pyx_v_journey = __pyx_t_8; - /* "PyPTRouter.pyx":209 + /* "PyPTRouter.pyx":206 * * # Convert journey to Python dictionary * journey_dict = self._convert_journey_to_dict(journey, detailed) # <<<<<<<<<<<<<< * * return journey_dict */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, __pyx_v_journey, __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 209, __pyx_L1_error) + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, __pyx_v_journey, __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 206, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_v_journey_dict = __pyx_t_2; __pyx_t_2 = 0; - /* "PyPTRouter.pyx":211 + /* "PyPTRouter.pyx":208 * journey_dict = self._convert_journey_to_dict(journey, detailed) * * return journey_dict # <<<<<<<<<<<<<< @@ -7402,7 +7417,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 * * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ /* function exit code */ @@ -7421,7 +7436,7 @@ static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1 return __pyx_r; } -/* "PyPTRouter.pyx":213 +/* "PyPTRouter.pyx":210 * return journey_dict * * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< @@ -7447,131 +7462,143 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_convert_journey_to_dict", 1); - /* "PyPTRouter.pyx":228 + /* "PyPTRouter.pyx":225 * journey_dict = { * # Overall journey information * "duration": journey.duration, # <<<<<<<<<<<<<< - * "source_transfer_time": journey.source_transfer_time, - * "waiting_time": journey.waiting_time, + * "trip_time": journey.trip_time, + * "num_transfers": journey.num_transfers, */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 228, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.duration); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 228, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.duration); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_duration, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_duration, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":229 + /* "PyPTRouter.pyx":226 * # Overall journey information * "duration": journey.duration, - * "source_transfer_time": journey.source_transfer_time, # <<<<<<<<<<<<<< - * "waiting_time": journey.waiting_time, - * "trip_time": journey.trip_time, + * "trip_time": journey.trip_time, # <<<<<<<<<<<<<< + * "num_transfers": journey.num_transfers, + * */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 229, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.trip_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 226, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_trip_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":230 + /* "PyPTRouter.pyx":227 * "duration": journey.duration, - * "source_transfer_time": journey.source_transfer_time, - * "waiting_time": journey.waiting_time, # <<<<<<<<<<<<<< * "trip_time": journey.trip_time, - * "num_transfers": journey.num_transfers, + * "num_transfers": journey.num_transfers, # <<<<<<<<<<<<<< + * + * # Departure information + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.num_transfers); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 227, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_num_transfers, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "PyPTRouter.pyx":230 + * + * # Departure information + * "source_transfer_time": journey.source_transfer_time, # <<<<<<<<<<<<<< + * "source_waiting_time": journey.source_waiting_time, + * "source_station_departure_time": journey.source_station_departure_secs, */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.waiting_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_waiting_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "PyPTRouter.pyx":231 + * # Departure information * "source_transfer_time": journey.source_transfer_time, - * "waiting_time": journey.waiting_time, - * "trip_time": journey.trip_time, # <<<<<<<<<<<<<< - * "num_transfers": journey.num_transfers, - * + * "source_waiting_time": journey.source_waiting_time, # <<<<<<<<<<<<<< + * "source_station_departure_time": journey.source_station_departure_secs, + * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.trip_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_waiting_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_trip_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_waiting_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "PyPTRouter.pyx":232 - * "waiting_time": journey.waiting_time, - * "trip_time": journey.trip_time, - * "num_transfers": journey.num_transfers, # <<<<<<<<<<<<<< + * "source_transfer_time": journey.source_transfer_time, + * "source_waiting_time": journey.source_waiting_time, + * "source_station_departure_time": journey.source_station_departure_secs, # <<<<<<<<<<<<<< + * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), * - * # Departure information */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.num_transfers); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_station_departure_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_num_transfers, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_station_departure_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":235 - * - * # Departure information - * "departure_time": journey.departure_secs, # <<<<<<<<<<<<<< - * "departure_day": self._day_to_str(journey.departure_day), + /* "PyPTRouter.pyx":233 + * "source_waiting_time": journey.source_waiting_time, + * "source_station_departure_time": journey.source_station_departure_secs, + * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), # <<<<<<<<<<<<<< * + * # Arrival information */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.departure_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 235, __pyx_L1_error) + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.source_station_departure_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_departure_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_station_departure_day, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "PyPTRouter.pyx":236 - * # Departure information - * "departure_time": journey.departure_secs, - * "departure_day": self._day_to_str(journey.departure_day), # <<<<<<<<<<<<<< * * # Arrival information + * "target_station_arrival_time": journey.target_station_arrival_secs, # <<<<<<<<<<<<<< + * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), + * "target_transfer_time": journey.target_transfer_time, */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.departure_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 236, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.target_station_arrival_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 236, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_departure_day, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_station_arrival_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":239 - * + /* "PyPTRouter.pyx":237 * # Arrival information - * "arrival_time": journey.arrival_secs, # <<<<<<<<<<<<<< - * "arrival_day": self._day_to_str(journey.arrival_day), + * "target_station_arrival_time": journey.target_station_arrival_secs, + * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), # <<<<<<<<<<<<<< + * "target_transfer_time": journey.target_transfer_time, * */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.arrival_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 239, __pyx_L1_error) + __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.target_station_arrival_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_arrival_time, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_station_arrival_day, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":240 - * # Arrival information - * "arrival_time": journey.arrival_secs, - * "arrival_day": self._day_to_str(journey.arrival_day), # <<<<<<<<<<<<<< + /* "PyPTRouter.pyx":238 + * "target_station_arrival_time": journey.target_station_arrival_secs, + * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), + * "target_transfer_time": journey.target_transfer_time, # <<<<<<<<<<<<<< * * # Journey steps */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.arrival_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 240, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.target_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_arrival_day, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":243 + /* "PyPTRouter.pyx":241 * * # Journey steps * "steps": [] # <<<<<<<<<<<<<< * } * */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 243, __pyx_L1_error) + __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 241, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_steps, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_steps, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_journey_dict = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; - /* "PyPTRouter.pyx":246 + /* "PyPTRouter.pyx":244 * } * * if not detailed: # <<<<<<<<<<<<<< @@ -7581,7 +7608,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru __pyx_t_3 = (!(__pyx_v_detailed != 0)); if (__pyx_t_3) { - /* "PyPTRouter.pyx":247 + /* "PyPTRouter.pyx":245 * * if not detailed: * return journey_dict # <<<<<<<<<<<<<< @@ -7593,7 +7620,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru __pyx_r = __pyx_v_journey_dict; goto __pyx_L0; - /* "PyPTRouter.pyx":246 + /* "PyPTRouter.pyx":244 * } * * if not detailed: # <<<<<<<<<<<<<< @@ -7602,7 +7629,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru */ } - /* "PyPTRouter.pyx":250 + /* "PyPTRouter.pyx":248 * * # Convert each journey step * for i in range(journey.steps.size()): # <<<<<<<<<<<<<< @@ -7614,32 +7641,32 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { __pyx_v_i = __pyx_t_6; - /* "PyPTRouter.pyx":251 + /* "PyPTRouter.pyx":249 * # Convert each journey step * for i in range(journey.steps.size()): * step_dict = self._convert_journey_step(journey.steps[i]) # <<<<<<<<<<<<<< * journey_dict["steps"].append(step_dict) * */ - __pyx_t_1 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_step(__pyx_v_self, (__pyx_v_journey.steps[__pyx_v_i])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error) + __pyx_t_1 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_step(__pyx_v_self, (__pyx_v_journey.steps[__pyx_v_i])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 249, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XDECREF_SET(__pyx_v_step_dict, __pyx_t_1); __pyx_t_1 = 0; - /* "PyPTRouter.pyx":252 + /* "PyPTRouter.pyx":250 * for i in range(journey.steps.size()): * step_dict = self._convert_journey_step(journey.steps[i]) * journey_dict["steps"].append(step_dict) # <<<<<<<<<<<<<< * * return journey_dict */ - __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_journey_dict, __pyx_n_u_steps); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 252, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_journey_dict, __pyx_n_u_steps); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 250, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_v_step_dict); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 252, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_v_step_dict); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 250, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } - /* "PyPTRouter.pyx":254 + /* "PyPTRouter.pyx":252 * journey_dict["steps"].append(step_dict) * * return journey_dict # <<<<<<<<<<<<<< @@ -7651,7 +7678,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru __pyx_r = __pyx_v_journey_dict; goto __pyx_L0; - /* "PyPTRouter.pyx":213 + /* "PyPTRouter.pyx":210 * return journey_dict * * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< @@ -7673,7 +7700,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(stru return __pyx_r; } -/* "PyPTRouter.pyx":256 +/* "PyPTRouter.pyx":254 * return journey_dict * * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< @@ -7687,7 +7714,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str int __pyx_t_1; __Pyx_RefNannySetupContext("_day_to_str", 1); - /* "PyPTRouter.pyx":258 + /* "PyPTRouter.pyx":256 * cdef str _day_to_str(self, Day day): * """Convert Day enum to string""" * if day == Day.CurrentDay: # <<<<<<<<<<<<<< @@ -7697,7 +7724,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str __pyx_t_1 = (__pyx_v_day == Day::CurrentDay); if (__pyx_t_1) { - /* "PyPTRouter.pyx":259 + /* "PyPTRouter.pyx":257 * """Convert Day enum to string""" * if day == Day.CurrentDay: * return "current_day" # <<<<<<<<<<<<<< @@ -7709,7 +7736,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str __pyx_r = __pyx_n_u_current_day; goto __pyx_L0; - /* "PyPTRouter.pyx":258 + /* "PyPTRouter.pyx":256 * cdef str _day_to_str(self, Day day): * """Convert Day enum to string""" * if day == Day.CurrentDay: # <<<<<<<<<<<<<< @@ -7718,7 +7745,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str */ } - /* "PyPTRouter.pyx":261 + /* "PyPTRouter.pyx":259 * return "current_day" * else: * return "next_day" # <<<<<<<<<<<<<< @@ -7732,7 +7759,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str goto __pyx_L0; } - /* "PyPTRouter.pyx":256 + /* "PyPTRouter.pyx":254 * return journey_dict * * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< @@ -7747,7 +7774,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED str return __pyx_r; } -/* "PyPTRouter.pyx":263 +/* "PyPTRouter.pyx":261 * return "next_day" * * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< @@ -7771,7 +7798,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct int __pyx_clineno = 0; __Pyx_RefNannySetupContext("_convert_journey_step", 1); - /* "PyPTRouter.pyx":266 + /* "PyPTRouter.pyx":264 * """Convert a JourneyStep to Python dictionary""" * * cdef string stop_id_str = string(b"stop_id") # <<<<<<<<<<<<<< @@ -7782,87 +7809,87 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_t_1 = std::string(((char const *)"stop_id")); } catch(...) { __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 266, __pyx_L1_error) + __PYX_ERR(0, 264, __pyx_L1_error) } __pyx_v_stop_id_str = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_1); - /* "PyPTRouter.pyx":270 + /* "PyPTRouter.pyx":268 * step_dict = { * # Basic information * "duration": step.duration, # <<<<<<<<<<<<<< * * # Time information */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 270, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.duration); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 270, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.duration); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_duration, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_duration, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "PyPTRouter.pyx":273 + /* "PyPTRouter.pyx":271 * * # Time information * "departure_time": step.departure_secs, # <<<<<<<<<<<<<< * "arrival_time": step.arrival_secs, * "day": self._day_to_str(step.day), */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.departure_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 273, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.departure_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 271, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "PyPTRouter.pyx":274 + /* "PyPTRouter.pyx":272 * # Time information * "departure_time": step.departure_secs, * "arrival_time": step.arrival_secs, # <<<<<<<<<<<<<< * "day": self._day_to_str(step.day), * */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.arrival_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 274, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.arrival_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 272, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_arrival_time, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_arrival_time, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "PyPTRouter.pyx":275 + /* "PyPTRouter.pyx":273 * "departure_time": step.departure_secs, * "arrival_time": step.arrival_secs, * "day": self._day_to_str(step.day), # <<<<<<<<<<<<<< * * # Stop information */ - __pyx_t_3 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_step.day); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 275, __pyx_L1_error) + __pyx_t_3 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_step.day); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 273, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_day, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_day, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "PyPTRouter.pyx":278 + /* "PyPTRouter.pyx":276 * * # Stop information * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), * } */ - __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.src_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 278, __pyx_L1_error) + __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.src_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_from_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_from_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "PyPTRouter.pyx":279 + /* "PyPTRouter.pyx":277 * # Stop information * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< * } * */ - __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.dest_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 279, __pyx_L1_error) + __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.dest_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 277, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_to_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 270, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_to_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_step_dict = ((PyObject*)__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":283 + /* "PyPTRouter.pyx":281 * * # Handle optional fields * if step.trip_id.has_value(): # <<<<<<<<<<<<<< @@ -7872,7 +7899,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_t_4 = (__pyx_v_step.trip_id.has_value() != 0); if (__pyx_t_4) { - /* "PyPTRouter.pyx":284 + /* "PyPTRouter.pyx":282 * # Handle optional fields * if step.trip_id.has_value(): * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') # <<<<<<<<<<<<<< @@ -7883,14 +7910,14 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_t_5 = __pyx_v_step.trip_id.value(); } catch(...) { __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 284, __pyx_L1_error) + __PYX_ERR(0, 282, __pyx_L1_error) } - __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_5, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 284, __pyx_L1_error) + __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_5, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 282, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_t_2) < 0))) __PYX_ERR(0, 284, __pyx_L1_error) + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_t_2) < 0))) __PYX_ERR(0, 282, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":283 + /* "PyPTRouter.pyx":281 * * # Handle optional fields * if step.trip_id.has_value(): # <<<<<<<<<<<<<< @@ -7900,7 +7927,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct goto __pyx_L3; } - /* "PyPTRouter.pyx":286 + /* "PyPTRouter.pyx":284 * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') * else: * step_dict["trip_id"] = "walking" # <<<<<<<<<<<<<< @@ -7908,11 +7935,11 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct * if step.agency_name.has_value(): */ /*else*/ { - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_n_u_walking) < 0))) __PYX_ERR(0, 286, __pyx_L1_error) + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_n_u_walking) < 0))) __PYX_ERR(0, 284, __pyx_L1_error) } __pyx_L3:; - /* "PyPTRouter.pyx":288 + /* "PyPTRouter.pyx":286 * step_dict["trip_id"] = "walking" * * if step.agency_name.has_value(): # <<<<<<<<<<<<<< @@ -7922,7 +7949,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_t_4 = (__pyx_v_step.agency_name.has_value() != 0); if (__pyx_t_4) { - /* "PyPTRouter.pyx":289 + /* "PyPTRouter.pyx":287 * * if step.agency_name.has_value(): * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') # <<<<<<<<<<<<<< @@ -7933,14 +7960,14 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_t_6 = __pyx_v_step.agency_name.value(); } catch(...) { __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 289, __pyx_L1_error) + __PYX_ERR(0, 287, __pyx_L1_error) } - __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_6, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 289, __pyx_L1_error) + __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_6, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 287, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_t_2) < 0))) __PYX_ERR(0, 289, __pyx_L1_error) + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_t_2) < 0))) __PYX_ERR(0, 287, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "PyPTRouter.pyx":288 + /* "PyPTRouter.pyx":286 * step_dict["trip_id"] = "walking" * * if step.agency_name.has_value(): # <<<<<<<<<<<<<< @@ -7950,7 +7977,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct goto __pyx_L4; } - /* "PyPTRouter.pyx":291 + /* "PyPTRouter.pyx":289 * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') * else: * step_dict["agency_name"] = "Unknown" # <<<<<<<<<<<<<< @@ -7958,11 +7985,11 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct * return step_dict */ /*else*/ { - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_n_u_Unknown) < 0))) __PYX_ERR(0, 291, __pyx_L1_error) + if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_n_u_Unknown) < 0))) __PYX_ERR(0, 289, __pyx_L1_error) } __pyx_L4:; - /* "PyPTRouter.pyx":293 + /* "PyPTRouter.pyx":291 * step_dict["agency_name"] = "Unknown" * * return step_dict # <<<<<<<<<<<<<< @@ -7972,7 +7999,7 @@ static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_r = __pyx_v_step_dict; goto __pyx_L0; - /* "PyPTRouter.pyx":263 + /* "PyPTRouter.pyx":261 * return "next_day" * * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< @@ -8416,8 +8443,6 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_n_s__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 1, 1}, {&__pyx_n_u_agency_name, __pyx_k_agency_name, sizeof(__pyx_k_agency_name), 0, 1, 0, 1}, {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1}, - {&__pyx_n_s_arrival_datetime, __pyx_k_arrival_datetime, sizeof(__pyx_k_arrival_datetime), 0, 0, 1, 1}, - {&__pyx_n_u_arrival_day, __pyx_k_arrival_day, sizeof(__pyx_k_arrival_day), 0, 1, 0, 1}, {&__pyx_n_u_arrival_time, __pyx_k_arrival_time, sizeof(__pyx_k_arrival_time), 0, 1, 0, 1}, {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, @@ -8427,7 +8452,6 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_n_s_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 0, 1, 1}, {&__pyx_n_s_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 0, 1, 1}, {&__pyx_n_u_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 1, 0, 1}, - {&__pyx_n_u_departure_day, __pyx_k_departure_day, sizeof(__pyx_k_departure_day), 0, 1, 0, 1}, {&__pyx_n_s_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 0, 1, 1}, {&__pyx_n_u_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 1, 0, 1}, {&__pyx_n_s_detailed, __pyx_k_detailed, sizeof(__pyx_k_detailed), 0, 0, 1, 1}, @@ -8479,18 +8503,24 @@ static int __Pyx_CreateStringTabAndInitStrings(void) { {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_source_station_departure_datetim, __pyx_k_source_station_departure_datetim, sizeof(__pyx_k_source_station_departure_datetim), 0, 0, 1, 1}, + {&__pyx_n_u_source_station_departure_day, __pyx_k_source_station_departure_day, sizeof(__pyx_k_source_station_departure_day), 0, 1, 0, 1}, + {&__pyx_n_u_source_station_departure_time, __pyx_k_source_station_departure_time, sizeof(__pyx_k_source_station_departure_time), 0, 1, 0, 1}, {&__pyx_n_u_source_transfer_time, __pyx_k_source_transfer_time, sizeof(__pyx_k_source_transfer_time), 0, 1, 0, 1}, + {&__pyx_n_u_source_waiting_time, __pyx_k_source_waiting_time, sizeof(__pyx_k_source_waiting_time), 0, 1, 0, 1}, {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, {&__pyx_n_s_src_vec, __pyx_k_src_vec, sizeof(__pyx_k_src_vec), 0, 0, 1, 1}, {&__pyx_n_u_steps, __pyx_k_steps, sizeof(__pyx_k_steps), 0, 1, 0, 1}, {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_u_target_station_arrival_day, __pyx_k_target_station_arrival_day, sizeof(__pyx_k_target_station_arrival_day), 0, 1, 0, 1}, + {&__pyx_n_u_target_station_arrival_time, __pyx_k_target_station_arrival_time, sizeof(__pyx_k_target_station_arrival_time), 0, 1, 0, 1}, + {&__pyx_n_u_target_transfer_time, __pyx_k_target_transfer_time, sizeof(__pyx_k_target_transfer_time), 0, 1, 0, 1}, {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, {&__pyx_n_s_tgt_vec, __pyx_k_tgt_vec, sizeof(__pyx_k_tgt_vec), 0, 0, 1, 1}, {&__pyx_n_u_to_stop_id, __pyx_k_to_stop_id, sizeof(__pyx_k_to_stop_id), 0, 1, 0, 1}, {&__pyx_n_u_trip_id, __pyx_k_trip_id, sizeof(__pyx_k_trip_id), 0, 1, 0, 1}, {&__pyx_n_u_trip_time, __pyx_k_trip_time, sizeof(__pyx_k_trip_time), 0, 1, 0, 1}, {&__pyx_kp_u_utf_8, __pyx_k_utf_8, sizeof(__pyx_k_utf_8), 0, 1, 0, 0}, - {&__pyx_n_u_waiting_time, __pyx_k_waiting_time, sizeof(__pyx_k_waiting_time), 0, 1, 0, 1}, {&__pyx_n_u_walking, __pyx_k_walking, sizeof(__pyx_k_walking), 0, 1, 0, 1}, {&__pyx_n_s_weekday, __pyx_k_weekday, sizeof(__pyx_k_weekday), 0, 0, 1, 1}, {&__pyx_n_s_year, __pyx_k_year, sizeof(__pyx_k_year), 0, 0, 1, 1}, @@ -8664,9 +8694,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * def construct_query( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ - __pyx_tuple__16 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_year, __pyx_n_s_month, __pyx_n_s_day, __pyx_n_s_weekday, __pyx_n_s_hours, __pyx_n_s_minutes, __pyx_n_s_seconds, __pyx_n_s_date, __pyx_n_s_departure_time, __pyx_n_s_query, __pyx_n_s_src_vec, __pyx_n_s_tgt_vec, __pyx_n_s_inc_src, __pyx_n_s_inc_tgt); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 71, __pyx_L1_error) + __pyx_tuple__16 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_year, __pyx_n_s_month, __pyx_n_s_day, __pyx_n_s_weekday, __pyx_n_s_hours, __pyx_n_s_minutes, __pyx_n_s_seconds, __pyx_n_s_date, __pyx_n_s_departure_time, __pyx_n_s_query, __pyx_n_s_src_vec, __pyx_n_s_tgt_vec, __pyx_n_s_inc_src, __pyx_n_s_inc_tgt); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 71, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__16); __Pyx_GIVEREF(__pyx_tuple__16); __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_construct_query, 71, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) __PYX_ERR(0, 71, __pyx_L1_error) @@ -8679,9 +8709,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ - __pyx_tuple__19 = PyTuple_Pack(11, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journeys, __pyx_n_s_journeys_list, __pyx_n_s_i, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 121, __pyx_L1_error) + __pyx_tuple__19 = PyTuple_Pack(11, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journeys, __pyx_n_s_journeys_list, __pyx_n_s_i, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 121, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__19); __Pyx_GIVEREF(__pyx_tuple__19); __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_pt_journeys_1to1, 121, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 121, __pyx_L1_error) @@ -8694,9 +8724,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { * * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ - __pyx_tuple__22 = PyTuple_Pack(10, __pyx_n_s_self, __pyx_n_s_arrival_datetime, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journey_opt, __pyx_n_s_journey, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 167, __pyx_L1_error) + __pyx_tuple__22 = PyTuple_Pack(10, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journey_opt, __pyx_n_s_journey, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 167, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__22); __Pyx_GIVEREF(__pyx_tuple__22); __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_fastest_pt_journey_1to1, 167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 167, __pyx_L1_error) @@ -9161,7 +9191,7 @@ if (!__Pyx_RefNanny) { * * def construct_query( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_construct_query, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__17)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -9175,7 +9205,7 @@ if (!__Pyx_RefNanny) { * * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_pt_journeys_1t, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__20)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -9189,7 +9219,7 @@ if (!__Pyx_RefNanny) { * * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< * self, - * arrival_datetime, + * source_station_departure_datetime, */ __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_fastest_pt_jou, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd b/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd index a9a5fec8..f9847660 100644 --- a/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.pxd @@ -54,14 +54,15 @@ cdef extern from "NetworkObjects/DataStructures.h": cdef struct Journey: vector[JourneyStep] steps - int departure_secs - Day departure_day - int arrival_secs - Day arrival_day + int source_station_departure_secs + Day source_station_departure_day + int target_station_arrival_secs + Day target_station_arrival_day int duration int source_transfer_time - int waiting_time + int source_waiting_time int trip_time + int target_transfer_time int num_transfers cdef extern from "NetworkObjects/GTFSObjects/GTFSObject.h": diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx b/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx index d8ea267d..daf46cc2 100644 --- a/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx +++ b/src/routing/pt/cpp_raptor_router/PyPTRouter.pyx @@ -70,13 +70,13 @@ cdef class PyPTRouter: def construct_query( self, - arrival_datetime, + source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, ): """Construct query information. Args: - arrival_datetime (datetime): Arrival datetime at the source station + source_station_departure_datetime (datetime): Departure datetime at the source station included_sources (list): List of source stop IDs and their station stop transfer times included_targets (list): List of target stop IDs and their station stop transfer times max_transfers (int): Maximum number of transfers allowed @@ -85,13 +85,13 @@ cdef class PyPTRouter: query (Query) """ # Calculate day of week using Python's datetime - cdef int year = arrival_datetime.year - cdef int month = arrival_datetime.month - cdef int day = arrival_datetime.day - cdef int weekday = arrival_datetime.weekday() - cdef int hours = arrival_datetime.hour - cdef int minutes = arrival_datetime.minute - cdef int seconds = arrival_datetime.second + cdef int year = source_station_departure_datetime.year + cdef int month = source_station_departure_datetime.month + cdef int day = source_station_departure_datetime.day + cdef int weekday = source_station_departure_datetime.weekday() + cdef int hours = source_station_departure_datetime.hour + cdef int minutes = source_station_departure_datetime.minute + cdef int seconds = source_station_departure_datetime.second # Create date, time objects for C++ cdef Date date = Date(year, month, day, weekday) @@ -120,7 +120,7 @@ cdef class PyPTRouter: def return_pt_journeys_1to1( self, - arrival_datetime, + source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False, ): @@ -130,7 +130,7 @@ cdef class PyPTRouter: at a specified departure time. Args: - arrival_datetime (datetime): Arrival datetime at the source station + source_station_departure_datetime (datetime): Departure datetime at the source station included_sources (list): List of source stop IDs and their station stop transfer times included_targets (list): List of target stop IDs and their station stop transfer times max_transfers (int): Maximum number of transfers allowed (-1 for unlimited) @@ -145,7 +145,7 @@ cdef class PyPTRouter: raise RuntimeError("RAPTOR router not initialized. Please initialize first.") query = self.construct_query( - arrival_datetime, included_sources, included_targets, max_transfers, + source_station_departure_datetime, included_sources, included_targets, max_transfers, ) # Set query and find journeys @@ -166,17 +166,14 @@ cdef class PyPTRouter: def return_fastest_pt_journey_1to1( self, - arrival_datetime, + source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False, ): - """Find the fastest public transport journey from source to target - - This method queries the RAPTOR router to find the optimal journey between two stops - at a specified departure time. + """Find the fastest public transport journey from source station to target station Args: - arrival_datetime (datetime): Arrival datetime at the source station + source_station_departure_datetime (datetime): Departure datetime at the source station included_sources (list): List of source stop IDs and their station stop transfer times included_targets (list): List of target stop IDs and their station stop transfer times max_transfers (int): Maximum number of transfers allowed (-1 for unlimited) @@ -191,7 +188,7 @@ cdef class PyPTRouter: raise RuntimeError("RAPTOR router not initialized. Please initialize first.") query = self.construct_query( - arrival_datetime, included_sources, included_targets, max_transfers, + source_station_departure_datetime, included_sources, included_targets, max_transfers, ) # Set query and find journeys @@ -226,18 +223,19 @@ cdef class PyPTRouter: journey_dict = { # Overall journey information "duration": journey.duration, - "source_transfer_time": journey.source_transfer_time, - "waiting_time": journey.waiting_time, "trip_time": journey.trip_time, "num_transfers": journey.num_transfers, # Departure information - "departure_time": journey.departure_secs, - "departure_day": self._day_to_str(journey.departure_day), + "source_transfer_time": journey.source_transfer_time, + "source_waiting_time": journey.source_waiting_time, + "source_station_departure_time": journey.source_station_departure_secs, + "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), # Arrival information - "arrival_time": journey.arrival_secs, - "arrival_day": self._day_to_str(journey.arrival_day), + "target_station_arrival_time": journey.target_station_arrival_secs, + "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), + "target_transfer_time": journey.target_transfer_time, # Journey steps "steps": [] diff --git a/src/routing/pt/cpp_raptor_router/Raptor.cpp b/src/routing/pt/cpp_raptor_router/Raptor.cpp index 69311fac..83dd7e08 100644 --- a/src/routing/pt/cpp_raptor_router/Raptor.cpp +++ b/src/routing/pt/cpp_raptor_router/Raptor.cpp @@ -24,13 +24,13 @@ Raptor::Raptor(const std::unordered_map &agencies, k = 1; // TODO: Remove this part - std::cout << "CPP PT Router: " - << "Raptor initialized with " + std::cout << "Raptor Router (C++): " + << "initialized with " << agencies_.size() << " agencies, " << services_.size() << " services, " - << stops.size() << " stops, " - << routes.size() << " routes, and " - << trips.size() << " trips." << std::endl; + << stops_.size() << " stops, " + << routes_.size() << " routes, and " + << trips_.size() << " trips." << std::endl; } void Raptor::setQuery(const Query &query) { @@ -185,7 +185,7 @@ std::vector Raptor::findJourneys() { std::optional Raptor::findOptimalJourney() { Journey optimal_journey; - int optimal_arrival_secs = std::numeric_limits::max(); + int optimal_target_station_arrival_secs = std::numeric_limits::max(); initializeAlgorithm(); @@ -213,13 +213,14 @@ std::optional Raptor::findOptimalJourney() { // Stopping criterion: if no stops are marked, then stop if (marked_stops.empty()) break; - for (const auto& [target_id, station_stop_transfer_time] : query_.included_targets) { + for (const auto& [target_id, target_station_stop_transfer_time] : query_.included_targets) { if (marked_stops.find(target_id) != marked_stops.end()) { - int arrival_secs = arrivals_[target_id][k].arrival_seconds.value(); - if (arrival_secs < optimal_arrival_secs) { - Journey possible_journey = reconstructJourney(target_id, station_stop_transfer_time); + int target_station_arrival_secs = arrivals_[target_id][k].arrival_seconds.value() + target_station_stop_transfer_time; + // TODO: add more criteria for optimality if needed, such as number of transfers, walking time, etc. + if (target_station_arrival_secs < optimal_target_station_arrival_secs) { + Journey possible_journey = reconstructJourney(target_id, target_station_stop_transfer_time); if (isValidJourney(possible_journey)) { - optimal_arrival_secs = arrival_secs; + optimal_target_station_arrival_secs = target_station_arrival_secs; optimal_journey = possible_journey; } } @@ -430,7 +431,7 @@ bool Raptor::isFootpath(const StopInfo &stop_info) { Journey Raptor::reconstructJourney( const std::string &target_id, - const int station_stop_transfer_time + const int target_station_stop_transfer_time ) { Journey journey; std::string current_stop_id = target_id; @@ -451,7 +452,11 @@ Journey Raptor::reconstructJourney( arrival_seconds = arrivals_[current_stop_id][k].arrival_seconds.value(); const auto& footpaths = stops_[parent_stop_id].getFootpaths(); - duration = footpaths.at(current_stop_id); + if (footpaths.find(current_stop_id) != footpaths.end()) { + duration = footpaths.at(current_stop_id); + } else { + duration = 0; // Should not happen + } departure_seconds = arrival_seconds - duration; } else { // PT leg const std::string &parent_trip_id = parent_trip_id_opt.value(); @@ -497,17 +502,22 @@ Journey Raptor::reconstructJourney( } // Set journey departure time and day - journey.departure_secs = Utils::timeToSeconds(query_.departure_time); - journey.departure_day = Day::CurrentDay; + journey.source_station_departure_secs = Utils::timeToSeconds(query_.departure_time); + journey.source_station_departure_day = Day::CurrentDay; // Set journey arrival time and day - journey.arrival_secs = journey.steps.back().arrival_secs + station_stop_transfer_time; - journey.arrival_day = journey.steps.back().day; - + journey.target_station_arrival_secs = journey.steps.back().arrival_secs + target_station_stop_transfer_time; + // Update arrival day based on arrival seconds + if (journey.target_station_arrival_secs > MIDNIGHT) { + journey.target_station_arrival_day = Day::NextDay; + } else { + journey.target_station_arrival_day = Day::CurrentDay; + } // Set journey duration, source transfer time, waiting time, trip time and transfer numbers - journey.duration = journey.arrival_secs - journey.departure_secs; + journey.duration = journey.target_station_arrival_secs - journey.source_station_departure_secs; // Get station stop transfer time from Query + journey.source_transfer_time = 0; Stop src_stop = *journey.steps.front().src_stop; for (const auto &source : query_.included_sources) { if (source.first == src_stop.getField("stop_id")) { @@ -516,9 +526,20 @@ Journey Raptor::reconstructJourney( } } - journey.waiting_time = journey.steps.front().departure_secs - journey.departure_secs - journey.source_transfer_time; - journey.trip_time = journey.duration - journey.waiting_time; - journey.num_transfers = static_cast(journey.steps.size()) - 1; + journey.target_transfer_time = target_station_stop_transfer_time; + + journey.source_waiting_time = journey.steps.front().departure_secs - journey.source_station_departure_secs - journey.source_transfer_time; + if (journey.source_waiting_time < 0) journey.source_waiting_time = 0; + + journey.trip_time = journey.duration - journey.source_waiting_time - journey.target_transfer_time - journey.source_transfer_time; + + int vehicle_legs = 0; + for (const auto& step : journey.steps) { + if (step.trip_id.has_value() && step.trip_id.value() != "walking") { + vehicle_legs++; + } + } + journey.num_transfers = (vehicle_legs > 0) ? (vehicle_legs - 1) : 0; } catch (const std::exception& e) { std::cerr << "Exception in reconstructJourney: " << e.what() << std::endl; } From 5a24eafc9070dc2ab3d89873808c6a0e19cf12a0 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 12 Dec 2025 10:17:03 +0100 Subject: [PATCH 04/31] Stop tracking .DS_Store file --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 78a7c0cd937a0684fa0f43f1c1340047be9cc484..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM&2AGh5FWRMY*axbwS``gR^nQf04k}(B~4SIN`O$q&jC=#W}~uVyN))ShA66( zBR}uJD{zB1;axbvH?~{tZW3{7DZ;Mo@z2b7{O#DzxI`pseg8Jm8WB0jOiPO>rX(Kc zJdx&1&kCr3JW)UiHSxDW-3e~nVG*zhSOhEr76FUEML+;|HYaDsy{|`YX%Vmp{Feyu z`QRcmtr|MkR2>~CR0sgNfNqsgM;xGJTtlmdjx|-H(5a&bVMK)qF@zS!xXbLIRYS*` zYH<=;oP?QKmIjKZ_w)+ec!!q81#~I`G=UBU$}I+;1rxi=XK+)95j+v((lz; z@k?$!l``~B>Miei&>1vKD?2huT0zu_l|bNk!1C%v5czUYll{o=DcOb|aEeZ`S-L(N zRW|ReyOr|sx;whJb$8v}DsLVi7oF9cx9;yZ--U;f{HPX2!kjU5MYm7OPpF+P`=}8| zp^OgD$NWpw0f0w&QeQowJOQvVGV4f?W9mWA zA^BM?;&V<*fgVE74(-xoYS31FV>!5t}d0?gV(n=N8Dl&DRy zL1C2EvI=CfT6Quz9?&yjI877dm)0~7dtz#5QC65u;YvCGw{v&?YopOtHEAl%!>V9JM^$IncsBfHbVi>B>2=mwgWzI79u`L#MP8rE>4z+Xc^EYutI8m2$_-J7?BV{I4t4KgR@ y8*8dWP^fSmRE6W9r~fcS-32SlR1F<#iXNnMe+W3II3ah*+xuUAZChLv1bzdDB%l!h From 48ed8b6b433dfa09d3524eb4c2ab7aa0e370f0b8 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 12 Dec 2025 10:30:46 +0100 Subject: [PATCH 05/31] Stop tracking src/routing/pt/cpp_raptor_router/PyPTRouter.cpp file --- .../pt/cpp_raptor_router/PyPTRouter.cpp | 14712 ---------------- 1 file changed, 14712 deletions(-) delete mode 100644 src/routing/pt/cpp_raptor_router/PyPTRouter.cpp diff --git a/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp b/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp deleted file mode 100644 index 67d2603f..00000000 --- a/src/routing/pt/cpp_raptor_router/PyPTRouter.cpp +++ /dev/null @@ -1,14712 +0,0 @@ -/* Generated by Cython 3.0.11 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [ - "DateTime.h", - "NetworkObjects\\DataStructures.h", - "NetworkObjects\\GTFSObjects\\Agency.h", - "NetworkObjects\\GTFSObjects\\GTFSObject.h", - "NetworkObjects\\GTFSObjects\\Route.h", - "NetworkObjects\\GTFSObjects\\Service.h", - "NetworkObjects\\GTFSObjects\\Stop.h", - "NetworkObjects\\GTFSObjects\\Trip.h", - "Parser.h", - "Raptor.h" - ], - "extra_compile_args": [ - "/std:c++20" - ], - "include_dirs": [ - "." - ], - "language": "c++", - "name": "PyPTRouter", - "sources": [ - "PyPTRouter.pyx", - ".\\Parser.cpp", - ".\\Raptor.cpp", - ".\\Utils.cpp", - ".\\NetworkObjects\\GTFSObjects\\Agency.cpp", - ".\\NetworkObjects\\GTFSObjects\\GTFSObject.cpp", - ".\\NetworkObjects\\GTFSObjects\\Route.cpp", - ".\\NetworkObjects\\GTFSObjects\\Service.cpp", - ".\\NetworkObjects\\GTFSObjects\\Stop.cpp", - ".\\NetworkObjects\\GTFSObjects\\Trip.cpp" - ] - }, - "module_name": "PyPTRouter" -} -END: Cython Metadata */ - -#ifndef PY_SSIZE_T_CLEAN -#define PY_SSIZE_T_CLEAN -#endif /* PY_SSIZE_T_CLEAN */ -#if defined(CYTHON_LIMITED_API) && 0 - #ifndef Py_LIMITED_API - #if CYTHON_LIMITED_API+0 > 0x03030000 - #define Py_LIMITED_API CYTHON_LIMITED_API - #else - #define Py_LIMITED_API 0x03030000 - #endif - #endif -#endif - -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.7+ or Python 3.3+. -#else -#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API -#define __PYX_EXTRA_ABI_MODULE_NAME "limited" -#else -#define __PYX_EXTRA_ABI_MODULE_NAME "" -#endif -#define CYTHON_ABI "3_0_11" __PYX_EXTRA_ABI_MODULE_NAME -#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI -#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." -#define CYTHON_HEX_VERSION 0x03000BF0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #define HAVE_LONG_LONG -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX -#if defined(GRAALVM_PYTHON) - /* For very preliminary testing purposes. Most variables are set the same as PyPy. - The existence of this section does not imply that anything works or is even tested */ - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 1 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) - #endif - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(PYPY_VERSION) - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3) - #endif - #if PY_VERSION_HEX < 0x03090000 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00) - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(CYTHON_LIMITED_API) - #ifdef Py_LIMITED_API - #undef __PYX_LIMITED_VERSION_HEX - #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API - #endif - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 1 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #undef CYTHON_CLINE_IN_TRACEBACK - #define CYTHON_CLINE_IN_TRACEBACK 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 1 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #endif - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #undef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 1 - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #endif - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif - #undef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 -#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #ifndef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #ifndef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL 0 - #ifndef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL 1 - #endif - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #ifndef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 1 - #endif - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 - #endif - #ifndef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 0 - #endif -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #define CYTHON_COMPILING_IN_LIMITED_API 0 - #define CYTHON_COMPILING_IN_GRAAL 0 - #define CYTHON_COMPILING_IN_NOGIL 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #ifndef CYTHON_USE_TYPE_SPECS - #define CYTHON_USE_TYPE_SPECS 0 - #endif - #ifndef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #ifndef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_GIL - #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6) - #endif - #ifndef CYTHON_METH_FASTCALL - #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1) - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP487_INIT_SUBCLASS - #define CYTHON_PEP487_INIT_SUBCLASS 1 - #endif - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) - #define CYTHON_PEP489_MULTI_PHASE_INIT 1 - #endif - #ifndef CYTHON_USE_MODULE_STATE - #define CYTHON_USE_MODULE_STATE 0 - #endif - #if PY_VERSION_HEX < 0x030400a1 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #elif !defined(CYTHON_USE_TP_FINALIZE) - #define CYTHON_USE_TP_FINALIZE 1 - #endif - #if PY_VERSION_HEX < 0x030600B1 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #elif !defined(CYTHON_USE_DICT_VERSIONS) - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5) - #endif - #if PY_VERSION_HEX < 0x030700A3 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #elif !defined(CYTHON_USE_EXC_INFO_STACK) - #define CYTHON_USE_EXC_INFO_STACK 1 - #endif - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 - #endif - #ifndef CYTHON_USE_FREELISTS - #define CYTHON_USE_FREELISTS 1 - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if !defined(CYTHON_VECTORCALL) -#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1) -#endif -#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1) -#if CYTHON_USE_PYLONG_INTERNALS - #if PY_MAJOR_VERSION < 3 - #include "longintrepr.h" - #endif - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED - #if defined(__cplusplus) - /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 - * but leads to warnings with -pedantic, since it is a C++17 feature */ - #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) - #if __has_cpp_attribute(maybe_unused) - #define CYTHON_UNUSED [[maybe_unused]] - #endif - #endif - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR - #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_USE_CPP_STD_MOVE - #if defined(__cplusplus) && (\ - __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) - #define CYTHON_USE_CPP_STD_MOVE 1 - #else - #define CYTHON_USE_CPP_STD_MOVE 0 - #endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - #endif - #endif - #if _MSC_VER < 1300 - #ifdef _WIN64 - typedef unsigned long long __pyx_uintptr_t; - #else - typedef unsigned int __pyx_uintptr_t; - #endif - #else - #ifdef _WIN64 - typedef unsigned __int64 __pyx_uintptr_t; - #else - typedef unsigned __int32 __pyx_uintptr_t; - #endif - #endif -#else - #include - typedef uintptr_t __pyx_uintptr_t; -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) - /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 - * but leads to warnings with -pedantic, since it is a C++17 feature */ - #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif -#ifdef __cplusplus - template - struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; - #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) -#else - #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) -#endif -#if CYTHON_COMPILING_IN_PYPY == 1 - #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000) -#else - #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000) -#endif -#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) - -#ifndef __cplusplus - #error "Cython files generated with the C++ option must be compiled with a C++ compiler." -#endif -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #else - #define CYTHON_INLINE inline - #endif -#endif -template -void __Pyx_call_destructor(T& x) { - x.~T(); -} -template -class __Pyx_FakeReference { - public: - __Pyx_FakeReference() : ptr(NULL) { } - __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } - T *operator->() { return ptr; } - T *operator&() { return ptr; } - operator T&() { return *ptr; } - template bool operator ==(const U& other) const { return *ptr == other; } - template bool operator !=(const U& other) const { return *ptr != other; } - template bool operator==(const __Pyx_FakeReference& other) const { return *ptr == *other.ptr; } - template bool operator!=(const __Pyx_FakeReference& other) const { return *ptr != *other.ptr; } - private: - T *ptr; -}; - -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_DefaultClassType PyClass_Type - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" - #define __Pyx_DefaultClassType PyType_Type -#if CYTHON_COMPILING_IN_LIMITED_API - static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, - PyObject *code, PyObject *c, PyObject* n, PyObject *v, - PyObject *fv, PyObject *cell, PyObject* fn, - PyObject *name, int fline, PyObject *lnos) { - PyObject *exception_table = NULL; - PyObject *types_module=NULL, *code_type=NULL, *result=NULL; - #if __PYX_LIMITED_VERSION_HEX < 0x030B0000 - PyObject *version_info; - PyObject *py_minor_version = NULL; - #endif - long minor_version = 0; - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000 - minor_version = 11; - #else - if (!(version_info = PySys_GetObject("version_info"))) goto end; - if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; - minor_version = PyLong_AsLong(py_minor_version); - Py_DECREF(py_minor_version); - if (minor_version == -1 && PyErr_Occurred()) goto end; - #endif - if (!(types_module = PyImport_ImportModule("types"))) goto end; - if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; - if (minor_version <= 7) { - (void)p; - result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code, - c, n, v, fn, name, fline, lnos, fv, cell); - } else if (minor_version <= 10) { - result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code, - c, n, v, fn, name, fline, lnos, fv, cell); - } else { - if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; - result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code, - c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); - } - end: - Py_XDECREF(code_type); - Py_XDECREF(exception_table); - Py_XDECREF(types_module); - if (type) { - PyErr_Restore(type, value, traceback); - } - return result; - } - #ifndef CO_OPTIMIZED - #define CO_OPTIMIZED 0x0001 - #endif - #ifndef CO_NEWLOCALS - #define CO_NEWLOCALS 0x0002 - #endif - #ifndef CO_VARARGS - #define CO_VARARGS 0x0004 - #endif - #ifndef CO_VARKEYWORDS - #define CO_VARKEYWORDS 0x0008 - #endif - #ifndef CO_ASYNC_GENERATOR - #define CO_ASYNC_GENERATOR 0x0200 - #endif - #ifndef CO_GENERATOR - #define CO_GENERATOR 0x0020 - #endif - #ifndef CO_COROUTINE - #define CO_COROUTINE 0x0080 - #endif -#elif PY_VERSION_HEX >= 0x030B0000 - static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, int k, int l, int s, int f, - PyObject *code, PyObject *c, PyObject* n, PyObject *v, - PyObject *fv, PyObject *cell, PyObject* fn, - PyObject *name, int fline, PyObject *lnos) { - PyCodeObject *result; - PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0); - if (!empty_bytes) return NULL; - result = - #if PY_VERSION_HEX >= 0x030C0000 - PyUnstable_Code_NewWithPosOnlyArgs - #else - PyCode_NewWithPosOnlyArgs - #endif - (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes); - Py_DECREF(empty_bytes); - return result; - } -#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#else - #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif -#endif -#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) - #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) -#else - #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) - #define __Pyx_Py_Is(x, y) Py_Is(x, y) -#else - #define __Pyx_Py_Is(x, y) ((x) == (y)) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) - #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) -#else - #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) - #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) -#else - #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) -#endif -#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) - #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) -#else - #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) -#endif -#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) -#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) -#else - #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) -#endif -#ifndef CO_COROUTINE - #define CO_COROUTINE 0x80 -#endif -#ifndef CO_ASYNC_GENERATOR - #define CO_ASYNC_GENERATOR 0x200 -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef Py_TPFLAGS_SEQUENCE - #define Py_TPFLAGS_SEQUENCE 0 -#endif -#ifndef Py_TPFLAGS_MAPPING - #define Py_TPFLAGS_MAPPING 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #if PY_VERSION_HEX >= 0x030d00A4 - # define __Pyx_PyCFunctionFast PyCFunctionFast - # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords - #else - # define __Pyx_PyCFunctionFast _PyCFunctionFast - # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords - #endif -#endif -#if CYTHON_METH_FASTCALL - #define __Pyx_METH_FASTCALL METH_FASTCALL - #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast - #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords -#else - #define __Pyx_METH_FASTCALL METH_VARARGS - #define __Pyx_PyCFunction_FastCall PyCFunction - #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords -#endif -#if CYTHON_VECTORCALL - #define __pyx_vectorcallfunc vectorcallfunc - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET - #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) -#elif CYTHON_BACKPORT_VECTORCALL - typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) - #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)) -#else - #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 - #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) -#endif -#if PY_MAJOR_VERSION >= 0x030900B1 -#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) -#else -#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) -#endif -#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) -#elif !CYTHON_COMPILING_IN_LIMITED_API -#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) -#endif -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) -static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { - return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; -} -#endif -static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) { -#if CYTHON_COMPILING_IN_LIMITED_API - return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; -#else - return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; -#endif -} -#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) -#if __PYX_LIMITED_VERSION_HEX < 0x030900B1 - #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) - typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); -#else - #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) - #define __Pyx_PyCMethod PyCMethod -#endif -#ifndef METH_METHOD - #define METH_METHOD 0x200 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyThreadState_Current PyThreadState_Get() -#elif !CYTHON_FAST_THREAD_STATE - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x030d00A1 - #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op) -{ - void *result; - result = PyModule_GetState(op); - if (!result) - Py_FatalError("Couldn't find the module state"); - return result; -} -#endif -#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype) -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) -#else - #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if PY_MAJOR_VERSION < 3 - #if CYTHON_COMPILING_IN_PYPY - #if PYPY_VERSION_NUM < 0x07030600 - #if defined(__cplusplus) && __cplusplus >= 201402L - [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]] - #elif defined(__GNUC__) || defined(__clang__) - __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))) - #elif defined(_MSC_VER) - __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")) - #endif - static CYTHON_INLINE int PyGILState_Check(void) { - return 0; - } - #else // PYPY_VERSION_NUM < 0x07030600 - #endif // PYPY_VERSION_NUM < 0x07030600 - #else - static CYTHON_INLINE int PyGILState_Check(void) { - PyThreadState * tstate = _PyThreadState_Current; - return tstate && (tstate == PyGILState_GetThisThreadState()); - } - #endif -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { - PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); - if (res == NULL) PyErr_Clear(); - return res; -} -#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000) -#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError -#define __Pyx_PyDict_GetItemStr PyDict_GetItem -#else -static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { -#if CYTHON_COMPILING_IN_PYPY - return PyDict_GetItem(dict, name); -#else - PyDictEntry *ep; - PyDictObject *mp = (PyDictObject*) dict; - long hash = ((PyStringObject *) name)->ob_shash; - assert(hash != -1); - ep = (mp->ma_lookup)(mp, name, hash); - if (ep == NULL) { - return NULL; - } - return ep->me_value; -#endif -} -#define __Pyx_PyDict_GetItemStr PyDict_GetItem -#endif -#if CYTHON_USE_TYPE_SLOTS - #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) - #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) - #define __Pyx_PyObject_GetIterNextFunc(obj) (Py_TYPE(obj)->tp_iternext) -#else - #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) - #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) - #define __Pyx_PyObject_GetIterNextFunc(obj) PyIter_Next -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v) -#else - #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v) -#endif -#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000 -#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ - PyTypeObject *type = Py_TYPE((PyObject*)obj);\ - assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ - PyObject_GC_Del(obj);\ - Py_DECREF(type);\ -} -#else -#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) -#endif -#if CYTHON_COMPILING_IN_LIMITED_API - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GetLength(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) - #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) - #define __Pyx_PyUnicode_DATA(u) ((void*)u) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) -#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #if PY_VERSION_HEX >= 0x030C0000 - #define __Pyx_PyUnicode_READY(op) (0) - #else - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #endif - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) - #if PY_VERSION_HEX >= 0x030C0000 - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #else - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #endif - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535U : 1114111U) - #define __Pyx_PyUnicode_KIND(u) ((int)sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = (Py_UNICODE) ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #if !defined(PyUnicode_DecodeUnicodeEscape) - #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) - #endif - #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500) - #undef PyUnicode_Contains - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) - #endif - #if !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) - #endif - #if !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) - #endif -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#if CYTHON_COMPILING_IN_CPYTHON - #define __Pyx_PySequence_ListKeepNew(obj)\ - (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) -#else - #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) - #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) - #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) - #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) - #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) - #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) - #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) - #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) -#else - #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) - #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) - #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) - #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) - #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) - #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) - #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) - #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) -#endif -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 - #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) -#else - static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { - PyObject *module = PyImport_AddModule(name); - Py_XINCREF(module); - return module; - } -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define __Pyx_Py3Int_Check(op) PyLong_Check(op) - #define __Pyx_Py3Int_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#else - #define __Pyx_Py3Int_Check(op) (PyLong_Check(op) || PyInt_Check(op)) - #define __Pyx_Py3Int_CheckExact(op) (PyLong_CheckExact(op) || PyInt_CheckExact(op)) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) - #if !defined(_USE_MATH_DEFINES) - #define _USE_MATH_DEFINES - #endif -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifdef CYTHON_EXTERN_C - #undef __PYX_EXTERN_C - #define __PYX_EXTERN_C CYTHON_EXTERN_C -#elif defined(__PYX_EXTERN_C) - #ifdef _MSC_VER - #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") - #else - #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. - #endif -#else - #define __PYX_EXTERN_C extern "C++" -#endif - -#define __PYX_HAVE__PyPTRouter -#define __PYX_HAVE_API__PyPTRouter -/* Early includes */ -#include -#include -#include "ios" -#include "new" -#include "stdexcept" -#include "typeinfo" -#include -#include - - #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600) - // move should be defined for these versions of MSVC, but __cplusplus isn't set usefully - #include - - namespace cython_std { - template typename std::remove_reference::type&& move(T& t) noexcept { return std::move(t); } - template typename std::remove_reference::type&& move(T&& t) noexcept { return std::move(t); } - } - - #endif - -#include -#include -#include "DateTime.h" -#include "NetworkObjects/DataStructures.h" -#include "NetworkObjects/GTFSObjects/GTFSObject.h" -#include "NetworkObjects/GTFSObjects/Stop.h" -#include "NetworkObjects/GTFSObjects/Agency.h" -#include "NetworkObjects/GTFSObjects/Service.h" -#include "NetworkObjects/GTFSObjects/Route.h" -#include "NetworkObjects/GTFSObjects/Trip.h" -#include "Parser.h" -#include "Raptor.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #if PY_VERSION_HEX >= 0x030C00A7 - #ifndef _PyLong_SIGN_MASK - #define _PyLong_SIGN_MASK 3 - #endif - #ifndef _PyLong_NON_SIZE_BITS - #define _PyLong_NON_SIZE_BITS 3 - #endif - #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) - #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) - #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) - #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) - #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) - #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) - #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) - #define __Pyx_PyLong_SignedDigitCount(x)\ - ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) - #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) - #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) - #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) - #else - #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) - #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) - #endif - typedef Py_ssize_t __Pyx_compact_pylong; - typedef size_t __Pyx_compact_upylong; - #else - #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) - #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) - #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) - #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) - #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) - #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) - #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) - #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) - #define __Pyx_PyLong_CompactValue(x)\ - ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) - typedef sdigit __Pyx_compact_pylong; - typedef digit __Pyx_compact_upylong; - #endif - #if PY_VERSION_HEX >= 0x030C00A5 - #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) - #else - #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) - #endif -#endif -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -#include -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = (char) c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#include -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -#if !CYTHON_USE_MODULE_STATE -static PyObject *__pyx_m = NULL; -#endif -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm = __FILE__; -static const char *__pyx_filename; - -/* #### Code section: filename_table ### */ - -static const char *__pyx_f[] = { - "PyPTRouter.pyx", - "", -}; -/* #### Code section: utility_code_proto_before_types ### */ -/* ForceInitThreads.proto */ -#ifndef __PYX_FORCE_INIT_THREADS - #define __PYX_FORCE_INIT_THREADS 0 -#endif - -/* EnumClassDecl.proto */ -#if defined (_MSC_VER) - #if _MSC_VER >= 1910 - #define __PYX_ENUM_CLASS_DECL enum - #else - #define __PYX_ENUM_CLASS_DECL - #endif -#else - #define __PYX_ENUM_CLASS_DECL enum -#endif - -/* #### Code section: numeric_typedefs ### */ -/* #### Code section: complex_type_declarations ### */ -/* #### Code section: type_declarations ### */ - -/*--- Type declarations ---*/ -struct __pyx_obj_10PyPTRouter_PyPTRouter; - -/* "PyPTRouter.pyx":10 - * from datetime import datetime - * - * cdef class PyPTRouter: # <<<<<<<<<<<<<< - * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping - * - */ -struct __pyx_obj_10PyPTRouter_PyPTRouter { - PyObject_HEAD - struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *__pyx_vtab; - Raptor *raptor_ptr; -}; - - - -struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter { - PyObject *(*_convert_journey_to_dict)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct Journey, bool); - PyObject *(*_day_to_str)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, __PYX_ENUM_CLASS_DECL Day); - PyObject *(*_convert_journey_step)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct JourneyStep); -}; -static struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *__pyx_vtabptr_10PyPTRouter_PyPTRouter; -/* #### Code section: utility_code_proto ### */ - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, Py_ssize_t); - void (*DECREF)(void*, PyObject*, Py_ssize_t); - void (*GOTREF)(void*, PyObject*, Py_ssize_t); - void (*GIVEREF)(void*, PyObject*, Py_ssize_t); - void* (*SetupContext)(const char*, Py_ssize_t, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ - } - #define __Pyx_RefNannyFinishContextNogil() {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __Pyx_RefNannyFinishContext();\ - PyGILState_Release(__pyx_gilstate_save);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__)) - #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext() -#endif - #define __Pyx_RefNannyFinishContextNogil() {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __Pyx_RefNannyFinishContext();\ - PyGILState_Release(__pyx_gilstate_save);\ - } - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) - #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContextNogil() - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_Py_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; Py_XDECREF(tmp);\ - } while (0) -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#if PY_VERSION_HEX >= 0x030C00A6 -#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) -#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) -#else -#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) -#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) -#endif -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) -#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* IterFinish.proto */ -static CYTHON_INLINE int __Pyx_IterFinish(void); - -/* UnpackItemEndCheck.proto */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); - -/* DictGetItem.proto */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); -#define __Pyx_PyObject_Dict_GetItem(obj, name)\ - (likely(PyDict_CheckExact(obj)) ?\ - __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) -#else -#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) -#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) -#endif - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* MoveIfSupported.proto */ -#if CYTHON_USE_CPP_STD_MOVE - #include - #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) -#else - #define __PYX_STD_MOVE_IF_SUPPORTED(x) x -#endif - -/* TupleAndListFromArray.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); -static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); -#endif - -/* IncludeStringH.proto */ -#include - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* fastcall.proto */ -#if CYTHON_AVOID_BORROWED_REFS - #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i) -#elif CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i) -#else - #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i) -#endif -#if CYTHON_AVOID_BORROWED_REFS - #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg) - #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg) -#else - #define __Pyx_Arg_NewRef_VARARGS(arg) arg - #define __Pyx_Arg_XDECREF_VARARGS(arg) -#endif -#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) -#define __Pyx_KwValues_VARARGS(args, nargs) NULL -#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) -#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) -#if CYTHON_METH_FASTCALL - #define __Pyx_Arg_FASTCALL(args, i) args[i] - #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds) - #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) - static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 - CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); - #else - #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) - #endif - #define __Pyx_Arg_NewRef_FASTCALL(arg) arg /* no-op, __Pyx_Arg_FASTCALL is direct and this needs - to have the same reference counting */ - #define __Pyx_Arg_XDECREF_FASTCALL(arg) -#else - #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS - #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS - #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS - #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS - #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS - #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg) - #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS -#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start) -#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start) -#else -#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) -#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) -#endif - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues, - PyObject **argnames[], - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, - const char* function_name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#if !CYTHON_VECTORCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif -#if !CYTHON_VECTORCALL -#if PY_VERSION_HEX >= 0x03080000 - #include "frameobject.h" -#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif - #define __Pxy_PyFrame_Initialize_Offsets() - #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus) -#else - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif -#endif -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectFastCall.proto */ -#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) -static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs); - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* PyObjectFormatSimple.proto */ -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#elif PY_MAJOR_VERSION < 3 - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ - PyObject_Format(s, f)) -#elif CYTHON_USE_TYPE_SLOTS - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) :\ - likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) :\ - PyObject_Format(s, f)) -#else - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* ListAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { - Py_INCREF(x); - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 - L->ob_item[len] = x; - #else - PyList_SET_ITEM(list, len, x); - #endif - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) -#endif - -/* PyObjectCall2Args.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod1.proto */ -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); - -/* append.proto */ -static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); - -/* IncludeCppStringH.proto */ -#include - -/* decode_c_string_utf16.proto */ -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 0; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = -1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} -static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { - int byteorder = 1; - return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); -} - -/* decode_c_bytes.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( - const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); - -/* decode_cpp_string.proto */ -static CYTHON_INLINE PyObject* __Pyx_decode_cpp_string( - std::string cppstring, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - return __Pyx_decode_c_bytes( - cppstring.data(), cppstring.size(), start, stop, encoding, errors, decode_func); -} - -/* KeywordStringCheck.proto */ -static int __Pyx_CheckKeywordStrings(PyObject *kw, const char* function_name, int kw_allowed); - -/* IncludeStructmemberH.proto */ -#include - -/* FixUpExtensionType.proto */ -#if CYTHON_USE_TYPE_SPECS -static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); -#endif - -/* PyObjectCallNoArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); - -/* PyObjectCallMethod0.proto */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); - -/* ValidateBasesTuple.proto */ -#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS -static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); -#endif - -/* PyType_Ready.proto */ -CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t); - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyTypeObject* typeptr , void* vtable); - -/* GetVTable.proto */ -static void* __Pyx_GetVtable(PyTypeObject *type); - -/* MergeVTables.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_MergeVtables(PyTypeObject *type); -#endif - -/* SetupReduce.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_setup_reduce(PyObject* type_obj); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* ImportDottedModule.proto */ -static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple); -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple); -#endif - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* FetchSharedCythonModule.proto */ -static PyObject *__Pyx_FetchSharedCythonABIModule(void); - -/* FetchCommonType.proto */ -#if !CYTHON_USE_TYPE_SPECS -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); -#else -static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases); -#endif - -/* PyMethodNew.proto */ -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { - PyObject *typesModule=NULL, *methodType=NULL, *result=NULL; - CYTHON_UNUSED_VAR(typ); - if (!self) - return __Pyx_NewRef(func); - typesModule = PyImport_ImportModule("types"); - if (!typesModule) return NULL; - methodType = PyObject_GetAttrString(typesModule, "MethodType"); - Py_DECREF(typesModule); - if (!methodType) return NULL; - result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL); - Py_DECREF(methodType); - return result; -} -#elif PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { - CYTHON_UNUSED_VAR(typ); - if (!self) - return __Pyx_NewRef(func); - return PyMethod_New(func, self); -} -#else - #define __Pyx_PyMethod_New PyMethod_New -#endif - -/* PyVectorcallFastCallDict.proto */ -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); -#endif - -/* CythonFunctionShared.proto */ -#define __Pyx_CyFunction_USED -#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 -#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 -#define __Pyx_CYFUNCTION_CCLASS 0x04 -#define __Pyx_CYFUNCTION_COROUTINE 0x08 -#define __Pyx_CyFunction_GetClosure(f)\ - (((__pyx_CyFunctionObject *) (f))->func_closure) -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - #define __Pyx_CyFunction_GetClassObj(f)\ - (((__pyx_CyFunctionObject *) (f))->func_classobj) -#else - #define __Pyx_CyFunction_GetClassObj(f)\ - ((PyObject*) ((PyCMethodObject *) (f))->mm_class) -#endif -#define __Pyx_CyFunction_SetClassObj(f, classobj)\ - __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) -#define __Pyx_CyFunction_Defaults(type, f)\ - ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) -#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ - ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) -typedef struct { -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject_HEAD - PyObject *func; -#elif PY_VERSION_HEX < 0x030900B1 - PyCFunctionObject func; -#else - PyCMethodObject func; -#endif -#if CYTHON_BACKPORT_VECTORCALL - __pyx_vectorcallfunc func_vectorcall; -#endif -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API - PyObject *func_weakreflist; -#endif - PyObject *func_dict; - PyObject *func_name; - PyObject *func_qualname; - PyObject *func_doc; - PyObject *func_globals; - PyObject *func_code; - PyObject *func_closure; -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - PyObject *func_classobj; -#endif - void *defaults; - int defaults_pyobjects; - size_t defaults_size; - int flags; - PyObject *defaults_tuple; - PyObject *defaults_kwdict; - PyObject *(*defaults_getter)(PyObject *); - PyObject *func_annotations; - PyObject *func_is_coroutine; -} __pyx_CyFunctionObject; -#undef __Pyx_CyOrPyCFunction_Check -#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_CyFunctionType) -#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type) -#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_CyFunctionType) -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc); -#undef __Pyx_IsSameCFunction -#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *closure, - PyObject *module, PyObject *globals, - PyObject* code); -static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, - size_t size, - int pyobjects); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, - PyObject *tuple); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, - PyObject *dict); -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, - PyObject *dict); -static int __pyx_CyFunction_init(PyObject *module); -#if CYTHON_METH_FASTCALL -static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); -#if CYTHON_BACKPORT_VECTORCALL -#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) -#else -#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) -#endif -#endif - -/* CythonFunction.proto */ -static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *closure, - PyObject *module, PyObject *globals, - PyObject* code); - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -#if !CYTHON_COMPILING_IN_LIMITED_API -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); -#endif - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* GCCDiagnostics.proto */ -#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#define __Pyx_HAS_GCC_DIAGNOSTIC -#endif - -/* CppExceptionConversion.proto */ -#ifndef __Pyx_CppExn2PyErr -#include -#include -#include -#include -static void __Pyx_CppExn2PyErr() { - try { - if (PyErr_Occurred()) - ; // let the latest Python exn pass through and ignore the current one - else - throw; - } catch (const std::bad_alloc& exn) { - PyErr_SetString(PyExc_MemoryError, exn.what()); - } catch (const std::bad_cast& exn) { - PyErr_SetString(PyExc_TypeError, exn.what()); - } catch (const std::bad_typeid& exn) { - PyErr_SetString(PyExc_TypeError, exn.what()); - } catch (const std::domain_error& exn) { - PyErr_SetString(PyExc_ValueError, exn.what()); - } catch (const std::invalid_argument& exn) { - PyErr_SetString(PyExc_ValueError, exn.what()); - } catch (const std::ios_base::failure& exn) { - PyErr_SetString(PyExc_IOError, exn.what()); - } catch (const std::out_of_range& exn) { - PyErr_SetString(PyExc_IndexError, exn.what()); - } catch (const std::overflow_error& exn) { - PyErr_SetString(PyExc_OverflowError, exn.what()); - } catch (const std::range_error& exn) { - PyErr_SetString(PyExc_ArithmeticError, exn.what()); - } catch (const std::underflow_error& exn) { - PyErr_SetString(PyExc_ArithmeticError, exn.what()); - } catch (const std::exception& exn) { - PyErr_SetString(PyExc_RuntimeError, exn.what()); - } - catch (...) - { - PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); - } -} -#endif - -static PyObject* __pyx_convert__to_py_struct__Date(struct Date s); -static PyObject* __pyx_convert__to_py_struct__Time(struct Time s); -/* RaiseUnexpectedTypeError.proto */ -static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); - -/* FormatTypeName.proto */ -#if CYTHON_COMPILING_IN_LIMITED_API -typedef PyObject *__Pyx_TypeName; -#define __Pyx_FMT_TYPENAME "%U" -static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp); -#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) -#else -typedef const char *__Pyx_TypeName; -#define __Pyx_FMT_TYPENAME "%.200s" -#define __Pyx_PyType_GetName(tp) ((tp)->tp_name) -#define __Pyx_DECREF_TypeName(obj) -#endif - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* CheckBinaryVersion.proto */ -static unsigned long __Pyx_get_runtime_version(void); -static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -/* #### Code section: module_declarations ### */ -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct Journey __pyx_v_journey, bool __pyx_v_detailed); /* proto*/ -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, __PYX_ENUM_CLASS_DECL Day __pyx_v_day); /* proto*/ -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct JourneyStep __pyx_v_step); /* proto*/ - -/* Module declarations from "libc.string" */ - -/* Module declarations from "libcpp.string" */ - -/* Module declarations from "libcpp.vector" */ - -/* Module declarations from "libcpp.utility" */ - -/* Module declarations from "libcpp.unordered_map" */ - -/* Module declarations from "libcpp" */ - -/* Module declarations from "libcpp.optional" */ - -/* Module declarations from "PyPTRouter" */ -static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(std::string const &); /*proto*/ -static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____int(std::pair const &); /*proto*/ -static PyObject *__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(std::vector > const &); /*proto*/ -static std::pair __pyx_convert_pair_from_py_std_3a__3a_string__and_int(PyObject *); /*proto*/ -static std::vector > __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(PyObject *); /*proto*/ -static struct Date __pyx_convert__from_py_struct__Date(PyObject *); /*proto*/ -static struct Time __pyx_convert__from_py_struct__Time(PyObject *); /*proto*/ -static struct Query __pyx_convert__from_py_struct__Query(PyObject *); /*proto*/ -/* #### Code section: typeinfo ### */ -/* #### Code section: before_global_var ### */ -#define __Pyx_MODULE_NAME "PyPTRouter" -extern int __pyx_module_is_main_PyPTRouter; -int __pyx_module_is_main_PyPTRouter = 0; - -/* Implementation of "PyPTRouter" */ -/* #### Code section: global_var ### */ -static PyObject *__pyx_builtin_TypeError; -static PyObject *__pyx_builtin_RuntimeError; -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_MemoryError; -static PyObject *__pyx_builtin_KeyError; -static PyObject *__pyx_builtin_ValueError; -/* #### Code section: string_decls ### */ -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_gc[] = "gc"; -static const char __pyx_k__14[] = "*"; -static const char __pyx_k__15[] = "."; -static const char __pyx_k__28[] = "?"; -static const char __pyx_k_day[] = "day"; -static const char __pyx_k_date[] = "date"; -static const char __pyx_k_hour[] = "hour"; -static const char __pyx_k_json[] = "json"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "__name__"; -static const char __pyx_k_self[] = "self"; -static const char __pyx_k_spec[] = "__spec__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_year[] = "year"; -static const char __pyx_k_hours[] = "hours"; -static const char __pyx_k_month[] = "month"; -static const char __pyx_k_query[] = "query"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_steps[] = "steps"; -static const char __pyx_k_utf_8[] = "utf-8"; -static const char __pyx_k_append[] = "append"; -static const char __pyx_k_enable[] = "enable"; -static const char __pyx_k_encode[] = "encode"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_minute[] = "minute"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_second[] = "second"; -static const char __pyx_k_Unknown[] = "Unknown"; -static const char __pyx_k_disable[] = "disable"; -static const char __pyx_k_inc_src[] = "inc_src"; -static const char __pyx_k_inc_tgt[] = "inc_tgt"; -static const char __pyx_k_journey[] = "journey"; -static const char __pyx_k_minutes[] = "minutes"; -static const char __pyx_k_seconds[] = "seconds"; -static const char __pyx_k_src_vec[] = "src_vec"; -static const char __pyx_k_tgt_vec[] = "tgt_vec"; -static const char __pyx_k_trip_id[] = "trip_id"; -static const char __pyx_k_walking[] = "walking"; -static const char __pyx_k_weekday[] = "weekday"; -static const char __pyx_k_KeyError[] = "KeyError"; -static const char __pyx_k_datetime[] = "datetime"; -static const char __pyx_k_detailed[] = "detailed"; -static const char __pyx_k_duration[] = "duration"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_journeys[] = "journeys"; -static const char __pyx_k_next_day[] = "next_day"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_isenabled[] = "isenabled"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_trip_time[] = "trip_time"; -static const char __pyx_k_PyPTRouter[] = "PyPTRouter"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_to_stop_id[] = "to_stop_id"; -static const char __pyx_k_MemoryError[] = "MemoryError"; -static const char __pyx_k_agency_name[] = "agency_name"; -static const char __pyx_k_current_day[] = "current_day"; -static const char __pyx_k_journey_opt[] = "journey_opt"; -static const char __pyx_k_RuntimeError[] = "RuntimeError"; -static const char __pyx_k_arrival_time[] = "arrival_time"; -static const char __pyx_k_from_stop_id[] = "from_stop_id"; -static const char __pyx_k_initializing[] = "_initializing"; -static const char __pyx_k_is_coroutine[] = "_is_coroutine"; -static const char __pyx_k_journey_dict[] = "journey_dict"; -static const char __pyx_k_stringsource[] = ""; -static const char __pyx_k_journeys_list[] = "journeys_list"; -static const char __pyx_k_max_transfers[] = "max_transfers"; -static const char __pyx_k_num_transfers[] = "num_transfers"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_PyPTRouter_pyx[] = "PyPTRouter.pyx"; -static const char __pyx_k_departure_time[] = "departure_time"; -static const char __pyx_k_construct_query[] = "construct_query"; -static const char __pyx_k_input_directory[] = "input_directory"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_included_sources[] = "included_sources"; -static const char __pyx_k_included_targets[] = "included_targets"; -static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_source_waiting_time[] = "source_waiting_time"; -static const char __pyx_k_source_transfer_time[] = "source_transfer_time"; -static const char __pyx_k_target_transfer_time[] = "target_transfer_time"; -static const char __pyx_k_return_pt_journeys_1to1[] = "return_pt_journeys_1to1"; -static const char __pyx_k_PyPTRouter___reduce_cython[] = "PyPTRouter.__reduce_cython__"; -static const char __pyx_k_PyPTRouter_construct_query[] = "PyPTRouter.construct_query"; -static const char __pyx_k_target_station_arrival_day[] = "target_station_arrival_day"; -static const char __pyx_k_target_station_arrival_time[] = "target_station_arrival_time"; -static const char __pyx_k_PyPTRouter___setstate_cython[] = "PyPTRouter.__setstate_cython__"; -static const char __pyx_k_source_station_departure_day[] = "source_station_departure_day"; -static const char __pyx_k_Expected_string_int_tuple_got[] = "Expected (string, int) tuple, got "; -static const char __pyx_k_source_station_departure_time[] = "source_station_departure_time"; -static const char __pyx_k_return_fastest_pt_journey_1to1[] = "return_fastest_pt_journey_1to1"; -static const char __pyx_k_No_value_specified_for_struct_at[] = "No value specified for struct attribute 'year'"; -static const char __pyx_k_PyPTRouter_return_fastest_pt_jou[] = "PyPTRouter.return_fastest_pt_journey_1to1"; -static const char __pyx_k_PyPTRouter_return_pt_journeys_1t[] = "PyPTRouter.return_pt_journeys_1to1"; -static const char __pyx_k_RAPTOR_router_not_initialized_Pl[] = "RAPTOR router not initialized. Please initialize first."; -static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static const char __pyx_k_source_station_departure_datetim[] = "source_station_departure_datetime"; -static const char __pyx_k_No_value_specified_for_struct_at_2[] = "No value specified for struct attribute 'month'"; -static const char __pyx_k_No_value_specified_for_struct_at_3[] = "No value specified for struct attribute 'day'"; -static const char __pyx_k_No_value_specified_for_struct_at_4[] = "No value specified for struct attribute 'weekday'"; -static const char __pyx_k_No_value_specified_for_struct_at_5[] = "No value specified for struct attribute 'hours'"; -static const char __pyx_k_No_value_specified_for_struct_at_6[] = "No value specified for struct attribute 'minutes'"; -static const char __pyx_k_No_value_specified_for_struct_at_7[] = "No value specified for struct attribute 'seconds'"; -static const char __pyx_k_No_value_specified_for_struct_at_8[] = "No value specified for struct attribute 'included_sources'"; -static const char __pyx_k_No_value_specified_for_struct_at_9[] = "No value specified for struct attribute 'included_targets'"; -static const char __pyx_k_No_value_specified_for_struct_at_10[] = "No value specified for struct attribute 'date'"; -static const char __pyx_k_No_value_specified_for_struct_at_11[] = "No value specified for struct attribute 'departure_time'"; -static const char __pyx_k_No_value_specified_for_struct_at_12[] = "No value specified for struct attribute 'max_transfers'"; -/* #### Code section: decls ### */ -static int __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_input_directory); /* proto */ -static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_tp_new_10PyPTRouter_PyPTRouter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -/* #### Code section: late_includes ### */ -/* #### Code section: module_state ### */ -typedef struct { - PyObject *__pyx_d; - PyObject *__pyx_b; - PyObject *__pyx_cython_runtime; - PyObject *__pyx_empty_tuple; - PyObject *__pyx_empty_bytes; - PyObject *__pyx_empty_unicode; - #ifdef __Pyx_CyFunction_USED - PyTypeObject *__pyx_CyFunctionType; - #endif - #ifdef __Pyx_FusedFunction_USED - PyTypeObject *__pyx_FusedFunctionType; - #endif - #ifdef __Pyx_Generator_USED - PyTypeObject *__pyx_GeneratorType; - #endif - #ifdef __Pyx_IterableCoroutine_USED - PyTypeObject *__pyx_IterableCoroutineType; - #endif - #ifdef __Pyx_Coroutine_USED - PyTypeObject *__pyx_CoroutineAwaitType; - #endif - #ifdef __Pyx_Coroutine_USED - PyTypeObject *__pyx_CoroutineType; - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - #endif - #if CYTHON_USE_MODULE_STATE - PyObject *__pyx_type_10PyPTRouter_PyPTRouter; - #endif - PyTypeObject *__pyx_ptype_10PyPTRouter_PyPTRouter; - PyObject *__pyx_kp_u_Expected_string_int_tuple_got; - PyObject *__pyx_n_s_KeyError; - PyObject *__pyx_n_s_MemoryError; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_10; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_11; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_12; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_2; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_3; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_4; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_5; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_6; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_7; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_8; - PyObject *__pyx_kp_s_No_value_specified_for_struct_at_9; - PyObject *__pyx_n_s_PyPTRouter; - PyObject *__pyx_n_s_PyPTRouter___reduce_cython; - PyObject *__pyx_n_s_PyPTRouter___setstate_cython; - PyObject *__pyx_n_s_PyPTRouter_construct_query; - PyObject *__pyx_kp_s_PyPTRouter_pyx; - PyObject *__pyx_n_s_PyPTRouter_return_fastest_pt_jou; - PyObject *__pyx_n_s_PyPTRouter_return_pt_journeys_1t; - PyObject *__pyx_kp_u_RAPTOR_router_not_initialized_Pl; - PyObject *__pyx_n_s_RuntimeError; - PyObject *__pyx_n_s_TypeError; - PyObject *__pyx_n_u_Unknown; - PyObject *__pyx_n_s_ValueError; - PyObject *__pyx_n_s__14; - PyObject *__pyx_kp_u__15; - PyObject *__pyx_n_s__28; - PyObject *__pyx_n_u_agency_name; - PyObject *__pyx_n_s_append; - PyObject *__pyx_n_u_arrival_time; - PyObject *__pyx_n_s_asyncio_coroutines; - PyObject *__pyx_n_s_cline_in_traceback; - PyObject *__pyx_n_s_construct_query; - PyObject *__pyx_n_u_current_day; - PyObject *__pyx_n_s_date; - PyObject *__pyx_n_s_datetime; - PyObject *__pyx_n_s_day; - PyObject *__pyx_n_u_day; - PyObject *__pyx_n_s_departure_time; - PyObject *__pyx_n_u_departure_time; - PyObject *__pyx_n_s_detailed; - PyObject *__pyx_kp_u_disable; - PyObject *__pyx_n_u_duration; - PyObject *__pyx_kp_u_enable; - PyObject *__pyx_n_s_encode; - PyObject *__pyx_n_u_from_stop_id; - PyObject *__pyx_kp_u_gc; - PyObject *__pyx_n_s_getstate; - PyObject *__pyx_n_s_hour; - PyObject *__pyx_n_s_hours; - PyObject *__pyx_n_s_i; - PyObject *__pyx_n_s_import; - PyObject *__pyx_n_s_inc_src; - PyObject *__pyx_n_s_inc_tgt; - PyObject *__pyx_n_s_included_sources; - PyObject *__pyx_n_s_included_targets; - PyObject *__pyx_n_s_initializing; - PyObject *__pyx_n_s_input_directory; - PyObject *__pyx_n_s_is_coroutine; - PyObject *__pyx_kp_u_isenabled; - PyObject *__pyx_n_s_journey; - PyObject *__pyx_n_s_journey_dict; - PyObject *__pyx_n_s_journey_opt; - PyObject *__pyx_n_s_journeys; - PyObject *__pyx_n_s_journeys_list; - PyObject *__pyx_n_s_json; - PyObject *__pyx_n_s_main; - PyObject *__pyx_n_s_max_transfers; - PyObject *__pyx_n_s_minute; - PyObject *__pyx_n_s_minutes; - PyObject *__pyx_n_s_month; - PyObject *__pyx_n_s_name; - PyObject *__pyx_n_u_next_day; - PyObject *__pyx_kp_s_no_default___reduce___due_to_non; - PyObject *__pyx_n_u_num_transfers; - PyObject *__pyx_n_s_pyx_state; - PyObject *__pyx_n_s_pyx_vtable; - PyObject *__pyx_n_s_query; - PyObject *__pyx_n_s_range; - PyObject *__pyx_n_s_reduce; - PyObject *__pyx_n_s_reduce_cython; - PyObject *__pyx_n_s_reduce_ex; - PyObject *__pyx_n_s_return_fastest_pt_journey_1to1; - PyObject *__pyx_n_s_return_pt_journeys_1to1; - PyObject *__pyx_n_s_second; - PyObject *__pyx_n_s_seconds; - PyObject *__pyx_n_s_self; - PyObject *__pyx_n_s_setstate; - PyObject *__pyx_n_s_setstate_cython; - PyObject *__pyx_n_s_source_station_departure_datetim; - PyObject *__pyx_n_u_source_station_departure_day; - PyObject *__pyx_n_u_source_station_departure_time; - PyObject *__pyx_n_u_source_transfer_time; - PyObject *__pyx_n_u_source_waiting_time; - PyObject *__pyx_n_s_spec; - PyObject *__pyx_n_s_src_vec; - PyObject *__pyx_n_u_steps; - PyObject *__pyx_kp_s_stringsource; - PyObject *__pyx_n_u_target_station_arrival_day; - PyObject *__pyx_n_u_target_station_arrival_time; - PyObject *__pyx_n_u_target_transfer_time; - PyObject *__pyx_n_s_test; - PyObject *__pyx_n_s_tgt_vec; - PyObject *__pyx_n_u_to_stop_id; - PyObject *__pyx_n_u_trip_id; - PyObject *__pyx_n_u_trip_time; - PyObject *__pyx_kp_u_utf_8; - PyObject *__pyx_n_u_walking; - PyObject *__pyx_n_s_weekday; - PyObject *__pyx_n_s_year; - PyObject *__pyx_int_neg_1; - PyObject *__pyx_tuple_; - PyObject *__pyx_tuple__2; - PyObject *__pyx_tuple__3; - PyObject *__pyx_tuple__4; - PyObject *__pyx_tuple__5; - PyObject *__pyx_tuple__6; - PyObject *__pyx_tuple__7; - PyObject *__pyx_tuple__8; - PyObject *__pyx_tuple__9; - PyObject *__pyx_tuple__10; - PyObject *__pyx_tuple__11; - PyObject *__pyx_tuple__12; - PyObject *__pyx_tuple__13; - PyObject *__pyx_tuple__16; - PyObject *__pyx_tuple__18; - PyObject *__pyx_tuple__19; - PyObject *__pyx_tuple__21; - PyObject *__pyx_tuple__22; - PyObject *__pyx_tuple__24; - PyObject *__pyx_tuple__26; - PyObject *__pyx_codeobj__17; - PyObject *__pyx_codeobj__20; - PyObject *__pyx_codeobj__23; - PyObject *__pyx_codeobj__25; - PyObject *__pyx_codeobj__27; -} __pyx_mstate; - -#if CYTHON_USE_MODULE_STATE -#ifdef __cplusplus -namespace { - extern struct PyModuleDef __pyx_moduledef; -} /* anonymous namespace */ -#else -static struct PyModuleDef __pyx_moduledef; -#endif - -#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o)) - -#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef))) - -#define __pyx_m (PyState_FindModule(&__pyx_moduledef)) -#else -static __pyx_mstate __pyx_mstate_global_static = -#ifdef __cplusplus - {}; -#else - {0}; -#endif -static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static; -#endif -/* #### Code section: module_state_clear ### */ -#if CYTHON_USE_MODULE_STATE -static int __pyx_m_clear(PyObject *m) { - __pyx_mstate *clear_module_state = __pyx_mstate(m); - if (!clear_module_state) return 0; - Py_CLEAR(clear_module_state->__pyx_d); - Py_CLEAR(clear_module_state->__pyx_b); - Py_CLEAR(clear_module_state->__pyx_cython_runtime); - Py_CLEAR(clear_module_state->__pyx_empty_tuple); - Py_CLEAR(clear_module_state->__pyx_empty_bytes); - Py_CLEAR(clear_module_state->__pyx_empty_unicode); - #ifdef __Pyx_CyFunction_USED - Py_CLEAR(clear_module_state->__pyx_CyFunctionType); - #endif - #ifdef __Pyx_FusedFunction_USED - Py_CLEAR(clear_module_state->__pyx_FusedFunctionType); - #endif - Py_CLEAR(clear_module_state->__pyx_ptype_10PyPTRouter_PyPTRouter); - Py_CLEAR(clear_module_state->__pyx_type_10PyPTRouter_PyPTRouter); - Py_CLEAR(clear_module_state->__pyx_kp_u_Expected_string_int_tuple_got); - Py_CLEAR(clear_module_state->__pyx_n_s_KeyError); - Py_CLEAR(clear_module_state->__pyx_n_s_MemoryError); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_10); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_11); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_12); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_2); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_3); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_4); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_5); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_6); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_7); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_8); - Py_CLEAR(clear_module_state->__pyx_kp_s_No_value_specified_for_struct_at_9); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter___reduce_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter___setstate_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_construct_query); - Py_CLEAR(clear_module_state->__pyx_kp_s_PyPTRouter_pyx); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_return_fastest_pt_jou); - Py_CLEAR(clear_module_state->__pyx_n_s_PyPTRouter_return_pt_journeys_1t); - Py_CLEAR(clear_module_state->__pyx_kp_u_RAPTOR_router_not_initialized_Pl); - Py_CLEAR(clear_module_state->__pyx_n_s_RuntimeError); - Py_CLEAR(clear_module_state->__pyx_n_s_TypeError); - Py_CLEAR(clear_module_state->__pyx_n_u_Unknown); - Py_CLEAR(clear_module_state->__pyx_n_s_ValueError); - Py_CLEAR(clear_module_state->__pyx_n_s__14); - Py_CLEAR(clear_module_state->__pyx_kp_u__15); - Py_CLEAR(clear_module_state->__pyx_n_s__28); - Py_CLEAR(clear_module_state->__pyx_n_u_agency_name); - Py_CLEAR(clear_module_state->__pyx_n_s_append); - Py_CLEAR(clear_module_state->__pyx_n_u_arrival_time); - Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines); - Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback); - Py_CLEAR(clear_module_state->__pyx_n_s_construct_query); - Py_CLEAR(clear_module_state->__pyx_n_u_current_day); - Py_CLEAR(clear_module_state->__pyx_n_s_date); - Py_CLEAR(clear_module_state->__pyx_n_s_datetime); - Py_CLEAR(clear_module_state->__pyx_n_s_day); - Py_CLEAR(clear_module_state->__pyx_n_u_day); - Py_CLEAR(clear_module_state->__pyx_n_s_departure_time); - Py_CLEAR(clear_module_state->__pyx_n_u_departure_time); - Py_CLEAR(clear_module_state->__pyx_n_s_detailed); - Py_CLEAR(clear_module_state->__pyx_kp_u_disable); - Py_CLEAR(clear_module_state->__pyx_n_u_duration); - Py_CLEAR(clear_module_state->__pyx_kp_u_enable); - Py_CLEAR(clear_module_state->__pyx_n_s_encode); - Py_CLEAR(clear_module_state->__pyx_n_u_from_stop_id); - Py_CLEAR(clear_module_state->__pyx_kp_u_gc); - Py_CLEAR(clear_module_state->__pyx_n_s_getstate); - Py_CLEAR(clear_module_state->__pyx_n_s_hour); - Py_CLEAR(clear_module_state->__pyx_n_s_hours); - Py_CLEAR(clear_module_state->__pyx_n_s_i); - Py_CLEAR(clear_module_state->__pyx_n_s_import); - Py_CLEAR(clear_module_state->__pyx_n_s_inc_src); - Py_CLEAR(clear_module_state->__pyx_n_s_inc_tgt); - Py_CLEAR(clear_module_state->__pyx_n_s_included_sources); - Py_CLEAR(clear_module_state->__pyx_n_s_included_targets); - Py_CLEAR(clear_module_state->__pyx_n_s_initializing); - Py_CLEAR(clear_module_state->__pyx_n_s_input_directory); - Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine); - Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled); - Py_CLEAR(clear_module_state->__pyx_n_s_journey); - Py_CLEAR(clear_module_state->__pyx_n_s_journey_dict); - Py_CLEAR(clear_module_state->__pyx_n_s_journey_opt); - Py_CLEAR(clear_module_state->__pyx_n_s_journeys); - Py_CLEAR(clear_module_state->__pyx_n_s_journeys_list); - Py_CLEAR(clear_module_state->__pyx_n_s_json); - Py_CLEAR(clear_module_state->__pyx_n_s_main); - Py_CLEAR(clear_module_state->__pyx_n_s_max_transfers); - Py_CLEAR(clear_module_state->__pyx_n_s_minute); - Py_CLEAR(clear_module_state->__pyx_n_s_minutes); - Py_CLEAR(clear_module_state->__pyx_n_s_month); - Py_CLEAR(clear_module_state->__pyx_n_s_name); - Py_CLEAR(clear_module_state->__pyx_n_u_next_day); - Py_CLEAR(clear_module_state->__pyx_kp_s_no_default___reduce___due_to_non); - Py_CLEAR(clear_module_state->__pyx_n_u_num_transfers); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_state); - Py_CLEAR(clear_module_state->__pyx_n_s_pyx_vtable); - Py_CLEAR(clear_module_state->__pyx_n_s_query); - Py_CLEAR(clear_module_state->__pyx_n_s_range); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_reduce_ex); - Py_CLEAR(clear_module_state->__pyx_n_s_return_fastest_pt_journey_1to1); - Py_CLEAR(clear_module_state->__pyx_n_s_return_pt_journeys_1to1); - Py_CLEAR(clear_module_state->__pyx_n_s_second); - Py_CLEAR(clear_module_state->__pyx_n_s_seconds); - Py_CLEAR(clear_module_state->__pyx_n_s_self); - Py_CLEAR(clear_module_state->__pyx_n_s_setstate); - Py_CLEAR(clear_module_state->__pyx_n_s_setstate_cython); - Py_CLEAR(clear_module_state->__pyx_n_s_source_station_departure_datetim); - Py_CLEAR(clear_module_state->__pyx_n_u_source_station_departure_day); - Py_CLEAR(clear_module_state->__pyx_n_u_source_station_departure_time); - Py_CLEAR(clear_module_state->__pyx_n_u_source_transfer_time); - Py_CLEAR(clear_module_state->__pyx_n_u_source_waiting_time); - Py_CLEAR(clear_module_state->__pyx_n_s_spec); - Py_CLEAR(clear_module_state->__pyx_n_s_src_vec); - Py_CLEAR(clear_module_state->__pyx_n_u_steps); - Py_CLEAR(clear_module_state->__pyx_kp_s_stringsource); - Py_CLEAR(clear_module_state->__pyx_n_u_target_station_arrival_day); - Py_CLEAR(clear_module_state->__pyx_n_u_target_station_arrival_time); - Py_CLEAR(clear_module_state->__pyx_n_u_target_transfer_time); - Py_CLEAR(clear_module_state->__pyx_n_s_test); - Py_CLEAR(clear_module_state->__pyx_n_s_tgt_vec); - Py_CLEAR(clear_module_state->__pyx_n_u_to_stop_id); - Py_CLEAR(clear_module_state->__pyx_n_u_trip_id); - Py_CLEAR(clear_module_state->__pyx_n_u_trip_time); - Py_CLEAR(clear_module_state->__pyx_kp_u_utf_8); - Py_CLEAR(clear_module_state->__pyx_n_u_walking); - Py_CLEAR(clear_module_state->__pyx_n_s_weekday); - Py_CLEAR(clear_module_state->__pyx_n_s_year); - Py_CLEAR(clear_module_state->__pyx_int_neg_1); - Py_CLEAR(clear_module_state->__pyx_tuple_); - Py_CLEAR(clear_module_state->__pyx_tuple__2); - Py_CLEAR(clear_module_state->__pyx_tuple__3); - Py_CLEAR(clear_module_state->__pyx_tuple__4); - Py_CLEAR(clear_module_state->__pyx_tuple__5); - Py_CLEAR(clear_module_state->__pyx_tuple__6); - Py_CLEAR(clear_module_state->__pyx_tuple__7); - Py_CLEAR(clear_module_state->__pyx_tuple__8); - Py_CLEAR(clear_module_state->__pyx_tuple__9); - Py_CLEAR(clear_module_state->__pyx_tuple__10); - Py_CLEAR(clear_module_state->__pyx_tuple__11); - Py_CLEAR(clear_module_state->__pyx_tuple__12); - Py_CLEAR(clear_module_state->__pyx_tuple__13); - Py_CLEAR(clear_module_state->__pyx_tuple__16); - Py_CLEAR(clear_module_state->__pyx_tuple__18); - Py_CLEAR(clear_module_state->__pyx_tuple__19); - Py_CLEAR(clear_module_state->__pyx_tuple__21); - Py_CLEAR(clear_module_state->__pyx_tuple__22); - Py_CLEAR(clear_module_state->__pyx_tuple__24); - Py_CLEAR(clear_module_state->__pyx_tuple__26); - Py_CLEAR(clear_module_state->__pyx_codeobj__17); - Py_CLEAR(clear_module_state->__pyx_codeobj__20); - Py_CLEAR(clear_module_state->__pyx_codeobj__23); - Py_CLEAR(clear_module_state->__pyx_codeobj__25); - Py_CLEAR(clear_module_state->__pyx_codeobj__27); - return 0; -} -#endif -/* #### Code section: module_state_traverse ### */ -#if CYTHON_USE_MODULE_STATE -static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { - __pyx_mstate *traverse_module_state = __pyx_mstate(m); - if (!traverse_module_state) return 0; - Py_VISIT(traverse_module_state->__pyx_d); - Py_VISIT(traverse_module_state->__pyx_b); - Py_VISIT(traverse_module_state->__pyx_cython_runtime); - Py_VISIT(traverse_module_state->__pyx_empty_tuple); - Py_VISIT(traverse_module_state->__pyx_empty_bytes); - Py_VISIT(traverse_module_state->__pyx_empty_unicode); - #ifdef __Pyx_CyFunction_USED - Py_VISIT(traverse_module_state->__pyx_CyFunctionType); - #endif - #ifdef __Pyx_FusedFunction_USED - Py_VISIT(traverse_module_state->__pyx_FusedFunctionType); - #endif - Py_VISIT(traverse_module_state->__pyx_ptype_10PyPTRouter_PyPTRouter); - Py_VISIT(traverse_module_state->__pyx_type_10PyPTRouter_PyPTRouter); - Py_VISIT(traverse_module_state->__pyx_kp_u_Expected_string_int_tuple_got); - Py_VISIT(traverse_module_state->__pyx_n_s_KeyError); - Py_VISIT(traverse_module_state->__pyx_n_s_MemoryError); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_10); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_11); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_12); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_2); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_3); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_4); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_5); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_6); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_7); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_8); - Py_VISIT(traverse_module_state->__pyx_kp_s_No_value_specified_for_struct_at_9); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter___reduce_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter___setstate_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_construct_query); - Py_VISIT(traverse_module_state->__pyx_kp_s_PyPTRouter_pyx); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_return_fastest_pt_jou); - Py_VISIT(traverse_module_state->__pyx_n_s_PyPTRouter_return_pt_journeys_1t); - Py_VISIT(traverse_module_state->__pyx_kp_u_RAPTOR_router_not_initialized_Pl); - Py_VISIT(traverse_module_state->__pyx_n_s_RuntimeError); - Py_VISIT(traverse_module_state->__pyx_n_s_TypeError); - Py_VISIT(traverse_module_state->__pyx_n_u_Unknown); - Py_VISIT(traverse_module_state->__pyx_n_s_ValueError); - Py_VISIT(traverse_module_state->__pyx_n_s__14); - Py_VISIT(traverse_module_state->__pyx_kp_u__15); - Py_VISIT(traverse_module_state->__pyx_n_s__28); - Py_VISIT(traverse_module_state->__pyx_n_u_agency_name); - Py_VISIT(traverse_module_state->__pyx_n_s_append); - Py_VISIT(traverse_module_state->__pyx_n_u_arrival_time); - Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines); - Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback); - Py_VISIT(traverse_module_state->__pyx_n_s_construct_query); - Py_VISIT(traverse_module_state->__pyx_n_u_current_day); - Py_VISIT(traverse_module_state->__pyx_n_s_date); - Py_VISIT(traverse_module_state->__pyx_n_s_datetime); - Py_VISIT(traverse_module_state->__pyx_n_s_day); - Py_VISIT(traverse_module_state->__pyx_n_u_day); - Py_VISIT(traverse_module_state->__pyx_n_s_departure_time); - Py_VISIT(traverse_module_state->__pyx_n_u_departure_time); - Py_VISIT(traverse_module_state->__pyx_n_s_detailed); - Py_VISIT(traverse_module_state->__pyx_kp_u_disable); - Py_VISIT(traverse_module_state->__pyx_n_u_duration); - Py_VISIT(traverse_module_state->__pyx_kp_u_enable); - Py_VISIT(traverse_module_state->__pyx_n_s_encode); - Py_VISIT(traverse_module_state->__pyx_n_u_from_stop_id); - Py_VISIT(traverse_module_state->__pyx_kp_u_gc); - Py_VISIT(traverse_module_state->__pyx_n_s_getstate); - Py_VISIT(traverse_module_state->__pyx_n_s_hour); - Py_VISIT(traverse_module_state->__pyx_n_s_hours); - Py_VISIT(traverse_module_state->__pyx_n_s_i); - Py_VISIT(traverse_module_state->__pyx_n_s_import); - Py_VISIT(traverse_module_state->__pyx_n_s_inc_src); - Py_VISIT(traverse_module_state->__pyx_n_s_inc_tgt); - Py_VISIT(traverse_module_state->__pyx_n_s_included_sources); - Py_VISIT(traverse_module_state->__pyx_n_s_included_targets); - Py_VISIT(traverse_module_state->__pyx_n_s_initializing); - Py_VISIT(traverse_module_state->__pyx_n_s_input_directory); - Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine); - Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled); - Py_VISIT(traverse_module_state->__pyx_n_s_journey); - Py_VISIT(traverse_module_state->__pyx_n_s_journey_dict); - Py_VISIT(traverse_module_state->__pyx_n_s_journey_opt); - Py_VISIT(traverse_module_state->__pyx_n_s_journeys); - Py_VISIT(traverse_module_state->__pyx_n_s_journeys_list); - Py_VISIT(traverse_module_state->__pyx_n_s_json); - Py_VISIT(traverse_module_state->__pyx_n_s_main); - Py_VISIT(traverse_module_state->__pyx_n_s_max_transfers); - Py_VISIT(traverse_module_state->__pyx_n_s_minute); - Py_VISIT(traverse_module_state->__pyx_n_s_minutes); - Py_VISIT(traverse_module_state->__pyx_n_s_month); - Py_VISIT(traverse_module_state->__pyx_n_s_name); - Py_VISIT(traverse_module_state->__pyx_n_u_next_day); - Py_VISIT(traverse_module_state->__pyx_kp_s_no_default___reduce___due_to_non); - Py_VISIT(traverse_module_state->__pyx_n_u_num_transfers); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_state); - Py_VISIT(traverse_module_state->__pyx_n_s_pyx_vtable); - Py_VISIT(traverse_module_state->__pyx_n_s_query); - Py_VISIT(traverse_module_state->__pyx_n_s_range); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_reduce_ex); - Py_VISIT(traverse_module_state->__pyx_n_s_return_fastest_pt_journey_1to1); - Py_VISIT(traverse_module_state->__pyx_n_s_return_pt_journeys_1to1); - Py_VISIT(traverse_module_state->__pyx_n_s_second); - Py_VISIT(traverse_module_state->__pyx_n_s_seconds); - Py_VISIT(traverse_module_state->__pyx_n_s_self); - Py_VISIT(traverse_module_state->__pyx_n_s_setstate); - Py_VISIT(traverse_module_state->__pyx_n_s_setstate_cython); - Py_VISIT(traverse_module_state->__pyx_n_s_source_station_departure_datetim); - Py_VISIT(traverse_module_state->__pyx_n_u_source_station_departure_day); - Py_VISIT(traverse_module_state->__pyx_n_u_source_station_departure_time); - Py_VISIT(traverse_module_state->__pyx_n_u_source_transfer_time); - Py_VISIT(traverse_module_state->__pyx_n_u_source_waiting_time); - Py_VISIT(traverse_module_state->__pyx_n_s_spec); - Py_VISIT(traverse_module_state->__pyx_n_s_src_vec); - Py_VISIT(traverse_module_state->__pyx_n_u_steps); - Py_VISIT(traverse_module_state->__pyx_kp_s_stringsource); - Py_VISIT(traverse_module_state->__pyx_n_u_target_station_arrival_day); - Py_VISIT(traverse_module_state->__pyx_n_u_target_station_arrival_time); - Py_VISIT(traverse_module_state->__pyx_n_u_target_transfer_time); - Py_VISIT(traverse_module_state->__pyx_n_s_test); - Py_VISIT(traverse_module_state->__pyx_n_s_tgt_vec); - Py_VISIT(traverse_module_state->__pyx_n_u_to_stop_id); - Py_VISIT(traverse_module_state->__pyx_n_u_trip_id); - Py_VISIT(traverse_module_state->__pyx_n_u_trip_time); - Py_VISIT(traverse_module_state->__pyx_kp_u_utf_8); - Py_VISIT(traverse_module_state->__pyx_n_u_walking); - Py_VISIT(traverse_module_state->__pyx_n_s_weekday); - Py_VISIT(traverse_module_state->__pyx_n_s_year); - Py_VISIT(traverse_module_state->__pyx_int_neg_1); - Py_VISIT(traverse_module_state->__pyx_tuple_); - Py_VISIT(traverse_module_state->__pyx_tuple__2); - Py_VISIT(traverse_module_state->__pyx_tuple__3); - Py_VISIT(traverse_module_state->__pyx_tuple__4); - Py_VISIT(traverse_module_state->__pyx_tuple__5); - Py_VISIT(traverse_module_state->__pyx_tuple__6); - Py_VISIT(traverse_module_state->__pyx_tuple__7); - Py_VISIT(traverse_module_state->__pyx_tuple__8); - Py_VISIT(traverse_module_state->__pyx_tuple__9); - Py_VISIT(traverse_module_state->__pyx_tuple__10); - Py_VISIT(traverse_module_state->__pyx_tuple__11); - Py_VISIT(traverse_module_state->__pyx_tuple__12); - Py_VISIT(traverse_module_state->__pyx_tuple__13); - Py_VISIT(traverse_module_state->__pyx_tuple__16); - Py_VISIT(traverse_module_state->__pyx_tuple__18); - Py_VISIT(traverse_module_state->__pyx_tuple__19); - Py_VISIT(traverse_module_state->__pyx_tuple__21); - Py_VISIT(traverse_module_state->__pyx_tuple__22); - Py_VISIT(traverse_module_state->__pyx_tuple__24); - Py_VISIT(traverse_module_state->__pyx_tuple__26); - Py_VISIT(traverse_module_state->__pyx_codeobj__17); - Py_VISIT(traverse_module_state->__pyx_codeobj__20); - Py_VISIT(traverse_module_state->__pyx_codeobj__23); - Py_VISIT(traverse_module_state->__pyx_codeobj__25); - Py_VISIT(traverse_module_state->__pyx_codeobj__27); - return 0; -} -#endif -/* #### Code section: module_state_defines ### */ -#define __pyx_d __pyx_mstate_global->__pyx_d -#define __pyx_b __pyx_mstate_global->__pyx_b -#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime -#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple -#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes -#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode -#ifdef __Pyx_CyFunction_USED -#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType -#endif -#ifdef __Pyx_FusedFunction_USED -#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType -#endif -#ifdef __Pyx_Generator_USED -#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType -#endif -#ifdef __Pyx_IterableCoroutine_USED -#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType -#endif -#ifdef __Pyx_Coroutine_USED -#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType -#endif -#ifdef __Pyx_Coroutine_USED -#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#endif -#if CYTHON_USE_MODULE_STATE -#define __pyx_type_10PyPTRouter_PyPTRouter __pyx_mstate_global->__pyx_type_10PyPTRouter_PyPTRouter -#endif -#define __pyx_ptype_10PyPTRouter_PyPTRouter __pyx_mstate_global->__pyx_ptype_10PyPTRouter_PyPTRouter -#define __pyx_kp_u_Expected_string_int_tuple_got __pyx_mstate_global->__pyx_kp_u_Expected_string_int_tuple_got -#define __pyx_n_s_KeyError __pyx_mstate_global->__pyx_n_s_KeyError -#define __pyx_n_s_MemoryError __pyx_mstate_global->__pyx_n_s_MemoryError -#define __pyx_kp_s_No_value_specified_for_struct_at __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at -#define __pyx_kp_s_No_value_specified_for_struct_at_10 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_10 -#define __pyx_kp_s_No_value_specified_for_struct_at_11 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_11 -#define __pyx_kp_s_No_value_specified_for_struct_at_12 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_12 -#define __pyx_kp_s_No_value_specified_for_struct_at_2 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_2 -#define __pyx_kp_s_No_value_specified_for_struct_at_3 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_3 -#define __pyx_kp_s_No_value_specified_for_struct_at_4 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_4 -#define __pyx_kp_s_No_value_specified_for_struct_at_5 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_5 -#define __pyx_kp_s_No_value_specified_for_struct_at_6 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_6 -#define __pyx_kp_s_No_value_specified_for_struct_at_7 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_7 -#define __pyx_kp_s_No_value_specified_for_struct_at_8 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_8 -#define __pyx_kp_s_No_value_specified_for_struct_at_9 __pyx_mstate_global->__pyx_kp_s_No_value_specified_for_struct_at_9 -#define __pyx_n_s_PyPTRouter __pyx_mstate_global->__pyx_n_s_PyPTRouter -#define __pyx_n_s_PyPTRouter___reduce_cython __pyx_mstate_global->__pyx_n_s_PyPTRouter___reduce_cython -#define __pyx_n_s_PyPTRouter___setstate_cython __pyx_mstate_global->__pyx_n_s_PyPTRouter___setstate_cython -#define __pyx_n_s_PyPTRouter_construct_query __pyx_mstate_global->__pyx_n_s_PyPTRouter_construct_query -#define __pyx_kp_s_PyPTRouter_pyx __pyx_mstate_global->__pyx_kp_s_PyPTRouter_pyx -#define __pyx_n_s_PyPTRouter_return_fastest_pt_jou __pyx_mstate_global->__pyx_n_s_PyPTRouter_return_fastest_pt_jou -#define __pyx_n_s_PyPTRouter_return_pt_journeys_1t __pyx_mstate_global->__pyx_n_s_PyPTRouter_return_pt_journeys_1t -#define __pyx_kp_u_RAPTOR_router_not_initialized_Pl __pyx_mstate_global->__pyx_kp_u_RAPTOR_router_not_initialized_Pl -#define __pyx_n_s_RuntimeError __pyx_mstate_global->__pyx_n_s_RuntimeError -#define __pyx_n_s_TypeError __pyx_mstate_global->__pyx_n_s_TypeError -#define __pyx_n_u_Unknown __pyx_mstate_global->__pyx_n_u_Unknown -#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError -#define __pyx_n_s__14 __pyx_mstate_global->__pyx_n_s__14 -#define __pyx_kp_u__15 __pyx_mstate_global->__pyx_kp_u__15 -#define __pyx_n_s__28 __pyx_mstate_global->__pyx_n_s__28 -#define __pyx_n_u_agency_name __pyx_mstate_global->__pyx_n_u_agency_name -#define __pyx_n_s_append __pyx_mstate_global->__pyx_n_s_append -#define __pyx_n_u_arrival_time __pyx_mstate_global->__pyx_n_u_arrival_time -#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines -#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback -#define __pyx_n_s_construct_query __pyx_mstate_global->__pyx_n_s_construct_query -#define __pyx_n_u_current_day __pyx_mstate_global->__pyx_n_u_current_day -#define __pyx_n_s_date __pyx_mstate_global->__pyx_n_s_date -#define __pyx_n_s_datetime __pyx_mstate_global->__pyx_n_s_datetime -#define __pyx_n_s_day __pyx_mstate_global->__pyx_n_s_day -#define __pyx_n_u_day __pyx_mstate_global->__pyx_n_u_day -#define __pyx_n_s_departure_time __pyx_mstate_global->__pyx_n_s_departure_time -#define __pyx_n_u_departure_time __pyx_mstate_global->__pyx_n_u_departure_time -#define __pyx_n_s_detailed __pyx_mstate_global->__pyx_n_s_detailed -#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable -#define __pyx_n_u_duration __pyx_mstate_global->__pyx_n_u_duration -#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable -#define __pyx_n_s_encode __pyx_mstate_global->__pyx_n_s_encode -#define __pyx_n_u_from_stop_id __pyx_mstate_global->__pyx_n_u_from_stop_id -#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc -#define __pyx_n_s_getstate __pyx_mstate_global->__pyx_n_s_getstate -#define __pyx_n_s_hour __pyx_mstate_global->__pyx_n_s_hour -#define __pyx_n_s_hours __pyx_mstate_global->__pyx_n_s_hours -#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i -#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import -#define __pyx_n_s_inc_src __pyx_mstate_global->__pyx_n_s_inc_src -#define __pyx_n_s_inc_tgt __pyx_mstate_global->__pyx_n_s_inc_tgt -#define __pyx_n_s_included_sources __pyx_mstate_global->__pyx_n_s_included_sources -#define __pyx_n_s_included_targets __pyx_mstate_global->__pyx_n_s_included_targets -#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing -#define __pyx_n_s_input_directory __pyx_mstate_global->__pyx_n_s_input_directory -#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine -#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled -#define __pyx_n_s_journey __pyx_mstate_global->__pyx_n_s_journey -#define __pyx_n_s_journey_dict __pyx_mstate_global->__pyx_n_s_journey_dict -#define __pyx_n_s_journey_opt __pyx_mstate_global->__pyx_n_s_journey_opt -#define __pyx_n_s_journeys __pyx_mstate_global->__pyx_n_s_journeys -#define __pyx_n_s_journeys_list __pyx_mstate_global->__pyx_n_s_journeys_list -#define __pyx_n_s_json __pyx_mstate_global->__pyx_n_s_json -#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main -#define __pyx_n_s_max_transfers __pyx_mstate_global->__pyx_n_s_max_transfers -#define __pyx_n_s_minute __pyx_mstate_global->__pyx_n_s_minute -#define __pyx_n_s_minutes __pyx_mstate_global->__pyx_n_s_minutes -#define __pyx_n_s_month __pyx_mstate_global->__pyx_n_s_month -#define __pyx_n_s_name __pyx_mstate_global->__pyx_n_s_name -#define __pyx_n_u_next_day __pyx_mstate_global->__pyx_n_u_next_day -#define __pyx_kp_s_no_default___reduce___due_to_non __pyx_mstate_global->__pyx_kp_s_no_default___reduce___due_to_non -#define __pyx_n_u_num_transfers __pyx_mstate_global->__pyx_n_u_num_transfers -#define __pyx_n_s_pyx_state __pyx_mstate_global->__pyx_n_s_pyx_state -#define __pyx_n_s_pyx_vtable __pyx_mstate_global->__pyx_n_s_pyx_vtable -#define __pyx_n_s_query __pyx_mstate_global->__pyx_n_s_query -#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range -#define __pyx_n_s_reduce __pyx_mstate_global->__pyx_n_s_reduce -#define __pyx_n_s_reduce_cython __pyx_mstate_global->__pyx_n_s_reduce_cython -#define __pyx_n_s_reduce_ex __pyx_mstate_global->__pyx_n_s_reduce_ex -#define __pyx_n_s_return_fastest_pt_journey_1to1 __pyx_mstate_global->__pyx_n_s_return_fastest_pt_journey_1to1 -#define __pyx_n_s_return_pt_journeys_1to1 __pyx_mstate_global->__pyx_n_s_return_pt_journeys_1to1 -#define __pyx_n_s_second __pyx_mstate_global->__pyx_n_s_second -#define __pyx_n_s_seconds __pyx_mstate_global->__pyx_n_s_seconds -#define __pyx_n_s_self __pyx_mstate_global->__pyx_n_s_self -#define __pyx_n_s_setstate __pyx_mstate_global->__pyx_n_s_setstate -#define __pyx_n_s_setstate_cython __pyx_mstate_global->__pyx_n_s_setstate_cython -#define __pyx_n_s_source_station_departure_datetim __pyx_mstate_global->__pyx_n_s_source_station_departure_datetim -#define __pyx_n_u_source_station_departure_day __pyx_mstate_global->__pyx_n_u_source_station_departure_day -#define __pyx_n_u_source_station_departure_time __pyx_mstate_global->__pyx_n_u_source_station_departure_time -#define __pyx_n_u_source_transfer_time __pyx_mstate_global->__pyx_n_u_source_transfer_time -#define __pyx_n_u_source_waiting_time __pyx_mstate_global->__pyx_n_u_source_waiting_time -#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec -#define __pyx_n_s_src_vec __pyx_mstate_global->__pyx_n_s_src_vec -#define __pyx_n_u_steps __pyx_mstate_global->__pyx_n_u_steps -#define __pyx_kp_s_stringsource __pyx_mstate_global->__pyx_kp_s_stringsource -#define __pyx_n_u_target_station_arrival_day __pyx_mstate_global->__pyx_n_u_target_station_arrival_day -#define __pyx_n_u_target_station_arrival_time __pyx_mstate_global->__pyx_n_u_target_station_arrival_time -#define __pyx_n_u_target_transfer_time __pyx_mstate_global->__pyx_n_u_target_transfer_time -#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test -#define __pyx_n_s_tgt_vec __pyx_mstate_global->__pyx_n_s_tgt_vec -#define __pyx_n_u_to_stop_id __pyx_mstate_global->__pyx_n_u_to_stop_id -#define __pyx_n_u_trip_id __pyx_mstate_global->__pyx_n_u_trip_id -#define __pyx_n_u_trip_time __pyx_mstate_global->__pyx_n_u_trip_time -#define __pyx_kp_u_utf_8 __pyx_mstate_global->__pyx_kp_u_utf_8 -#define __pyx_n_u_walking __pyx_mstate_global->__pyx_n_u_walking -#define __pyx_n_s_weekday __pyx_mstate_global->__pyx_n_s_weekday -#define __pyx_n_s_year __pyx_mstate_global->__pyx_n_s_year -#define __pyx_int_neg_1 __pyx_mstate_global->__pyx_int_neg_1 -#define __pyx_tuple_ __pyx_mstate_global->__pyx_tuple_ -#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2 -#define __pyx_tuple__3 __pyx_mstate_global->__pyx_tuple__3 -#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4 -#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5 -#define __pyx_tuple__6 __pyx_mstate_global->__pyx_tuple__6 -#define __pyx_tuple__7 __pyx_mstate_global->__pyx_tuple__7 -#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8 -#define __pyx_tuple__9 __pyx_mstate_global->__pyx_tuple__9 -#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10 -#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11 -#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12 -#define __pyx_tuple__13 __pyx_mstate_global->__pyx_tuple__13 -#define __pyx_tuple__16 __pyx_mstate_global->__pyx_tuple__16 -#define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18 -#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19 -#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21 -#define __pyx_tuple__22 __pyx_mstate_global->__pyx_tuple__22 -#define __pyx_tuple__24 __pyx_mstate_global->__pyx_tuple__24 -#define __pyx_tuple__26 __pyx_mstate_global->__pyx_tuple__26 -#define __pyx_codeobj__17 __pyx_mstate_global->__pyx_codeobj__17 -#define __pyx_codeobj__20 __pyx_mstate_global->__pyx_codeobj__20 -#define __pyx_codeobj__23 __pyx_mstate_global->__pyx_codeobj__23 -#define __pyx_codeobj__25 __pyx_mstate_global->__pyx_codeobj__25 -#define __pyx_codeobj__27 __pyx_mstate_global->__pyx_codeobj__27 -/* #### Code section: module_code ### */ - -/* "string.from_py":13 - * - * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") - * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< - * cdef Py_ssize_t length = 0 - * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) - */ - -static std::string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(PyObject *__pyx_v_o) { - Py_ssize_t __pyx_v_length; - char const *__pyx_v_data; - std::string __pyx_r; - char const *__pyx_t_1; - std::string __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - - /* "string.from_py":14 - * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") - * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: - * cdef Py_ssize_t length = 0 # <<<<<<<<<<<<<< - * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) - * return string(data, length) - */ - __pyx_v_length = 0; - - /* "string.from_py":15 - * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: - * cdef Py_ssize_t length = 0 - * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) # <<<<<<<<<<<<<< - * return string(data, length) - * - */ - __pyx_t_1 = __Pyx_PyObject_AsStringAndSize(__pyx_v_o, (&__pyx_v_length)); if (unlikely(__pyx_t_1 == ((char const *)NULL))) __PYX_ERR(1, 15, __pyx_L1_error) - __pyx_v_data = __pyx_t_1; - - /* "string.from_py":16 - * cdef Py_ssize_t length = 0 - * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) - * return string(data, length) # <<<<<<<<<<<<<< - * - * - */ - try { - __pyx_t_2 = std::string(__pyx_v_data, __pyx_v_length); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(1, 16, __pyx_L1_error) - } - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "string.from_py":13 - * - * @cname("__pyx_convert_string_from_py_6libcpp_6string_std__in_string") - * cdef string __pyx_convert_string_from_py_6libcpp_6string_std__in_string(object o) except *: # <<<<<<<<<<<<<< - * cdef Py_ssize_t length = 0 - * cdef const char* data = __Pyx_PyObject_AsStringAndSize(o, &length) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("string.from_py.__pyx_convert_string_from_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - return __pyx_r; -} - -/* "string.to_py":31 - * - * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - -static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string", 1); - - /* "string.to_py":32 - * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): - * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< - * cdef extern from *: - * cdef object __Pyx_PyUnicode_FromStringAndSize(const char*, size_t) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 32, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "string.to_py":31 - * - * @cname("__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyObject_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("string.to_py.__pyx_convert_PyObject_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "string.to_py":37 - * - * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - -static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string", 1); - - /* "string.to_py":38 - * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): - * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< - * cdef extern from *: - * cdef object __Pyx_PyStr_FromStringAndSize(const char*, size_t) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyUnicode_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 38, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "string.to_py":37 - * - * @cname("__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyUnicode_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("string.to_py.__pyx_convert_PyUnicode_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "string.to_py":43 - * - * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - -static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string", 1); - - /* "string.to_py":44 - * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): - * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< - * cdef extern from *: - * cdef object __Pyx_PyBytes_FromStringAndSize(const char*, size_t) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyStr_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 44, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "string.to_py":43 - * - * @cname("__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyStr_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("string.to_py.__pyx_convert_PyStr_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "string.to_py":49 - * - * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - -static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string", 1); - - /* "string.to_py":50 - * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): - * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< - * cdef extern from *: - * cdef object __Pyx_PyByteArray_FromStringAndSize(const char*, size_t) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 50, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "string.to_py":49 - * - * @cname("__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyBytes_FromStringAndSize(s.data(), s.size()) - * cdef extern from *: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("string.to_py.__pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "string.to_py":55 - * - * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) - * - */ - -static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(std::string const &__pyx_v_s) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string", 1); - - /* "string.to_py":56 - * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): - * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) # <<<<<<<<<<<<<< - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyByteArray_FromStringAndSize(__pyx_v_s.data(), __pyx_v_s.size()); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "string.to_py":55 - * - * @cname("__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string") - * cdef inline object __pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string(const string& s): # <<<<<<<<<<<<<< - * return __Pyx_PyByteArray_FromStringAndSize(s.data(), s.size()) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("string.to_py.__pyx_convert_PyByteArray_string_to_py_6libcpp_6string_std__in_string", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "pair.to_py":190 - * - * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") - * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): # <<<<<<<<<<<<<< - * return p.first, p.second - * - */ - -static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____int(std::pair const &__pyx_v_p) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_pair_to_py_std_3a__3a_string____int", 1); - - /* "pair.to_py":191 - * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") - * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): - * return p.first, p.second # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_6libcpp_6string_std__in_string(__pyx_v_p.first); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 191, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_p.second); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 191, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 191, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_1); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1)) __PYX_ERR(1, 191, __pyx_L1_error); - __Pyx_GIVEREF(__pyx_t_2); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2)) __PYX_ERR(1, 191, __pyx_L1_error); - __pyx_t_1 = 0; - __pyx_t_2 = 0; - __pyx_r = __pyx_t_3; - __pyx_t_3 = 0; - goto __pyx_L0; - - /* "pair.to_py":190 - * - * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____int") - * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____int(const pair[X,Y]& p): # <<<<<<<<<<<<<< - * return p.first, p.second - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("pair.to_py.__pyx_convert_pair_to_py_std_3a__3a_string____int", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "vector.to_py":66 - * - * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): # <<<<<<<<<<<<<< - * if v.size() > PY_SSIZE_T_MAX: - * raise MemoryError() - */ - -static PyObject *__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(std::vector > const &__pyx_v_v) { - Py_ssize_t __pyx_v_v_size_signed; - PyObject *__pyx_v_o = NULL; - Py_ssize_t __pyx_v_i; - PyObject *__pyx_v_item = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", 1); - - /* "vector.to_py":67 - * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): - * if v.size() > PY_SSIZE_T_MAX: # <<<<<<<<<<<<<< - * raise MemoryError() - * v_size_signed = v.size() - */ - __pyx_t_1 = (__pyx_v_v.size() > ((size_t)PY_SSIZE_T_MAX)); - if (unlikely(__pyx_t_1)) { - - /* "vector.to_py":68 - * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): - * if v.size() > PY_SSIZE_T_MAX: - * raise MemoryError() # <<<<<<<<<<<<<< - * v_size_signed = v.size() - * - */ - PyErr_NoMemory(); __PYX_ERR(1, 68, __pyx_L1_error) - - /* "vector.to_py":67 - * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): - * if v.size() > PY_SSIZE_T_MAX: # <<<<<<<<<<<<<< - * raise MemoryError() - * v_size_signed = v.size() - */ - } - - /* "vector.to_py":69 - * if v.size() > PY_SSIZE_T_MAX: - * raise MemoryError() - * v_size_signed = v.size() # <<<<<<<<<<<<<< - * - * o = PyList_New(v_size_signed) - */ - __pyx_v_v_size_signed = ((Py_ssize_t)__pyx_v_v.size()); - - /* "vector.to_py":71 - * v_size_signed = v.size() - * - * o = PyList_New(v_size_signed) # <<<<<<<<<<<<<< - * - * cdef Py_ssize_t i - */ - __pyx_t_2 = PyList_New(__pyx_v_v_size_signed); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_o = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "vector.to_py":76 - * cdef object item - * - * for i in range(v_size_signed): # <<<<<<<<<<<<<< - * item = v[i] - * Py_INCREF(item) - */ - __pyx_t_3 = __pyx_v_v_size_signed; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "vector.to_py":77 - * - * for i in range(v_size_signed): - * item = v[i] # <<<<<<<<<<<<<< - * Py_INCREF(item) - * PyList_SET_ITEM(o, i, item) - */ - __pyx_t_2 = __pyx_convert_pair_to_py_std_3a__3a_string____int((__pyx_v_v[__pyx_v_i])); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 77, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_2); - __pyx_t_2 = 0; - - /* "vector.to_py":78 - * for i in range(v_size_signed): - * item = v[i] - * Py_INCREF(item) # <<<<<<<<<<<<<< - * PyList_SET_ITEM(o, i, item) - * - */ - Py_INCREF(__pyx_v_item); - - /* "vector.to_py":79 - * item = v[i] - * Py_INCREF(item) - * PyList_SET_ITEM(o, i, item) # <<<<<<<<<<<<<< - * - * return o - */ - PyList_SET_ITEM(__pyx_v_o, __pyx_v_i, __pyx_v_item); - } - - /* "vector.to_py":81 - * PyList_SET_ITEM(o, i, item) - * - * return o # <<<<<<<<<<<<<< - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_o); - __pyx_r = __pyx_v_o; - goto __pyx_L0; - - /* "vector.to_py":66 - * - * @cname("__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef object __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(const vector[X]& v): # <<<<<<<<<<<<<< - * if v.size() > PY_SSIZE_T_MAX: - * raise MemoryError() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("vector.to_py.__pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_o); - __Pyx_XDECREF(__pyx_v_item); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "pair.from_py":177 - * - * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") - * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: # <<<<<<<<<<<<<< - * x, y = o - * return pair[X,Y](x, y) - */ - -static std::pair __pyx_convert_pair_from_py_std_3a__3a_string__and_int(PyObject *__pyx_v_o) { - PyObject *__pyx_v_x = NULL; - PyObject *__pyx_v_y = NULL; - std::pair __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *(*__pyx_t_4)(PyObject *); - std::string __pyx_t_5; - int __pyx_t_6; - std::pair __pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_pair_from_py_std_3a__3a_string__and_int", 1); - - /* "pair.from_py":178 - * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") - * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: - * x, y = o # <<<<<<<<<<<<<< - * return pair[X,Y](x, y) - * - */ - if ((likely(PyTuple_CheckExact(__pyx_v_o))) || (PyList_CheckExact(__pyx_v_o))) { - PyObject* sequence = __pyx_v_o; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(1, 178, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); - } else { - __pyx_t_1 = PyList_GET_ITEM(sequence, 0); - __pyx_t_2 = PyList_GET_ITEM(sequence, 1); - } - __Pyx_INCREF(__pyx_t_1); - __Pyx_INCREF(__pyx_t_2); - #else - __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 178, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 178, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - #endif - } else { - Py_ssize_t index = -1; - __pyx_t_3 = PyObject_GetIter(__pyx_v_o); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 178, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); - index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed; - __Pyx_GOTREF(__pyx_t_1); - index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed; - __Pyx_GOTREF(__pyx_t_2); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) __PYX_ERR(1, 178, __pyx_L1_error) - __pyx_t_4 = NULL; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L4_unpacking_done; - __pyx_L3_unpacking_failed:; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_4 = NULL; - if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(1, 178, __pyx_L1_error) - __pyx_L4_unpacking_done:; - } - __pyx_v_x = __pyx_t_1; - __pyx_t_1 = 0; - __pyx_v_y = __pyx_t_2; - __pyx_t_2 = 0; - - /* "pair.from_py":179 - * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: - * x, y = o - * return pair[X,Y](x, y) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_5 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_v_x); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 179, __pyx_L1_error) - __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_v_y); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 179, __pyx_L1_error) - try { - __pyx_t_7 = std::pair (((std::string)__pyx_t_5), ((int)__pyx_t_6)); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(1, 179, __pyx_L1_error) - } - __pyx_r = __pyx_t_7; - goto __pyx_L0; - - /* "pair.from_py":177 - * - * @cname("__pyx_convert_pair_from_py_std_3a__3a_string__and_int") - * cdef pair[X,Y] __pyx_convert_pair_from_py_std_3a__3a_string__and_int(object o) except *: # <<<<<<<<<<<<<< - * x, y = o - * return pair[X,Y](x, y) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("pair.from_py.__pyx_convert_pair_from_py_std_3a__3a_string__and_int", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_x); - __Pyx_XDECREF(__pyx_v_y); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "vector.from_py":45 - * - * @cname("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: # <<<<<<<<<<<<<< - * cdef vector[X] v - * for item in o: - */ - -static std::vector > __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(PyObject *__pyx_v_o) { - std::vector > __pyx_v_v; - PyObject *__pyx_v_item = NULL; - std::vector > __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *(*__pyx_t_3)(PyObject *); - PyObject *__pyx_t_4 = NULL; - std::pair __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", 1); - - /* "vector.from_py":47 - * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: - * cdef vector[X] v - * for item in o: # <<<<<<<<<<<<<< - * v.push_back(item) - * return v - */ - if (likely(PyList_CheckExact(__pyx_v_o)) || PyTuple_CheckExact(__pyx_v_o)) { - __pyx_t_1 = __pyx_v_o; __Pyx_INCREF(__pyx_t_1); - __pyx_t_2 = 0; - __pyx_t_3 = NULL; - } else { - __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_o); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 47, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_3)) { - if (likely(PyList_CheckExact(__pyx_t_1))) { - { - Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 47, __pyx_L1_error) - #endif - if (__pyx_t_2 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(1, 47, __pyx_L1_error) - #else - __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - } else { - { - Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(1, 47, __pyx_L1_error) - #endif - if (__pyx_t_2 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(1, 47, __pyx_L1_error) - #else - __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - } - } else { - __pyx_t_4 = __pyx_t_3(__pyx_t_1); - if (unlikely(!__pyx_t_4)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(1, 47, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_4); - } - __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_4); - __pyx_t_4 = 0; - - /* "vector.from_py":48 - * cdef vector[X] v - * for item in o: - * v.push_back(item) # <<<<<<<<<<<<<< - * return v - * - */ - __pyx_t_5 = __pyx_convert_pair_from_py_std_3a__3a_string__and_int(__pyx_v_item); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 48, __pyx_L1_error) - try { - __pyx_v_v.push_back(((std::pair )__pyx_t_5)); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(1, 48, __pyx_L1_error) - } - - /* "vector.from_py":47 - * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: - * cdef vector[X] v - * for item in o: # <<<<<<<<<<<<<< - * v.push_back(item) - * return v - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "vector.from_py":49 - * for item in o: - * v.push_back(item) - * return v # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_v; - goto __pyx_L0; - - /* "vector.from_py":45 - * - * @cname("__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___") - * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(object o) except *: # <<<<<<<<<<<<<< - * cdef vector[X] v - * for item in o: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("vector.from_py.__pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_item); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "FromPyStructUtility":12 - * - * @cname("__pyx_convert__from_py_struct__Date") - * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: # <<<<<<<<<<<<<< - * cdef struct_type result - * if not PyMapping_Check(obj): - */ - -static struct Date __pyx_convert__from_py_struct__Date(PyObject *__pyx_v_obj) { - struct Date __pyx_v_result; - PyObject *__pyx_v_value = NULL; - struct Date __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Date", 1); - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); - if (__pyx_t_1) { - - /* "FromPyStructUtility":15 - * cdef struct_type result - * if not PyMapping_Check(obj): - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< - * - * try: - */ - __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - } - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['year'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":18 - * - * try: - * value = obj['year'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'year'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_year); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_v_value = __pyx_t_6; - __pyx_t_6 = 0; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['year'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "FromPyStructUtility":19 - * try: - * value = obj['year'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'year'") - * result.year = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":20 - * value = obj['year'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'year'") # <<<<<<<<<<<<<< - * result.year = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 20, __pyx_L6_except_error) - } - goto __pyx_L6_except_error; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['year'] - * except KeyError: - */ - __pyx_L6_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L9_try_end:; - } - - /* "FromPyStructUtility":21 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'year'") - * result.year = value # <<<<<<<<<<<<<< - * try: - * value = obj['month'] - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) - __pyx_v_result.year = __pyx_t_2; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'year'") - * result.year = value - * try: # <<<<<<<<<<<<<< - * value = obj['month'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "FromPyStructUtility":23 - * result.year = value - * try: - * value = obj['month'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'month'") - */ - __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_month); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); - __pyx_t_8 = 0; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'year'") - * result.year = value - * try: # <<<<<<<<<<<<<< - * value = obj['month'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L17_try_end; - __pyx_L12_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":24 - * try: - * value = obj['month'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'month'") - * result.month = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_6); - - /* "FromPyStructUtility":25 - * value = obj['month'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'month'") # <<<<<<<<<<<<<< - * result.month = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 25, __pyx_L14_except_error) - } - goto __pyx_L14_except_error; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'year'") - * result.year = value - * try: # <<<<<<<<<<<<<< - * value = obj['month'] - * except KeyError: - */ - __pyx_L14_except_error:; - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L17_try_end:; - } - - /* "FromPyStructUtility":26 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'month'") - * result.month = value # <<<<<<<<<<<<<< - * try: - * value = obj['day'] - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) - __pyx_v_result.month = __pyx_t_2; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'month'") - * result.month = value - * try: # <<<<<<<<<<<<<< - * value = obj['day'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":28 - * result.month = value - * try: - * value = obj['day'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'day'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_day); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); - __pyx_t_6 = 0; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'month'") - * result.month = value - * try: # <<<<<<<<<<<<<< - * value = obj['day'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L25_try_end; - __pyx_L20_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":29 - * try: - * value = obj['day'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'day'") - * result.day = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":30 - * value = obj['day'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'day'") # <<<<<<<<<<<<<< - * result.day = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 30, __pyx_L22_except_error) - } - goto __pyx_L22_except_error; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'month'") - * result.month = value - * try: # <<<<<<<<<<<<<< - * value = obj['day'] - * except KeyError: - */ - __pyx_L22_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L25_try_end:; - } - - /* "FromPyStructUtility":31 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'day'") - * result.day = value # <<<<<<<<<<<<<< - * try: - * value = obj['weekday'] - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) - __pyx_v_result.day = __pyx_t_2; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'day'") - * result.day = value - * try: # <<<<<<<<<<<<<< - * value = obj['weekday'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "FromPyStructUtility":33 - * result.day = value - * try: - * value = obj['weekday'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'weekday'") - */ - __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_weekday); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 33, __pyx_L28_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); - __pyx_t_8 = 0; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'day'") - * result.day = value - * try: # <<<<<<<<<<<<<< - * value = obj['weekday'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L33_try_end; - __pyx_L28_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":34 - * try: - * value = obj['weekday'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'weekday'") - * result.weekday = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 34, __pyx_L30_except_error) - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_6); - - /* "FromPyStructUtility":35 - * value = obj['weekday'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'weekday'") # <<<<<<<<<<<<<< - * result.weekday = value - * return result - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 35, __pyx_L30_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 35, __pyx_L30_except_error) - } - goto __pyx_L30_except_error; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'day'") - * result.day = value - * try: # <<<<<<<<<<<<<< - * value = obj['weekday'] - * except KeyError: - */ - __pyx_L30_except_error:; - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L33_try_end:; - } - - /* "FromPyStructUtility":36 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'weekday'") - * result.weekday = value # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 36, __pyx_L1_error) - __pyx_v_result.weekday = __pyx_t_2; - - /* "FromPyStructUtility":37 - * raise ValueError("No value specified for struct attribute 'weekday'") - * result.weekday = value - * return result # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "FromPyStructUtility":12 - * - * @cname("__pyx_convert__from_py_struct__Date") - * cdef struct_type __pyx_convert__from_py_struct__Date(obj) except *: # <<<<<<<<<<<<<< - * cdef struct_type result - * if not PyMapping_Check(obj): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Date", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_value); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static struct Time __pyx_convert__from_py_struct__Time(PyObject *__pyx_v_obj) { - struct Time __pyx_v_result; - PyObject *__pyx_v_value = NULL; - struct Time __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Time", 1); - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); - if (__pyx_t_1) { - - /* "FromPyStructUtility":15 - * cdef struct_type result - * if not PyMapping_Check(obj): - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< - * - * try: - */ - __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - } - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['hours'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":18 - * - * try: - * value = obj['hours'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'hours'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_hours); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_v_value = __pyx_t_6; - __pyx_t_6 = 0; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['hours'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "FromPyStructUtility":19 - * try: - * value = obj['hours'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'hours'") - * result.hours = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":20 - * value = obj['hours'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'hours'") # <<<<<<<<<<<<<< - * result.hours = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 20, __pyx_L6_except_error) - } - goto __pyx_L6_except_error; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['hours'] - * except KeyError: - */ - __pyx_L6_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L9_try_end:; - } - - /* "FromPyStructUtility":21 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'hours'") - * result.hours = value # <<<<<<<<<<<<<< - * try: - * value = obj['minutes'] - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) - __pyx_v_result.hours = __pyx_t_2; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'hours'") - * result.hours = value - * try: # <<<<<<<<<<<<<< - * value = obj['minutes'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "FromPyStructUtility":23 - * result.hours = value - * try: - * value = obj['minutes'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'minutes'") - */ - __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_minutes); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); - __pyx_t_8 = 0; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'hours'") - * result.hours = value - * try: # <<<<<<<<<<<<<< - * value = obj['minutes'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L17_try_end; - __pyx_L12_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":24 - * try: - * value = obj['minutes'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'minutes'") - * result.minutes = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_6); - - /* "FromPyStructUtility":25 - * value = obj['minutes'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'minutes'") # <<<<<<<<<<<<<< - * result.minutes = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 25, __pyx_L14_except_error) - } - goto __pyx_L14_except_error; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'hours'") - * result.hours = value - * try: # <<<<<<<<<<<<<< - * value = obj['minutes'] - * except KeyError: - */ - __pyx_L14_except_error:; - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L17_try_end:; - } - - /* "FromPyStructUtility":26 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'minutes'") - * result.minutes = value # <<<<<<<<<<<<<< - * try: - * value = obj['seconds'] - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) - __pyx_v_result.minutes = __pyx_t_2; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'minutes'") - * result.minutes = value - * try: # <<<<<<<<<<<<<< - * value = obj['seconds'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":28 - * result.minutes = value - * try: - * value = obj['seconds'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'seconds'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_seconds); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); - __pyx_t_6 = 0; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'minutes'") - * result.minutes = value - * try: # <<<<<<<<<<<<<< - * value = obj['seconds'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L25_try_end; - __pyx_L20_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":29 - * try: - * value = obj['seconds'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'seconds'") - * result.seconds = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":30 - * value = obj['seconds'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'seconds'") # <<<<<<<<<<<<<< - * result.seconds = value - * return result - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 30, __pyx_L22_except_error) - } - goto __pyx_L22_except_error; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'minutes'") - * result.minutes = value - * try: # <<<<<<<<<<<<<< - * value = obj['seconds'] - * except KeyError: - */ - __pyx_L22_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L25_try_end:; - } - - /* "FromPyStructUtility":31 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'seconds'") - * result.seconds = value # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) - __pyx_v_result.seconds = __pyx_t_2; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'seconds'") - * result.seconds = value - * return result # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "FromPyStructUtility":12 - * - * @cname("__pyx_convert__from_py_struct__Time") - * cdef struct_type __pyx_convert__from_py_struct__Time(obj) except *: # <<<<<<<<<<<<<< - * cdef struct_type result - * if not PyMapping_Check(obj): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Time", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_value); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static struct Query __pyx_convert__from_py_struct__Query(PyObject *__pyx_v_obj) { - struct Query __pyx_v_result; - PyObject *__pyx_v_value = NULL; - struct Query __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - std::vector > __pyx_t_10; - struct Date __pyx_t_11; - struct Time __pyx_t_12; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__pyx_convert__from_py_struct__Query", 1); - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - __pyx_t_1 = (!PyMapping_Check(__pyx_v_obj)); - if (__pyx_t_1) { - - /* "FromPyStructUtility":15 - * cdef struct_type result - * if not PyMapping_Check(obj): - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) # <<<<<<<<<<<<<< - * - * try: - */ - __pyx_t_2 = __Pyx_RaiseUnexpectedTypeError(((char const *)"a mapping"), __pyx_v_obj); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(1, 15, __pyx_L1_error) - - /* "FromPyStructUtility":14 - * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: - * cdef struct_type result - * if not PyMapping_Check(obj): # <<<<<<<<<<<<<< - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - */ - } - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['included_sources'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":18 - * - * try: - * value = obj['included_sources'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_sources'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_included_sources); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 18, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_v_value = __pyx_t_6; - __pyx_t_6 = 0; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['included_sources'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L9_try_end; - __pyx_L4_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "FromPyStructUtility":19 - * try: - * value = obj['included_sources'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'included_sources'") - * result.included_sources = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 19, __pyx_L6_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":20 - * value = obj['included_sources'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_sources'") # <<<<<<<<<<<<<< - * result.included_sources = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 20, __pyx_L6_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 20, __pyx_L6_except_error) - } - goto __pyx_L6_except_error; - - /* "FromPyStructUtility":17 - * __Pyx_RaiseUnexpectedTypeError(b"a mapping", obj) - * - * try: # <<<<<<<<<<<<<< - * value = obj['included_sources'] - * except KeyError: - */ - __pyx_L6_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L9_try_end:; - } - - /* "FromPyStructUtility":21 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_sources'") - * result.included_sources = value # <<<<<<<<<<<<<< - * try: - * value = obj['included_targets'] - */ - __pyx_t_10 = __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 21, __pyx_L1_error) - __pyx_v_result.included_sources = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_10); - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'included_sources'") - * result.included_sources = value - * try: # <<<<<<<<<<<<<< - * value = obj['included_targets'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "FromPyStructUtility":23 - * result.included_sources = value - * try: - * value = obj['included_targets'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_targets'") - */ - __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_included_targets); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 23, __pyx_L12_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); - __pyx_t_8 = 0; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'included_sources'") - * result.included_sources = value - * try: # <<<<<<<<<<<<<< - * value = obj['included_targets'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L17_try_end; - __pyx_L12_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":24 - * try: - * value = obj['included_targets'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'included_targets'") - * result.included_targets = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 24, __pyx_L14_except_error) - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_6); - - /* "FromPyStructUtility":25 - * value = obj['included_targets'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_targets'") # <<<<<<<<<<<<<< - * result.included_targets = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 25, __pyx_L14_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 25, __pyx_L14_except_error) - } - goto __pyx_L14_except_error; - - /* "FromPyStructUtility":22 - * raise ValueError("No value specified for struct attribute 'included_sources'") - * result.included_sources = value - * try: # <<<<<<<<<<<<<< - * value = obj['included_targets'] - * except KeyError: - */ - __pyx_L14_except_error:; - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L17_try_end:; - } - - /* "FromPyStructUtility":26 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_targets'") - * result.included_targets = value # <<<<<<<<<<<<<< - * try: - * value = obj['date'] - */ - __pyx_t_10 = __pyx_convert_vector_from_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 26, __pyx_L1_error) - __pyx_v_result.included_targets = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_10); - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'included_targets'") - * result.included_targets = value - * try: # <<<<<<<<<<<<<< - * value = obj['date'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":28 - * result.included_targets = value - * try: - * value = obj['date'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'date'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_date); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 28, __pyx_L20_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); - __pyx_t_6 = 0; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'included_targets'") - * result.included_targets = value - * try: # <<<<<<<<<<<<<< - * value = obj['date'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L25_try_end; - __pyx_L20_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":29 - * try: - * value = obj['date'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'date'") - * result.date = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 29, __pyx_L22_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":30 - * value = obj['date'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'date'") # <<<<<<<<<<<<<< - * result.date = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 30, __pyx_L22_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 30, __pyx_L22_except_error) - } - goto __pyx_L22_except_error; - - /* "FromPyStructUtility":27 - * raise ValueError("No value specified for struct attribute 'included_targets'") - * result.included_targets = value - * try: # <<<<<<<<<<<<<< - * value = obj['date'] - * except KeyError: - */ - __pyx_L22_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L25_try_end:; - } - - /* "FromPyStructUtility":31 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'date'") - * result.date = value # <<<<<<<<<<<<<< - * try: - * value = obj['departure_time'] - */ - __pyx_t_11 = __pyx_convert__from_py_struct__Date(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 31, __pyx_L1_error) - __pyx_v_result.date = __pyx_t_11; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'date'") - * result.date = value - * try: # <<<<<<<<<<<<<< - * value = obj['departure_time'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_4, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "FromPyStructUtility":33 - * result.date = value - * try: - * value = obj['departure_time'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'departure_time'") - */ - __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_departure_time); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 33, __pyx_L28_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_8); - __pyx_t_8 = 0; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'date'") - * result.date = value - * try: # <<<<<<<<<<<<<< - * value = obj['departure_time'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L33_try_end; - __pyx_L28_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":34 - * try: - * value = obj['departure_time'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'departure_time'") - * result.departure_time = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(1, 34, __pyx_L30_except_error) - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_6); - - /* "FromPyStructUtility":35 - * value = obj['departure_time'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'departure_time'") # <<<<<<<<<<<<<< - * result.departure_time = value - * try: - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 35, __pyx_L30_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 35, __pyx_L30_except_error) - } - goto __pyx_L30_except_error; - - /* "FromPyStructUtility":32 - * raise ValueError("No value specified for struct attribute 'date'") - * result.date = value - * try: # <<<<<<<<<<<<<< - * value = obj['departure_time'] - * except KeyError: - */ - __pyx_L30_except_error:; - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_4, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L33_try_end:; - } - - /* "FromPyStructUtility":36 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'departure_time'") - * result.departure_time = value # <<<<<<<<<<<<<< - * try: - * value = obj['max_transfers'] - */ - __pyx_t_12 = __pyx_convert__from_py_struct__Time(__pyx_v_value); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 36, __pyx_L1_error) - __pyx_v_result.departure_time = __pyx_t_12; - - /* "FromPyStructUtility":37 - * raise ValueError("No value specified for struct attribute 'departure_time'") - * result.departure_time = value - * try: # <<<<<<<<<<<<<< - * value = obj['max_transfers'] - * except KeyError: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - /*try:*/ { - - /* "FromPyStructUtility":38 - * result.departure_time = value - * try: - * value = obj['max_transfers'] # <<<<<<<<<<<<<< - * except KeyError: - * raise ValueError("No value specified for struct attribute 'max_transfers'") - */ - __pyx_t_6 = __Pyx_PyObject_Dict_GetItem(__pyx_v_obj, __pyx_n_s_max_transfers); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 38, __pyx_L36_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_value, __pyx_t_6); - __pyx_t_6 = 0; - - /* "FromPyStructUtility":37 - * raise ValueError("No value specified for struct attribute 'departure_time'") - * result.departure_time = value - * try: # <<<<<<<<<<<<<< - * value = obj['max_transfers'] - * except KeyError: - */ - } - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - goto __pyx_L41_try_end; - __pyx_L36_error:; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "FromPyStructUtility":39 - * try: - * value = obj['max_transfers'] - * except KeyError: # <<<<<<<<<<<<<< - * raise ValueError("No value specified for struct attribute 'max_transfers'") - * result.max_transfers = value - */ - __pyx_t_2 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_2) { - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(1, 39, __pyx_L38_except_error) - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - - /* "FromPyStructUtility":40 - * value = obj['max_transfers'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'max_transfers'") # <<<<<<<<<<<<<< - * result.max_transfers = value - * return result - */ - __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(1, 40, __pyx_L38_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(1, 40, __pyx_L38_except_error) - } - goto __pyx_L38_except_error; - - /* "FromPyStructUtility":37 - * raise ValueError("No value specified for struct attribute 'departure_time'") - * result.departure_time = value - * try: # <<<<<<<<<<<<<< - * value = obj['max_transfers'] - * except KeyError: - */ - __pyx_L38_except_error:; - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); - goto __pyx_L1_error; - __pyx_L41_try_end:; - } - - /* "FromPyStructUtility":41 - * except KeyError: - * raise ValueError("No value specified for struct attribute 'max_transfers'") - * result.max_transfers = value # <<<<<<<<<<<<<< - * return result - * - */ - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_value); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 41, __pyx_L1_error) - __pyx_v_result.max_transfers = __pyx_t_2; - - /* "FromPyStructUtility":42 - * raise ValueError("No value specified for struct attribute 'max_transfers'") - * result.max_transfers = value - * return result # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - /* "FromPyStructUtility":12 - * - * @cname("__pyx_convert__from_py_struct__Query") - * cdef struct_type __pyx_convert__from_py_struct__Query(obj) except *: # <<<<<<<<<<<<<< - * cdef struct_type result - * if not PyMapping_Check(obj): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("FromPyStructUtility.__pyx_convert__from_py_struct__Query", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_pretend_to_initialize(&__pyx_r); - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_value); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":13 - * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping - * - * def __cinit__(self, str input_directory): # <<<<<<<<<<<<<< - * """Initialize the RAPTOR router - * - */ - -/* Python wrapper */ -static int __pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_input_directory = 0; - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return -1; - #endif - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_directory,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 1: values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = __Pyx_NumKwargs_VARARGS(__pyx_kwds); - switch (__pyx_nargs) { - case 0: - if (likely((values[0] = __Pyx_GetKwValue_VARARGS(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_input_directory)) != 0)) { - (void)__Pyx_Arg_NewRef_VARARGS(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__cinit__") < 0)) __PYX_ERR(0, 13, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_VARARGS(__pyx_args, 0); - } - __pyx_v_input_directory = ((PyObject*)values[0]); - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 13, __pyx_L3_error) - __pyx_L6_skip:; - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); - } - } - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_input_directory), (&PyUnicode_Type), 1, "input_directory", 1))) __PYX_ERR(0, 13, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_input_directory); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = -1; - __pyx_L0:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_VARARGS(values[__pyx_temp]); - } - } - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_10PyPTRouter_10PyPTRouter___cinit__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_input_directory) { - std::string __pyx_v_cpp_directory; - std::unordered_map __pyx_v_agencies; - std::unordered_map __pyx_v_services; - std::unordered_map __pyx_v_trips; - std::unordered_map ,Route,struct pair_hash> __pyx_v_routes; - std::unordered_map __pyx_v_stops; - Parser *__pyx_v_parser; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - std::string __pyx_t_2; - int __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 1); - - /* "PyPTRouter.pyx":30 - * """ - * # Convert Python string to C++ string - * cdef string cpp_directory = input_directory.encode('utf-8') # <<<<<<<<<<<<<< - * - * # Initialize data containers for GTFS data - */ - if (unlikely(__pyx_v_input_directory == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode"); - __PYX_ERR(0, 30, __pyx_L1_error) - } - __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_input_directory); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 30, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_cpp_directory = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_2); - - /* "PyPTRouter.pyx":40 - * - * # Process directory - * cdef Parser* parser = new Parser(cpp_directory) # <<<<<<<<<<<<<< - * - * agencies = parser.getAgencies() - */ - __pyx_v_parser = new Parser(__pyx_v_cpp_directory); - - /* "PyPTRouter.pyx":42 - * cdef Parser* parser = new Parser(cpp_directory) - * - * agencies = parser.getAgencies() # <<<<<<<<<<<<<< - * services = parser.getServices() - * trips = parser.getTrips() - */ - __pyx_v_agencies = __pyx_v_parser->getAgencies(); - - /* "PyPTRouter.pyx":43 - * - * agencies = parser.getAgencies() - * services = parser.getServices() # <<<<<<<<<<<<<< - * trips = parser.getTrips() - * routes = parser.getRoutes() - */ - __pyx_v_services = __pyx_v_parser->getServices(); - - /* "PyPTRouter.pyx":44 - * agencies = parser.getAgencies() - * services = parser.getServices() - * trips = parser.getTrips() # <<<<<<<<<<<<<< - * routes = parser.getRoutes() - * stops = parser.getStops() - */ - __pyx_v_trips = __pyx_v_parser->getTrips(); - - /* "PyPTRouter.pyx":45 - * services = parser.getServices() - * trips = parser.getTrips() - * routes = parser.getRoutes() # <<<<<<<<<<<<<< - * stops = parser.getStops() - * - */ - __pyx_v_routes = __pyx_v_parser->getRoutes(); - - /* "PyPTRouter.pyx":46 - * trips = parser.getTrips() - * routes = parser.getRoutes() - * stops = parser.getStops() # <<<<<<<<<<<<<< - * - * del parser - */ - __pyx_v_stops = __pyx_v_parser->getStops(); - - /* "PyPTRouter.pyx":48 - * stops = parser.getStops() - * - * del parser # <<<<<<<<<<<<<< - * - * # Clean up existing instance if any - */ - delete __pyx_v_parser; - - /* "PyPTRouter.pyx":51 - * - * # Clean up existing instance if any - * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< - * del self.raptor_ptr - * - */ - __pyx_t_3 = (__pyx_v_self->raptor_ptr != NULL); - if (__pyx_t_3) { - - /* "PyPTRouter.pyx":52 - * # Clean up existing instance if any - * if self.raptor_ptr != NULL: - * del self.raptor_ptr # <<<<<<<<<<<<<< - * - * # Create new RAPTOR instance with data - */ - delete __pyx_v_self->raptor_ptr; - - /* "PyPTRouter.pyx":51 - * - * # Clean up existing instance if any - * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< - * del self.raptor_ptr - * - */ - } - - /* "PyPTRouter.pyx":55 - * - * # Create new RAPTOR instance with data - * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) # <<<<<<<<<<<<<< - * - * def __dealloc__(self): - */ - __pyx_v_self->raptor_ptr = new Raptor(__pyx_v_agencies, __pyx_v_services, __pyx_v_stops, __pyx_v_routes, __pyx_v_trips); - - /* "PyPTRouter.pyx":13 - * cdef Raptor* raptor_ptr # Hold a pointer to the C++ instance which we're wrapping - * - * def __cinit__(self, str input_directory): # <<<<<<<<<<<<<< - * """Initialize the RAPTOR router - * - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":57 - * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * """Deallocate the RAPTOR router - * - */ - -/* Python wrapper */ -static void __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(PyObject *__pyx_v_self) { - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_kwvalues = __Pyx_KwValues_VARARGS(__pyx_args, __pyx_nargs); - __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_10PyPTRouter_10PyPTRouter_2__dealloc__(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self) { - int __pyx_t_1; - - /* "PyPTRouter.pyx":68 - * - Sets raptor_ptr to NULL after deletion is handled by C++ - * """ - * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< - * del self.raptor_ptr - * - */ - __pyx_t_1 = (__pyx_v_self->raptor_ptr != NULL); - if (__pyx_t_1) { - - /* "PyPTRouter.pyx":69 - * """ - * if self.raptor_ptr != NULL: - * del self.raptor_ptr # <<<<<<<<<<<<<< - * - * def construct_query( - */ - delete __pyx_v_self->raptor_ptr; - - /* "PyPTRouter.pyx":68 - * - Sets raptor_ptr to NULL after deletion is handled by C++ - * """ - * if self.raptor_ptr != NULL: # <<<<<<<<<<<<<< - * del self.raptor_ptr - * - */ - } - - /* "PyPTRouter.pyx":57 - * self.raptor_ptr = new Raptor(agencies, services, stops, routes, trips) - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * """Deallocate the RAPTOR router - * - */ - - /* function exit code */ -} - -/* "PyPTRouter.pyx":71 - * del self.raptor_ptr - * - * def construct_query( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query, "PyPTRouter.construct_query(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1)\nConstruct query information.\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed\n\n Returns:\n query (Query)\n "); -static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query = {"construct_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query}; -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -) { - PyObject *__pyx_v_source_station_departure_datetime = 0; - PyObject *__pyx_v_included_sources = 0; - PyObject *__pyx_v_included_targets = 0; - int __pyx_v_max_transfers; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[4] = {0,0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("construct_query (wrapper)", 0); - #if !CYTHON_METH_FASTCALL - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; - #endif - #endif - __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); - { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); - switch (__pyx_nargs) { - case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, 1); __PYX_ERR(0, 71, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, 2); __PYX_ERR(0, 71, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); - if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "construct_query") < 0)) __PYX_ERR(0, 71, __pyx_L3_error) - } - } else { - switch (__pyx_nargs) { - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_source_station_departure_datetime = values[0]; - __pyx_v_included_sources = ((PyObject*)values[1]); - __pyx_v_included_targets = ((PyObject*)values[2]); - if (values[3]) { - __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 74, __pyx_L3_error) - } else { - __pyx_v_max_transfers = ((int)-1); - } - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("construct_query", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 71, __pyx_L3_error) - __pyx_L6_skip:; - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.construct_query", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 74, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 74, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_4construct_query(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers) { - int __pyx_v_year; - int __pyx_v_month; - int __pyx_v_day; - int __pyx_v_weekday; - int __pyx_v_hours; - int __pyx_v_minutes; - int __pyx_v_seconds; - struct Date __pyx_v_date; - struct Time __pyx_v_departure_time; - std::vector > __pyx_v_src_vec; - std::vector > __pyx_v_tgt_vec; - PyObject *__pyx_v_inc_src = NULL; - PyObject *__pyx_v_inc_tgt = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - unsigned int __pyx_t_5; - struct Date __pyx_t_6; - struct Time __pyx_t_7; - std::vector > __pyx_t_8; - Py_ssize_t __pyx_t_9; - int __pyx_t_10; - int __pyx_t_11; - Py_ssize_t __pyx_t_12; - PyObject *__pyx_t_13 = NULL; - std::string __pyx_t_14; - std::pair __pyx_t_15; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("construct_query", 1); - - /* "PyPTRouter.pyx":88 - * """ - * # Calculate day of week using Python's datetime - * cdef int year = source_station_departure_datetime.year # <<<<<<<<<<<<<< - * cdef int month = source_station_departure_datetime.month - * cdef int day = source_station_departure_datetime.day - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_year); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 88, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_year = __pyx_t_2; - - /* "PyPTRouter.pyx":89 - * # Calculate day of week using Python's datetime - * cdef int year = source_station_departure_datetime.year - * cdef int month = source_station_departure_datetime.month # <<<<<<<<<<<<<< - * cdef int day = source_station_departure_datetime.day - * cdef int weekday = source_station_departure_datetime.weekday() - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_month); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_month = __pyx_t_2; - - /* "PyPTRouter.pyx":90 - * cdef int year = source_station_departure_datetime.year - * cdef int month = source_station_departure_datetime.month - * cdef int day = source_station_departure_datetime.day # <<<<<<<<<<<<<< - * cdef int weekday = source_station_departure_datetime.weekday() - * cdef int hours = source_station_departure_datetime.hour - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_day); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 90, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_day = __pyx_t_2; - - /* "PyPTRouter.pyx":91 - * cdef int month = source_station_departure_datetime.month - * cdef int day = source_station_departure_datetime.day - * cdef int weekday = source_station_departure_datetime.weekday() # <<<<<<<<<<<<<< - * cdef int hours = source_station_departure_datetime.hour - * cdef int minutes = source_station_departure_datetime.minute - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_weekday); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 91, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = NULL; - __pyx_t_5 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_5 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_4, NULL}; - __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 0+__pyx_t_5); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 91, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_weekday = __pyx_t_2; - - /* "PyPTRouter.pyx":92 - * cdef int day = source_station_departure_datetime.day - * cdef int weekday = source_station_departure_datetime.weekday() - * cdef int hours = source_station_departure_datetime.hour # <<<<<<<<<<<<<< - * cdef int minutes = source_station_departure_datetime.minute - * cdef int seconds = source_station_departure_datetime.second - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_hour); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 92, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_hours = __pyx_t_2; - - /* "PyPTRouter.pyx":93 - * cdef int weekday = source_station_departure_datetime.weekday() - * cdef int hours = source_station_departure_datetime.hour - * cdef int minutes = source_station_departure_datetime.minute # <<<<<<<<<<<<<< - * cdef int seconds = source_station_departure_datetime.second - * - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_minute); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_minutes = __pyx_t_2; - - /* "PyPTRouter.pyx":94 - * cdef int hours = source_station_departure_datetime.hour - * cdef int minutes = source_station_departure_datetime.minute - * cdef int seconds = source_station_departure_datetime.second # <<<<<<<<<<<<<< - * - * # Create date, time objects for C++ - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_source_station_departure_datetime, __pyx_n_s_second); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_seconds = __pyx_t_2; - - /* "PyPTRouter.pyx":97 - * - * # Create date, time objects for C++ - * cdef Date date = Date(year, month, day, weekday) # <<<<<<<<<<<<<< - * cdef Time departure_time = Time(hours, minutes, seconds) - * - */ - __pyx_t_6.year = __pyx_v_year; - __pyx_t_6.month = __pyx_v_month; - __pyx_t_6.day = __pyx_v_day; - __pyx_t_6.weekday = __pyx_v_weekday; - __pyx_v_date = __pyx_t_6; - - /* "PyPTRouter.pyx":98 - * # Create date, time objects for C++ - * cdef Date date = Date(year, month, day, weekday) - * cdef Time departure_time = Time(hours, minutes, seconds) # <<<<<<<<<<<<<< - * - * cdef Query query - */ - __pyx_t_7.hours = __pyx_v_hours; - __pyx_t_7.minutes = __pyx_v_minutes; - __pyx_t_7.seconds = __pyx_v_seconds; - __pyx_v_departure_time = __pyx_t_7; - - /* "PyPTRouter.pyx":105 - * cdef vector[pair[string, int]] tgt_vec - * - * src_vec = vector[pair[string, int]]() # <<<<<<<<<<<<<< - * for inc_src in included_sources: - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): - */ - try { - __pyx_t_8 = std::vector > (); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 105, __pyx_L1_error) - } - __pyx_v_src_vec = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_8); - - /* "PyPTRouter.pyx":106 - * - * src_vec = vector[pair[string, int]]() - * for inc_src in included_sources: # <<<<<<<<<<<<<< - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) - */ - if (unlikely(__pyx_v_included_sources == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(0, 106, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_included_sources; __Pyx_INCREF(__pyx_t_1); - __pyx_t_9 = 0; - for (;;) { - { - Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 106, __pyx_L1_error) - #endif - if (__pyx_t_9 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_9); __Pyx_INCREF(__pyx_t_3); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 106, __pyx_L1_error) - #else - __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_inc_src, __pyx_t_3); - __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":107 - * src_vec = vector[pair[string, int]]() - * for inc_src in included_sources: - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): # <<<<<<<<<<<<<< - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) - * else: - */ - __pyx_t_11 = PyTuple_Check(__pyx_v_inc_src); - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_12 = PyObject_Length(__pyx_v_inc_src); if (unlikely(__pyx_t_12 == ((Py_ssize_t)-1))) __PYX_ERR(0, 107, __pyx_L1_error) - __pyx_t_11 = (__pyx_t_12 == 2); - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_11 = PyUnicode_Check(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_11 = PyInt_Check(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_10 = __pyx_t_11; - __pyx_L6_bool_binop_done:; - if (likely(__pyx_t_10)) { - - /* "PyPTRouter.pyx":108 - * for inc_src in included_sources: - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) # <<<<<<<<<<<<<< - * else: - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") - */ - __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_inc_src, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_encode); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - __pyx_t_5 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_13))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_13); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_13, function); - __pyx_t_5 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_kp_u_utf_8}; - __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_13, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - } - __pyx_t_14 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_src, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - try { - __pyx_t_15 = std::pair (__pyx_t_14, __pyx_t_2); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 108, __pyx_L1_error) - } - try { - __pyx_v_src_vec.push_back(__pyx_t_15); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 108, __pyx_L1_error) - } - - /* "PyPTRouter.pyx":107 - * src_vec = vector[pair[string, int]]() - * for inc_src in included_sources: - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): # <<<<<<<<<<<<<< - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) - * else: - */ - goto __pyx_L5; - } - - /* "PyPTRouter.pyx":110 - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) - * else: - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") # <<<<<<<<<<<<<< - * - * tgt_vec = vector[pair[string, int]]() - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_inc_src)), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_13 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Expected_string_int_tuple_got, __pyx_t_3); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_13); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 110, __pyx_L1_error) - } - __pyx_L5:; - - /* "PyPTRouter.pyx":106 - * - * src_vec = vector[pair[string, int]]() - * for inc_src in included_sources: # <<<<<<<<<<<<<< - * if isinstance(inc_src, tuple) and len(inc_src) == 2 and isinstance(inc_src[0], str) and isinstance(inc_src[1], int): - * src_vec.push_back(pair[string, int](inc_src[0].encode('utf-8'), inc_src[1])) - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "PyPTRouter.pyx":112 - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_src)}") - * - * tgt_vec = vector[pair[string, int]]() # <<<<<<<<<<<<<< - * for inc_tgt in included_targets: - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): - */ - try { - __pyx_t_8 = std::vector > (); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 112, __pyx_L1_error) - } - __pyx_v_tgt_vec = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_8); - - /* "PyPTRouter.pyx":113 - * - * tgt_vec = vector[pair[string, int]]() - * for inc_tgt in included_targets: # <<<<<<<<<<<<<< - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) - */ - if (unlikely(__pyx_v_included_targets == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(0, 113, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_included_targets; __Pyx_INCREF(__pyx_t_1); - __pyx_t_9 = 0; - for (;;) { - { - Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1); - #if !CYTHON_ASSUME_SAFE_MACROS - if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 113, __pyx_L1_error) - #endif - if (__pyx_t_9 >= __pyx_temp) break; - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_9); __Pyx_INCREF(__pyx_t_3); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 113, __pyx_L1_error) - #else - __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_inc_tgt, __pyx_t_3); - __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":114 - * tgt_vec = vector[pair[string, int]]() - * for inc_tgt in included_targets: - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): # <<<<<<<<<<<<<< - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) - * else: - */ - __pyx_t_11 = PyTuple_Check(__pyx_v_inc_tgt); - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_12 = PyObject_Length(__pyx_v_inc_tgt); if (unlikely(__pyx_t_12 == ((Py_ssize_t)-1))) __PYX_ERR(0, 114, __pyx_L1_error) - __pyx_t_11 = (__pyx_t_12 == 2); - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_11 = PyUnicode_Check(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_11) { - } else { - __pyx_t_10 = __pyx_t_11; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_11 = PyInt_Check(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_10 = __pyx_t_11; - __pyx_L14_bool_binop_done:; - if (likely(__pyx_t_10)) { - - /* "PyPTRouter.pyx":115 - * for inc_tgt in included_targets: - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) # <<<<<<<<<<<<<< - * else: - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") - */ - __pyx_t_13 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_13); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __pyx_t_13 = NULL; - __pyx_t_5 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_13)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_13); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - __pyx_t_5 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[2] = {__pyx_t_13, __pyx_kp_u_utf_8}; - __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5); - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } - __pyx_t_14 = __pyx_convert_string_from_py_6libcpp_6string_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_inc_tgt, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 115, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - try { - __pyx_t_15 = std::pair (__pyx_t_14, __pyx_t_2); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 115, __pyx_L1_error) - } - try { - __pyx_v_tgt_vec.push_back(__pyx_t_15); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 115, __pyx_L1_error) - } - - /* "PyPTRouter.pyx":114 - * tgt_vec = vector[pair[string, int]]() - * for inc_tgt in included_targets: - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): # <<<<<<<<<<<<<< - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) - * else: - */ - goto __pyx_L13; - } - - /* "PyPTRouter.pyx":117 - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) - * else: - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") # <<<<<<<<<<<<<< - * - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_inc_tgt)), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Expected_string_int_tuple_got, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 117, __pyx_L1_error) - } - __pyx_L13:; - - /* "PyPTRouter.pyx":113 - * - * tgt_vec = vector[pair[string, int]]() - * for inc_tgt in included_targets: # <<<<<<<<<<<<<< - * if isinstance(inc_tgt, tuple) and len(inc_tgt) == 2 and isinstance(inc_tgt[0], str) and isinstance(inc_tgt[1], int): - * tgt_vec.push_back(pair[string, int](inc_tgt[0].encode('utf-8'), inc_tgt[1])) - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "PyPTRouter.pyx":119 - * raise TypeError(f"Expected (string, int) tuple, got {type(inc_tgt)}") - * - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) # <<<<<<<<<<<<<< - * - * def return_pt_journeys_1to1( - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_src_vec); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_included_sources, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __pyx_convert_vector_to_py_std_3a__3a_pair_3c_std_3a__3a_string_2c_int_3e___(__pyx_v_tgt_vec); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_included_targets, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __pyx_convert__to_py_struct__Date(__pyx_v_date); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_date, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __pyx_convert__to_py_struct__Time(__pyx_v_departure_time); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_transfers, __pyx_t_3) < 0) __PYX_ERR(0, 119, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "PyPTRouter.pyx":71 - * del self.raptor_ptr - * - * def construct_query( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_13); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.construct_query", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_inc_src); - __Pyx_XDECREF(__pyx_v_inc_tgt); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":121 - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - * - * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1, "PyPTRouter.return_pt_journeys_1to1(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the best public transport journey from source to target\n\n This method queries the RAPTOR router to find the optimal journey between two stops\n at a specified departure time.\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); -static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1 = {"return_pt_journeys_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1}; -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -) { - PyObject *__pyx_v_source_station_departure_datetime = 0; - PyObject *__pyx_v_included_sources = 0; - PyObject *__pyx_v_included_targets = 0; - int __pyx_v_max_transfers; - bool __pyx_v_detailed; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[5] = {0,0,0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("return_pt_journeys_1to1 (wrapper)", 0); - #if !CYTHON_METH_FASTCALL - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; - #endif - #endif - __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); - { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); - switch (__pyx_nargs) { - case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, 1); __PYX_ERR(0, 121, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, 2); __PYX_ERR(0, 121, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); - if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_detailed); - if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 121, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "return_pt_journeys_1to1") < 0)) __PYX_ERR(0, 121, __pyx_L3_error) - } - } else { - switch (__pyx_nargs) { - case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_source_station_departure_datetime = values[0]; - __pyx_v_included_sources = ((PyObject*)values[1]); - __pyx_v_included_targets = ((PyObject*)values[2]); - if (values[3]) { - __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 124, __pyx_L3_error) - } else { - __pyx_v_max_transfers = ((int)-1); - } - if (values[4]) { - __pyx_v_detailed = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_detailed == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 125, __pyx_L3_error) - } else { - - /* "PyPTRouter.pyx":125 - * source_station_departure_datetime, - * list included_sources, list included_targets, int max_transfers=-1, - * bool detailed=False, # <<<<<<<<<<<<<< - * ): - * """Find the best public transport journey from source to target - */ - __pyx_v_detailed = ((bool)0); - } - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("return_pt_journeys_1to1", 0, 3, 5, __pyx_nargs); __PYX_ERR(0, 121, __pyx_L3_error) - __pyx_L6_skip:; - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_pt_journeys_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 124, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 124, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); - - /* "PyPTRouter.pyx":121 - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - * - * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { - PyObject *__pyx_v_query = NULL; - std::vector __pyx_v_journeys; - PyObject *__pyx_v_journeys_list = NULL; - std::vector ::size_type __pyx_v_i; - PyObject *__pyx_v_journey_dict = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - unsigned int __pyx_t_6; - struct Query __pyx_t_7; - std::vector ::size_type __pyx_t_8; - std::vector ::size_type __pyx_t_9; - std::vector ::size_type __pyx_t_10; - int __pyx_t_11; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("return_pt_journeys_1to1", 1); - - /* "PyPTRouter.pyx":144 - * - duration: Total journey duration in seconds - * """ - * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - */ - __pyx_t_1 = (__pyx_v_self->raptor_ptr == NULL); - if (unlikely(__pyx_t_1)) { - - /* "PyPTRouter.pyx":145 - * """ - * if self.raptor_ptr == NULL: - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< - * - * query = self.construct_query( - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 145, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 145, __pyx_L1_error) - - /* "PyPTRouter.pyx":144 - * - duration: Total journey duration in seconds - * """ - * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - */ - } - - /* "PyPTRouter.pyx":147 - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - * query = self.construct_query( # <<<<<<<<<<<<<< - * source_station_departure_datetime, included_sources, included_targets, max_transfers, - * ) - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "PyPTRouter.pyx":148 - * - * query = self.construct_query( - * source_station_departure_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< - * ) - * - */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 148, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - __pyx_t_6 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_6 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; - __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 147, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_v_query = __pyx_t_2; - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":152 - * - * # Set query and find journeys - * self.raptor_ptr.setQuery(query) # <<<<<<<<<<<<<< - * cdef vector[Journey] journeys = self.raptor_ptr.findJourneys() - * - */ - __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 152, __pyx_L1_error) - __pyx_v_self->raptor_ptr->setQuery(__pyx_t_7); - - /* "PyPTRouter.pyx":153 - * # Set query and find journeys - * self.raptor_ptr.setQuery(query) - * cdef vector[Journey] journeys = self.raptor_ptr.findJourneys() # <<<<<<<<<<<<<< - * - * # Check if any journeys were found - */ - __pyx_v_journeys = __pyx_v_self->raptor_ptr->findJourneys(); - - /* "PyPTRouter.pyx":156 - * - * # Check if any journeys were found - * if journeys.size() == 0: # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_1 = (__pyx_v_journeys.size() == 0); - if (__pyx_t_1) { - - /* "PyPTRouter.pyx":157 - * # Check if any journeys were found - * if journeys.size() == 0: - * return None # <<<<<<<<<<<<<< - * - * # Convert all journeys to Python list of dictionaries - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "PyPTRouter.pyx":156 - * - * # Check if any journeys were found - * if journeys.size() == 0: # <<<<<<<<<<<<<< - * return None - * - */ - } - - /* "PyPTRouter.pyx":160 - * - * # Convert all journeys to Python list of dictionaries - * journeys_list = [] # <<<<<<<<<<<<<< - * for i in range(journeys.size()): - * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) - */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 160, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_journeys_list = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":161 - * # Convert all journeys to Python list of dictionaries - * journeys_list = [] - * for i in range(journeys.size()): # <<<<<<<<<<<<<< - * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) - * journeys_list.append(journey_dict) - */ - __pyx_t_8 = __pyx_v_journeys.size(); - __pyx_t_9 = __pyx_t_8; - for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { - __pyx_v_i = __pyx_t_10; - - /* "PyPTRouter.pyx":162 - * journeys_list = [] - * for i in range(journeys.size()): - * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) # <<<<<<<<<<<<<< - * journeys_list.append(journey_dict) - * - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, (__pyx_v_journeys[__pyx_v_i]), __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 162, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_XDECREF_SET(__pyx_v_journey_dict, __pyx_t_2); - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":163 - * for i in range(journeys.size()): - * journey_dict = self._convert_journey_to_dict(journeys[i], detailed) - * journeys_list.append(journey_dict) # <<<<<<<<<<<<<< - * - * return journeys_list - */ - __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_journeys_list, __pyx_v_journey_dict); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 163, __pyx_L1_error) - } - - /* "PyPTRouter.pyx":165 - * journeys_list.append(journey_dict) - * - * return journeys_list # <<<<<<<<<<<<<< - * - * def return_fastest_pt_journey_1to1( - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_journeys_list); - __pyx_r = __pyx_v_journeys_list; - goto __pyx_L0; - - /* "PyPTRouter.pyx":121 - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - * - * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_pt_journeys_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_query); - __Pyx_XDECREF(__pyx_v_journeys_list); - __Pyx_XDECREF(__pyx_v_journey_dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":167 - * return journeys_list - * - * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1, "PyPTRouter.return_fastest_pt_journey_1to1(self, source_station_departure_datetime, list included_sources, list included_targets, int max_transfers=-1, bool detailed=False)\nFind the fastest public transport journey from source station to target station\n\n Args:\n source_station_departure_datetime (datetime): Departure datetime at the source station\n included_sources (list): List of source stop IDs and their station stop transfer times\n included_targets (list): List of target stop IDs and their station stop transfer times\n max_transfers (int): Maximum number of transfers allowed (-1 for unlimited)\n detailed (bool): Whether to return the detailed journey plan.\n\n Returns:\n dict: A dictionary containing journey details, or None if no journey is found.\n The dictionary includes:\n - duration: Total journey duration in seconds\n "); -static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1 = {"return_fastest_pt_journey_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1}; -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -) { - PyObject *__pyx_v_source_station_departure_datetime = 0; - PyObject *__pyx_v_included_sources = 0; - PyObject *__pyx_v_included_targets = 0; - int __pyx_v_max_transfers; - bool __pyx_v_detailed; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[5] = {0,0,0,0,0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("return_fastest_pt_journey_1to1 (wrapper)", 0); - #if !CYTHON_METH_FASTCALL - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; - #endif - #endif - __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); - { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source_station_departure_datetim,&__pyx_n_s_included_sources,&__pyx_n_s_included_targets,&__pyx_n_s_max_transfers,&__pyx_n_s_detailed,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); - switch (__pyx_nargs) { - case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_source_station_departure_datetim)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_sources)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, 1); __PYX_ERR(0, 167, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_included_targets)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) - else { - __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, 2); __PYX_ERR(0, 167, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_max_transfers); - if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (kw_args > 0) { - PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_detailed); - if (value) { values[4] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "return_fastest_pt_journey_1to1") < 0)) __PYX_ERR(0, 167, __pyx_L3_error) - } - } else { - switch (__pyx_nargs) { - case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); - values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_source_station_departure_datetime = values[0]; - __pyx_v_included_sources = ((PyObject*)values[1]); - __pyx_v_included_targets = ((PyObject*)values[2]); - if (values[3]) { - __pyx_v_max_transfers = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_max_transfers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 170, __pyx_L3_error) - } else { - __pyx_v_max_transfers = ((int)-1); - } - if (values[4]) { - __pyx_v_detailed = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_detailed == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 171, __pyx_L3_error) - } else { - - /* "PyPTRouter.pyx":171 - * source_station_departure_datetime, - * list included_sources, list included_targets, int max_transfers=-1, - * bool detailed=False, # <<<<<<<<<<<<<< - * ): - * """Find the fastest public transport journey from source station to target station - */ - __pyx_v_detailed = ((bool)0); - } - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("return_fastest_pt_journey_1to1", 0, 3, 5, __pyx_nargs); __PYX_ERR(0, 167, __pyx_L3_error) - __pyx_L6_skip:; - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_fastest_pt_journey_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_sources), (&PyList_Type), 1, "included_sources", 1))) __PYX_ERR(0, 170, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_included_targets), (&PyList_Type), 1, "included_targets", 1))) __PYX_ERR(0, 170, __pyx_L1_error) - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_v_max_transfers, __pyx_v_detailed); - - /* "PyPTRouter.pyx":167 - * return journeys_list - * - * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, PyObject *__pyx_v_source_station_departure_datetime, PyObject *__pyx_v_included_sources, PyObject *__pyx_v_included_targets, int __pyx_v_max_transfers, bool __pyx_v_detailed) { - PyObject *__pyx_v_query = NULL; - std::optional __pyx_v_journey_opt; - struct Journey __pyx_v_journey; - PyObject *__pyx_v_journey_dict = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - unsigned int __pyx_t_6; - struct Query __pyx_t_7; - __Pyx_FakeReference __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("return_fastest_pt_journey_1to1", 1); - - /* "PyPTRouter.pyx":187 - * - duration: Total journey duration in seconds - * """ - * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - */ - __pyx_t_1 = (__pyx_v_self->raptor_ptr == NULL); - if (unlikely(__pyx_t_1)) { - - /* "PyPTRouter.pyx":188 - * """ - * if self.raptor_ptr == NULL: - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< - * - * query = self.construct_query( - */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 188, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 188, __pyx_L1_error) - - /* "PyPTRouter.pyx":187 - * - duration: Total journey duration in seconds - * """ - * if self.raptor_ptr == NULL: # <<<<<<<<<<<<<< - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - */ - } - - /* "PyPTRouter.pyx":190 - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") - * - * query = self.construct_query( # <<<<<<<<<<<<<< - * source_station_departure_datetime, included_sources, included_targets, max_transfers, - * ) - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_construct_query); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 190, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "PyPTRouter.pyx":191 - * - * query = self.construct_query( - * source_station_departure_datetime, included_sources, included_targets, max_transfers, # <<<<<<<<<<<<<< - * ) - * - */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_max_transfers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 191, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - __pyx_t_6 = 0; - #if CYTHON_UNPACK_METHODS - if (likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_6 = 1; - } - } - #endif - { - PyObject *__pyx_callargs[5] = {__pyx_t_5, __pyx_v_source_station_departure_datetime, __pyx_v_included_sources, __pyx_v_included_targets, __pyx_t_4}; - __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 4+__pyx_t_6); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 190, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __pyx_v_query = __pyx_t_2; - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":195 - * - * # Set query and find journeys - * self.raptor_ptr.setQuery(query) # <<<<<<<<<<<<<< - * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() - * - */ - __pyx_t_7 = __pyx_convert__from_py_struct__Query(__pyx_v_query); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L1_error) - __pyx_v_self->raptor_ptr->setQuery(__pyx_t_7); - - /* "PyPTRouter.pyx":196 - * # Set query and find journeys - * self.raptor_ptr.setQuery(query) - * cdef optional[Journey] journey_opt = self.raptor_ptr.findOptimalJourney() # <<<<<<<<<<<<<< - * - * # Check if journey was found - */ - __pyx_v_journey_opt = __pyx_v_self->raptor_ptr->findOptimalJourney(); - - /* "PyPTRouter.pyx":199 - * - * # Check if journey was found - * if not journey_opt.has_value(): # <<<<<<<<<<<<<< - * return None - * - */ - __pyx_t_1 = (!(__pyx_v_journey_opt.has_value() != 0)); - if (__pyx_t_1) { - - /* "PyPTRouter.pyx":200 - * # Check if journey was found - * if not journey_opt.has_value(): - * return None # <<<<<<<<<<<<<< - * - * # Get the actual journey from optional - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "PyPTRouter.pyx":199 - * - * # Check if journey was found - * if not journey_opt.has_value(): # <<<<<<<<<<<<<< - * return None - * - */ - } - - /* "PyPTRouter.pyx":203 - * - * # Get the actual journey from optional - * cdef Journey journey = journey_opt.value() # <<<<<<<<<<<<<< - * - * # Convert journey to Python dictionary - */ - try { - __pyx_t_8 = __pyx_v_journey_opt.value(); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 203, __pyx_L1_error) - } - __pyx_v_journey = __pyx_t_8; - - /* "PyPTRouter.pyx":206 - * - * # Convert journey to Python dictionary - * journey_dict = self._convert_journey_to_dict(journey, detailed) # <<<<<<<<<<<<<< - * - * return journey_dict - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_to_dict(__pyx_v_self, __pyx_v_journey, __pyx_v_detailed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 206, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_journey_dict = __pyx_t_2; - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":208 - * journey_dict = self._convert_journey_to_dict(journey, detailed) - * - * return journey_dict # <<<<<<<<<<<<<< - * - * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_journey_dict); - __pyx_r = __pyx_v_journey_dict; - goto __pyx_L0; - - /* "PyPTRouter.pyx":167 - * return journeys_list - * - * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.return_fastest_pt_journey_1to1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_query); - __Pyx_XDECREF(__pyx_v_journey_dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":210 - * return journey_dict - * - * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< - * """Convert a Journey object to a Python dictionary - * - */ - -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct Journey __pyx_v_journey, bool __pyx_v_detailed) { - PyObject *__pyx_v_journey_dict = NULL; - std::vector ::size_type __pyx_v_i; - PyObject *__pyx_v_step_dict = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - std::vector ::size_type __pyx_t_4; - std::vector ::size_type __pyx_t_5; - std::vector ::size_type __pyx_t_6; - int __pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_convert_journey_to_dict", 1); - - /* "PyPTRouter.pyx":225 - * journey_dict = { - * # Overall journey information - * "duration": journey.duration, # <<<<<<<<<<<<<< - * "trip_time": journey.trip_time, - * "num_transfers": journey.num_transfers, - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.duration); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_duration, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":226 - * # Overall journey information - * "duration": journey.duration, - * "trip_time": journey.trip_time, # <<<<<<<<<<<<<< - * "num_transfers": journey.num_transfers, - * - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.trip_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 226, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_trip_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":227 - * "duration": journey.duration, - * "trip_time": journey.trip_time, - * "num_transfers": journey.num_transfers, # <<<<<<<<<<<<<< - * - * # Departure information - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.num_transfers); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 227, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_num_transfers, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":230 - * - * # Departure information - * "source_transfer_time": journey.source_transfer_time, # <<<<<<<<<<<<<< - * "source_waiting_time": journey.source_waiting_time, - * "source_station_departure_time": journey.source_station_departure_secs, - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":231 - * # Departure information - * "source_transfer_time": journey.source_transfer_time, - * "source_waiting_time": journey.source_waiting_time, # <<<<<<<<<<<<<< - * "source_station_departure_time": journey.source_station_departure_secs, - * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_waiting_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_waiting_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":232 - * "source_transfer_time": journey.source_transfer_time, - * "source_waiting_time": journey.source_waiting_time, - * "source_station_departure_time": journey.source_station_departure_secs, # <<<<<<<<<<<<<< - * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), - * - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.source_station_departure_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_station_departure_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":233 - * "source_waiting_time": journey.source_waiting_time, - * "source_station_departure_time": journey.source_station_departure_secs, - * "source_station_departure_day": self._day_to_str(journey.source_station_departure_day), # <<<<<<<<<<<<<< - * - * # Arrival information - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.source_station_departure_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source_station_departure_day, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":236 - * - * # Arrival information - * "target_station_arrival_time": journey.target_station_arrival_secs, # <<<<<<<<<<<<<< - * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), - * "target_transfer_time": journey.target_transfer_time, - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.target_station_arrival_secs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 236, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_station_arrival_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":237 - * # Arrival information - * "target_station_arrival_time": journey.target_station_arrival_secs, - * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), # <<<<<<<<<<<<<< - * "target_transfer_time": journey.target_transfer_time, - * - */ - __pyx_t_2 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_journey.target_station_arrival_day); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_station_arrival_day, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":238 - * "target_station_arrival_time": journey.target_station_arrival_secs, - * "target_station_arrival_day": self._day_to_str(journey.target_station_arrival_day), - * "target_transfer_time": journey.target_transfer_time, # <<<<<<<<<<<<<< - * - * # Journey steps - */ - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_journey.target_transfer_time); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_target_transfer_time, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":241 - * - * # Journey steps - * "steps": [] # <<<<<<<<<<<<<< - * } - * - */ - __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 241, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_steps, __pyx_t_2) < 0) __PYX_ERR(0, 225, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_v_journey_dict = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "PyPTRouter.pyx":244 - * } - * - * if not detailed: # <<<<<<<<<<<<<< - * return journey_dict - * - */ - __pyx_t_3 = (!(__pyx_v_detailed != 0)); - if (__pyx_t_3) { - - /* "PyPTRouter.pyx":245 - * - * if not detailed: - * return journey_dict # <<<<<<<<<<<<<< - * - * # Convert each journey step - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_journey_dict); - __pyx_r = __pyx_v_journey_dict; - goto __pyx_L0; - - /* "PyPTRouter.pyx":244 - * } - * - * if not detailed: # <<<<<<<<<<<<<< - * return journey_dict - * - */ - } - - /* "PyPTRouter.pyx":248 - * - * # Convert each journey step - * for i in range(journey.steps.size()): # <<<<<<<<<<<<<< - * step_dict = self._convert_journey_step(journey.steps[i]) - * journey_dict["steps"].append(step_dict) - */ - __pyx_t_4 = __pyx_v_journey.steps.size(); - __pyx_t_5 = __pyx_t_4; - for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { - __pyx_v_i = __pyx_t_6; - - /* "PyPTRouter.pyx":249 - * # Convert each journey step - * for i in range(journey.steps.size()): - * step_dict = self._convert_journey_step(journey.steps[i]) # <<<<<<<<<<<<<< - * journey_dict["steps"].append(step_dict) - * - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_convert_journey_step(__pyx_v_self, (__pyx_v_journey.steps[__pyx_v_i])); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 249, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_XDECREF_SET(__pyx_v_step_dict, __pyx_t_1); - __pyx_t_1 = 0; - - /* "PyPTRouter.pyx":250 - * for i in range(journey.steps.size()): - * step_dict = self._convert_journey_step(journey.steps[i]) - * journey_dict["steps"].append(step_dict) # <<<<<<<<<<<<<< - * - * return journey_dict - */ - __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_journey_dict, __pyx_n_u_steps); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_v_step_dict); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 250, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - - /* "PyPTRouter.pyx":252 - * journey_dict["steps"].append(step_dict) - * - * return journey_dict # <<<<<<<<<<<<<< - * - * cdef str _day_to_str(self, Day day): - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_journey_dict); - __pyx_r = __pyx_v_journey_dict; - goto __pyx_L0; - - /* "PyPTRouter.pyx":210 - * return journey_dict - * - * cdef _convert_journey_to_dict(self, Journey journey, bool detailed): # <<<<<<<<<<<<<< - * """Convert a Journey object to a Python dictionary - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter._convert_journey_to_dict", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_journey_dict); - __Pyx_XDECREF(__pyx_v_step_dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":254 - * return journey_dict - * - * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< - * """Convert Day enum to string""" - * if day == Day.CurrentDay: - */ - -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, __PYX_ENUM_CLASS_DECL Day __pyx_v_day) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("_day_to_str", 1); - - /* "PyPTRouter.pyx":256 - * cdef str _day_to_str(self, Day day): - * """Convert Day enum to string""" - * if day == Day.CurrentDay: # <<<<<<<<<<<<<< - * return "current_day" - * else: - */ - __pyx_t_1 = (__pyx_v_day == Day::CurrentDay); - if (__pyx_t_1) { - - /* "PyPTRouter.pyx":257 - * """Convert Day enum to string""" - * if day == Day.CurrentDay: - * return "current_day" # <<<<<<<<<<<<<< - * else: - * return "next_day" - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_n_u_current_day); - __pyx_r = __pyx_n_u_current_day; - goto __pyx_L0; - - /* "PyPTRouter.pyx":256 - * cdef str _day_to_str(self, Day day): - * """Convert Day enum to string""" - * if day == Day.CurrentDay: # <<<<<<<<<<<<<< - * return "current_day" - * else: - */ - } - - /* "PyPTRouter.pyx":259 - * return "current_day" - * else: - * return "next_day" # <<<<<<<<<<<<<< - * - * cdef _convert_journey_step(self, JourneyStep step): - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_n_u_next_day); - __pyx_r = __pyx_n_u_next_day; - goto __pyx_L0; - } - - /* "PyPTRouter.pyx":254 - * return journey_dict - * - * cdef str _day_to_str(self, Day day): # <<<<<<<<<<<<<< - * """Convert Day enum to string""" - * if day == Day.CurrentDay: - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "PyPTRouter.pyx":261 - * return "next_day" - * - * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< - * """Convert a JourneyStep to Python dictionary""" - * - */ - -static PyObject *__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step(struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, struct JourneyStep __pyx_v_step) { - std::string __pyx_v_stop_id_str; - PyObject *__pyx_v_step_dict = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - std::string __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - __Pyx_FakeReference __pyx_t_5; - __Pyx_FakeReference __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_convert_journey_step", 1); - - /* "PyPTRouter.pyx":264 - * """Convert a JourneyStep to Python dictionary""" - * - * cdef string stop_id_str = string(b"stop_id") # <<<<<<<<<<<<<< - * - * step_dict = { - */ - try { - __pyx_t_1 = std::string(((char const *)"stop_id")); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 264, __pyx_L1_error) - } - __pyx_v_stop_id_str = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_1); - - /* "PyPTRouter.pyx":268 - * step_dict = { - * # Basic information - * "duration": step.duration, # <<<<<<<<<<<<<< - * - * # Time information - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.duration); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_duration, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":271 - * - * # Time information - * "departure_time": step.departure_secs, # <<<<<<<<<<<<<< - * "arrival_time": step.arrival_secs, - * "day": self._day_to_str(step.day), - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.departure_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 271, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_departure_time, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":272 - * # Time information - * "departure_time": step.departure_secs, - * "arrival_time": step.arrival_secs, # <<<<<<<<<<<<<< - * "day": self._day_to_str(step.day), - * - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_step.arrival_secs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 272, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_arrival_time, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":273 - * "departure_time": step.departure_secs, - * "arrival_time": step.arrival_secs, - * "day": self._day_to_str(step.day), # <<<<<<<<<<<<<< - * - * # Stop information - */ - __pyx_t_3 = ((struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter *)__pyx_v_self->__pyx_vtab)->_day_to_str(__pyx_v_self, __pyx_v_step.day); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 273, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_day, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":276 - * - * # Stop information - * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< - * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), - * } - */ - __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.src_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 276, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_from_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":277 - * # Stop information - * "from_stop_id": step.src_stop.getField(stop_id_str).decode('utf-8'), - * "to_stop_id": step.dest_stop.getField(stop_id_str).decode('utf-8'), # <<<<<<<<<<<<<< - * } - * - */ - __pyx_t_3 = __Pyx_decode_cpp_string(__pyx_v_step.dest_stop->getField(__pyx_v_stop_id_str), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 277, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_to_stop_id, __pyx_t_3) < 0) __PYX_ERR(0, 268, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_step_dict = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":281 - * - * # Handle optional fields - * if step.trip_id.has_value(): # <<<<<<<<<<<<<< - * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') - * else: - */ - __pyx_t_4 = (__pyx_v_step.trip_id.has_value() != 0); - if (__pyx_t_4) { - - /* "PyPTRouter.pyx":282 - * # Handle optional fields - * if step.trip_id.has_value(): - * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') # <<<<<<<<<<<<<< - * else: - * step_dict["trip_id"] = "walking" - */ - try { - __pyx_t_5 = __pyx_v_step.trip_id.value(); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 282, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_5, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 282, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_t_2) < 0))) __PYX_ERR(0, 282, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":281 - * - * # Handle optional fields - * if step.trip_id.has_value(): # <<<<<<<<<<<<<< - * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') - * else: - */ - goto __pyx_L3; - } - - /* "PyPTRouter.pyx":284 - * step_dict["trip_id"] = step.trip_id.value().decode('utf-8') - * else: - * step_dict["trip_id"] = "walking" # <<<<<<<<<<<<<< - * - * if step.agency_name.has_value(): - */ - /*else*/ { - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_trip_id, __pyx_n_u_walking) < 0))) __PYX_ERR(0, 284, __pyx_L1_error) - } - __pyx_L3:; - - /* "PyPTRouter.pyx":286 - * step_dict["trip_id"] = "walking" - * - * if step.agency_name.has_value(): # <<<<<<<<<<<<<< - * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') - * else: - */ - __pyx_t_4 = (__pyx_v_step.agency_name.has_value() != 0); - if (__pyx_t_4) { - - /* "PyPTRouter.pyx":287 - * - * if step.agency_name.has_value(): - * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') # <<<<<<<<<<<<<< - * else: - * step_dict["agency_name"] = "Unknown" - */ - try { - __pyx_t_6 = __pyx_v_step.agency_name.value(); - } catch(...) { - __Pyx_CppExn2PyErr(); - __PYX_ERR(0, 287, __pyx_L1_error) - } - __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_6, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_t_2) < 0))) __PYX_ERR(0, 287, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":286 - * step_dict["trip_id"] = "walking" - * - * if step.agency_name.has_value(): # <<<<<<<<<<<<<< - * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') - * else: - */ - goto __pyx_L4; - } - - /* "PyPTRouter.pyx":289 - * step_dict["agency_name"] = step.agency_name.value().decode('utf-8') - * else: - * step_dict["agency_name"] = "Unknown" # <<<<<<<<<<<<<< - * - * return step_dict - */ - /*else*/ { - if (unlikely((PyDict_SetItem(__pyx_v_step_dict, __pyx_n_u_agency_name, __pyx_n_u_Unknown) < 0))) __PYX_ERR(0, 289, __pyx_L1_error) - } - __pyx_L4:; - - /* "PyPTRouter.pyx":291 - * step_dict["agency_name"] = "Unknown" - * - * return step_dict # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_step_dict); - __pyx_r = __pyx_v_step_dict; - goto __pyx_L0; - - /* "PyPTRouter.pyx":261 - * return "next_day" - * - * cdef _convert_journey_step(self, JourneyStep step): # <<<<<<<<<<<<<< - * """Convert a JourneyStep to Python dictionary""" - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("PyPTRouter.PyPTRouter._convert_journey_step", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_step_dict); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__, "PyPTRouter.__reduce_cython__(self)"); -static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_11__reduce_cython__ = {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__}; -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -) { - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - #if !CYTHON_METH_FASTCALL - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; - #endif - #endif - __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); - if (unlikely(__pyx_nargs > 0)) { - __Pyx_RaiseArgtupleInvalid("__reduce_cython__", 1, 0, 0, __pyx_nargs); return NULL;} - if (unlikely(__pyx_kwds) && __Pyx_NumKwargs_FASTCALL(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__reduce_cython__", 0))) return NULL; - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 1); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -); /*proto*/ -PyDoc_STRVAR(__pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__, "PyPTRouter.__setstate_cython__(self, __pyx_state)"); -static PyMethodDef __pyx_mdef_10PyPTRouter_10PyPTRouter_13__setstate_cython__ = {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__}; -static PyObject *__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__(PyObject *__pyx_v_self, -#if CYTHON_METH_FASTCALL -PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds -#else -PyObject *__pyx_args, PyObject *__pyx_kwds -#endif -) { - CYTHON_UNUSED PyObject *__pyx_v___pyx_state = 0; - #if !CYTHON_METH_FASTCALL - CYTHON_UNUSED Py_ssize_t __pyx_nargs; - #endif - CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[1] = {0}; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - #if !CYTHON_METH_FASTCALL - #if CYTHON_ASSUME_SAFE_MACROS - __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); - #else - __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; - #endif - #endif - __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); - { - PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_state,0}; - if (__pyx_kwds) { - Py_ssize_t kw_args; - switch (__pyx_nargs) { - case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); - switch (__pyx_nargs) { - case 0: - if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_pyx_state)) != 0)) { - (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); - kw_args--; - } - else if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 3, __pyx_L3_error) - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__setstate_cython__") < 0)) __PYX_ERR(1, 3, __pyx_L3_error) - } - } else if (unlikely(__pyx_nargs != 1)) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); - } - __pyx_v___pyx_state = values[0]; - } - goto __pyx_L6_skip; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__setstate_cython__", 1, 1, 1, __pyx_nargs); __PYX_ERR(1, 3, __pyx_L3_error) - __pyx_L6_skip:; - goto __pyx_L4_argument_unpacking_done; - __pyx_L3_error:; - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(((struct __pyx_obj_10PyPTRouter_PyPTRouter *)__pyx_v_self), __pyx_v___pyx_state); - - /* function exit code */ - { - Py_ssize_t __pyx_temp; - for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { - __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); - } - } - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_10PyPTRouter_10PyPTRouter_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_10PyPTRouter_PyPTRouter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 1); - - /* "(tree fragment)":4 - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" # <<<<<<<<<<<<<< - */ - __Pyx_Raise(__pyx_builtin_TypeError, __pyx_kp_s_no_default___reduce___due_to_non, 0, 0); - __PYX_ERR(1, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("PyPTRouter.PyPTRouter.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} -static struct __pyx_vtabstruct_10PyPTRouter_PyPTRouter __pyx_vtable_10PyPTRouter_PyPTRouter; - -static PyObject *__pyx_tp_new_10PyPTRouter_PyPTRouter(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_obj_10PyPTRouter_PyPTRouter *p; - PyObject *o; - #if CYTHON_COMPILING_IN_LIMITED_API - allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc); - o = alloc_func(t, 0); - #else - if (likely(!__Pyx_PyType_HasFeature(t, Py_TPFLAGS_IS_ABSTRACT))) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - #endif - p = ((struct __pyx_obj_10PyPTRouter_PyPTRouter *)o); - p->__pyx_vtab = __pyx_vtabptr_10PyPTRouter_PyPTRouter; - if (unlikely(__pyx_pw_10PyPTRouter_10PyPTRouter_1__cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_10PyPTRouter_PyPTRouter(PyObject *o) { - #if CYTHON_USE_TP_FINALIZE - if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) { - if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_10PyPTRouter_PyPTRouter) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - } - #endif - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_pw_10PyPTRouter_10PyPTRouter_3__dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - (*Py_TYPE(o)->tp_free)(o); - #else - { - freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free); - if (tp_free) tp_free(o); - } - #endif -} - -static PyMethodDef __pyx_methods_10PyPTRouter_PyPTRouter[] = { - {"construct_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_4construct_query}, - {"return_pt_journeys_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_6return_pt_journeys_1to1}, - {"return_fastest_pt_journey_1to1", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_8return_fastest_pt_journey_1to1}, - {"__reduce_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_10__reduce_cython__}, - {"__setstate_cython__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_10PyPTRouter_10PyPTRouter_12__setstate_cython__}, - {0, 0, 0, 0} -}; -#if CYTHON_USE_TYPE_SPECS -static PyType_Slot __pyx_type_10PyPTRouter_PyPTRouter_slots[] = { - {Py_tp_dealloc, (void *)__pyx_tp_dealloc_10PyPTRouter_PyPTRouter}, - {Py_tp_methods, (void *)__pyx_methods_10PyPTRouter_PyPTRouter}, - {Py_tp_new, (void *)__pyx_tp_new_10PyPTRouter_PyPTRouter}, - {0, 0}, -}; -static PyType_Spec __pyx_type_10PyPTRouter_PyPTRouter_spec = { - "PyPTRouter.PyPTRouter", - sizeof(struct __pyx_obj_10PyPTRouter_PyPTRouter), - 0, - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, - __pyx_type_10PyPTRouter_PyPTRouter_slots, -}; -#else - -static PyTypeObject __pyx_type_10PyPTRouter_PyPTRouter = { - PyVarObject_HEAD_INIT(0, 0) - "PyPTRouter.""PyPTRouter", /*tp_name*/ - sizeof(struct __pyx_obj_10PyPTRouter_PyPTRouter), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_10PyPTRouter_PyPTRouter, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_10PyPTRouter_PyPTRouter, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - #if !CYTHON_USE_TYPE_SPECS - 0, /*tp_dictoffset*/ - #endif - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_10PyPTRouter_PyPTRouter, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - #if CYTHON_USE_TP_FINALIZE - 0, /*tp_finalize*/ - #else - NULL, /*tp_finalize*/ - #endif - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if __PYX_NEED_TP_PRINT_SLOT == 1 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030C0000 - 0, /*tp_watched*/ - #endif - #if PY_VERSION_HEX >= 0x030d00A4 - 0, /*tp_versions_used*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, /*tp_pypy_flags*/ - #endif -}; -#endif - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif -/* #### Code section: pystring_table ### */ - -static int __Pyx_CreateStringTabAndInitStrings(void) { - __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_Expected_string_int_tuple_got, __pyx_k_Expected_string_int_tuple_got, sizeof(__pyx_k_Expected_string_int_tuple_got), 0, 1, 0, 0}, - {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, - {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, - {&__pyx_kp_s_No_value_specified_for_struct_at, __pyx_k_No_value_specified_for_struct_at, sizeof(__pyx_k_No_value_specified_for_struct_at), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_10, __pyx_k_No_value_specified_for_struct_at_10, sizeof(__pyx_k_No_value_specified_for_struct_at_10), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_11, __pyx_k_No_value_specified_for_struct_at_11, sizeof(__pyx_k_No_value_specified_for_struct_at_11), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_12, __pyx_k_No_value_specified_for_struct_at_12, sizeof(__pyx_k_No_value_specified_for_struct_at_12), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_2, __pyx_k_No_value_specified_for_struct_at_2, sizeof(__pyx_k_No_value_specified_for_struct_at_2), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_3, __pyx_k_No_value_specified_for_struct_at_3, sizeof(__pyx_k_No_value_specified_for_struct_at_3), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_4, __pyx_k_No_value_specified_for_struct_at_4, sizeof(__pyx_k_No_value_specified_for_struct_at_4), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_5, __pyx_k_No_value_specified_for_struct_at_5, sizeof(__pyx_k_No_value_specified_for_struct_at_5), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_6, __pyx_k_No_value_specified_for_struct_at_6, sizeof(__pyx_k_No_value_specified_for_struct_at_6), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_7, __pyx_k_No_value_specified_for_struct_at_7, sizeof(__pyx_k_No_value_specified_for_struct_at_7), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_8, __pyx_k_No_value_specified_for_struct_at_8, sizeof(__pyx_k_No_value_specified_for_struct_at_8), 0, 0, 1, 0}, - {&__pyx_kp_s_No_value_specified_for_struct_at_9, __pyx_k_No_value_specified_for_struct_at_9, sizeof(__pyx_k_No_value_specified_for_struct_at_9), 0, 0, 1, 0}, - {&__pyx_n_s_PyPTRouter, __pyx_k_PyPTRouter, sizeof(__pyx_k_PyPTRouter), 0, 0, 1, 1}, - {&__pyx_n_s_PyPTRouter___reduce_cython, __pyx_k_PyPTRouter___reduce_cython, sizeof(__pyx_k_PyPTRouter___reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_PyPTRouter___setstate_cython, __pyx_k_PyPTRouter___setstate_cython, sizeof(__pyx_k_PyPTRouter___setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_PyPTRouter_construct_query, __pyx_k_PyPTRouter_construct_query, sizeof(__pyx_k_PyPTRouter_construct_query), 0, 0, 1, 1}, - {&__pyx_kp_s_PyPTRouter_pyx, __pyx_k_PyPTRouter_pyx, sizeof(__pyx_k_PyPTRouter_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_PyPTRouter_return_fastest_pt_jou, __pyx_k_PyPTRouter_return_fastest_pt_jou, sizeof(__pyx_k_PyPTRouter_return_fastest_pt_jou), 0, 0, 1, 1}, - {&__pyx_n_s_PyPTRouter_return_pt_journeys_1t, __pyx_k_PyPTRouter_return_pt_journeys_1t, sizeof(__pyx_k_PyPTRouter_return_pt_journeys_1t), 0, 0, 1, 1}, - {&__pyx_kp_u_RAPTOR_router_not_initialized_Pl, __pyx_k_RAPTOR_router_not_initialized_Pl, sizeof(__pyx_k_RAPTOR_router_not_initialized_Pl), 0, 1, 0, 0}, - {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_n_u_Unknown, __pyx_k_Unknown, sizeof(__pyx_k_Unknown), 0, 1, 0, 1}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 1}, - {&__pyx_kp_u__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 1, 0, 0}, - {&__pyx_n_s__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 1, 1}, - {&__pyx_n_u_agency_name, __pyx_k_agency_name, sizeof(__pyx_k_agency_name), 0, 1, 0, 1}, - {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1}, - {&__pyx_n_u_arrival_time, __pyx_k_arrival_time, sizeof(__pyx_k_arrival_time), 0, 1, 0, 1}, - {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_construct_query, __pyx_k_construct_query, sizeof(__pyx_k_construct_query), 0, 0, 1, 1}, - {&__pyx_n_u_current_day, __pyx_k_current_day, sizeof(__pyx_k_current_day), 0, 1, 0, 1}, - {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1}, - {&__pyx_n_s_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 0, 1, 1}, - {&__pyx_n_s_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 0, 1, 1}, - {&__pyx_n_u_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 1, 0, 1}, - {&__pyx_n_s_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 0, 1, 1}, - {&__pyx_n_u_departure_time, __pyx_k_departure_time, sizeof(__pyx_k_departure_time), 0, 1, 0, 1}, - {&__pyx_n_s_detailed, __pyx_k_detailed, sizeof(__pyx_k_detailed), 0, 0, 1, 1}, - {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0}, - {&__pyx_n_u_duration, __pyx_k_duration, sizeof(__pyx_k_duration), 0, 1, 0, 1}, - {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0}, - {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, - {&__pyx_n_u_from_stop_id, __pyx_k_from_stop_id, sizeof(__pyx_k_from_stop_id), 0, 1, 0, 1}, - {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_n_s_hour, __pyx_k_hour, sizeof(__pyx_k_hour), 0, 0, 1, 1}, - {&__pyx_n_s_hours, __pyx_k_hours, sizeof(__pyx_k_hours), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_inc_src, __pyx_k_inc_src, sizeof(__pyx_k_inc_src), 0, 0, 1, 1}, - {&__pyx_n_s_inc_tgt, __pyx_k_inc_tgt, sizeof(__pyx_k_inc_tgt), 0, 0, 1, 1}, - {&__pyx_n_s_included_sources, __pyx_k_included_sources, sizeof(__pyx_k_included_sources), 0, 0, 1, 1}, - {&__pyx_n_s_included_targets, __pyx_k_included_targets, sizeof(__pyx_k_included_targets), 0, 0, 1, 1}, - {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1}, - {&__pyx_n_s_input_directory, __pyx_k_input_directory, sizeof(__pyx_k_input_directory), 0, 0, 1, 1}, - {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1}, - {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0}, - {&__pyx_n_s_journey, __pyx_k_journey, sizeof(__pyx_k_journey), 0, 0, 1, 1}, - {&__pyx_n_s_journey_dict, __pyx_k_journey_dict, sizeof(__pyx_k_journey_dict), 0, 0, 1, 1}, - {&__pyx_n_s_journey_opt, __pyx_k_journey_opt, sizeof(__pyx_k_journey_opt), 0, 0, 1, 1}, - {&__pyx_n_s_journeys, __pyx_k_journeys, sizeof(__pyx_k_journeys), 0, 0, 1, 1}, - {&__pyx_n_s_journeys_list, __pyx_k_journeys_list, sizeof(__pyx_k_journeys_list), 0, 0, 1, 1}, - {&__pyx_n_s_json, __pyx_k_json, sizeof(__pyx_k_json), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_max_transfers, __pyx_k_max_transfers, sizeof(__pyx_k_max_transfers), 0, 0, 1, 1}, - {&__pyx_n_s_minute, __pyx_k_minute, sizeof(__pyx_k_minute), 0, 0, 1, 1}, - {&__pyx_n_s_minutes, __pyx_k_minutes, sizeof(__pyx_k_minutes), 0, 0, 1, 1}, - {&__pyx_n_s_month, __pyx_k_month, sizeof(__pyx_k_month), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_u_next_day, __pyx_k_next_day, sizeof(__pyx_k_next_day), 0, 1, 0, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_n_u_num_transfers, __pyx_k_num_transfers, sizeof(__pyx_k_num_transfers), 0, 1, 0, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_query, __pyx_k_query, sizeof(__pyx_k_query), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_return_fastest_pt_journey_1to1, __pyx_k_return_fastest_pt_journey_1to1, sizeof(__pyx_k_return_fastest_pt_journey_1to1), 0, 0, 1, 1}, - {&__pyx_n_s_return_pt_journeys_1to1, __pyx_k_return_pt_journeys_1to1, sizeof(__pyx_k_return_pt_journeys_1to1), 0, 0, 1, 1}, - {&__pyx_n_s_second, __pyx_k_second, sizeof(__pyx_k_second), 0, 0, 1, 1}, - {&__pyx_n_s_seconds, __pyx_k_seconds, sizeof(__pyx_k_seconds), 0, 0, 1, 1}, - {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_source_station_departure_datetim, __pyx_k_source_station_departure_datetim, sizeof(__pyx_k_source_station_departure_datetim), 0, 0, 1, 1}, - {&__pyx_n_u_source_station_departure_day, __pyx_k_source_station_departure_day, sizeof(__pyx_k_source_station_departure_day), 0, 1, 0, 1}, - {&__pyx_n_u_source_station_departure_time, __pyx_k_source_station_departure_time, sizeof(__pyx_k_source_station_departure_time), 0, 1, 0, 1}, - {&__pyx_n_u_source_transfer_time, __pyx_k_source_transfer_time, sizeof(__pyx_k_source_transfer_time), 0, 1, 0, 1}, - {&__pyx_n_u_source_waiting_time, __pyx_k_source_waiting_time, sizeof(__pyx_k_source_waiting_time), 0, 1, 0, 1}, - {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1}, - {&__pyx_n_s_src_vec, __pyx_k_src_vec, sizeof(__pyx_k_src_vec), 0, 0, 1, 1}, - {&__pyx_n_u_steps, __pyx_k_steps, sizeof(__pyx_k_steps), 0, 1, 0, 1}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_u_target_station_arrival_day, __pyx_k_target_station_arrival_day, sizeof(__pyx_k_target_station_arrival_day), 0, 1, 0, 1}, - {&__pyx_n_u_target_station_arrival_time, __pyx_k_target_station_arrival_time, sizeof(__pyx_k_target_station_arrival_time), 0, 1, 0, 1}, - {&__pyx_n_u_target_transfer_time, __pyx_k_target_transfer_time, sizeof(__pyx_k_target_transfer_time), 0, 1, 0, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_tgt_vec, __pyx_k_tgt_vec, sizeof(__pyx_k_tgt_vec), 0, 0, 1, 1}, - {&__pyx_n_u_to_stop_id, __pyx_k_to_stop_id, sizeof(__pyx_k_to_stop_id), 0, 1, 0, 1}, - {&__pyx_n_u_trip_id, __pyx_k_trip_id, sizeof(__pyx_k_trip_id), 0, 1, 0, 1}, - {&__pyx_n_u_trip_time, __pyx_k_trip_time, sizeof(__pyx_k_trip_time), 0, 1, 0, 1}, - {&__pyx_kp_u_utf_8, __pyx_k_utf_8, sizeof(__pyx_k_utf_8), 0, 1, 0, 0}, - {&__pyx_n_u_walking, __pyx_k_walking, sizeof(__pyx_k_walking), 0, 1, 0, 1}, - {&__pyx_n_s_weekday, __pyx_k_weekday, sizeof(__pyx_k_weekday), 0, 0, 1, 1}, - {&__pyx_n_s_year, __pyx_k_year, sizeof(__pyx_k_year), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} - }; - return __Pyx_InitStrings(__pyx_string_tab); -} -/* #### Code section: cached_builtins ### */ -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 110, __pyx_L1_error) - __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 145, __pyx_L1_error) - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 161, __pyx_L1_error) - __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(1, 68, __pyx_L1_error) - __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(1, 19, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 20, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} -/* #### Code section: cached_constants ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "FromPyStructUtility":20 - * value = obj['year'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'year'") # <<<<<<<<<<<<<< - * result.year = value - * try: - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "FromPyStructUtility":25 - * value = obj['month'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'month'") # <<<<<<<<<<<<<< - * result.month = value - * try: - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_2); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - - /* "FromPyStructUtility":30 - * value = obj['day'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'day'") # <<<<<<<<<<<<<< - * result.day = value - * try: - */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_3); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); - - /* "FromPyStructUtility":35 - * value = obj['weekday'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'weekday'") # <<<<<<<<<<<<<< - * result.weekday = value - * return result - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_4); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "FromPyStructUtility":20 - * value = obj['hours'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'hours'") # <<<<<<<<<<<<<< - * result.hours = value - * try: - */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_5); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); - - /* "FromPyStructUtility":25 - * value = obj['minutes'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'minutes'") # <<<<<<<<<<<<<< - * result.minutes = value - * try: - */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_6); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); - - /* "FromPyStructUtility":30 - * value = obj['seconds'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'seconds'") # <<<<<<<<<<<<<< - * result.seconds = value - * return result - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_7); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "FromPyStructUtility":20 - * value = obj['included_sources'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_sources'") # <<<<<<<<<<<<<< - * result.included_sources = value - * try: - */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_8); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 20, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* "FromPyStructUtility":25 - * value = obj['included_targets'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'included_targets'") # <<<<<<<<<<<<<< - * result.included_targets = value - * try: - */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_9); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); - - /* "FromPyStructUtility":30 - * value = obj['date'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'date'") # <<<<<<<<<<<<<< - * result.date = value - * try: - */ - __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_10); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(1, 30, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); - - /* "FromPyStructUtility":35 - * value = obj['departure_time'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'departure_time'") # <<<<<<<<<<<<<< - * result.departure_time = value - * try: - */ - __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_11); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(1, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__11); - __Pyx_GIVEREF(__pyx_tuple__11); - - /* "FromPyStructUtility":40 - * value = obj['max_transfers'] - * except KeyError: - * raise ValueError("No value specified for struct attribute 'max_transfers'") # <<<<<<<<<<<<<< - * result.max_transfers = value - * return result - */ - __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_No_value_specified_for_struct_at_12); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(1, 40, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - - /* "PyPTRouter.pyx":145 - * """ - * if self.raptor_ptr == NULL: - * raise RuntimeError("RAPTOR router not initialized. Please initialize first.") # <<<<<<<<<<<<<< - * - * query = self.construct_query( - */ - __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_RAPTOR_router_not_initialized_Pl); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 145, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__13); - __Pyx_GIVEREF(__pyx_tuple__13); - - /* "PyPTRouter.pyx":71 - * del self.raptor_ptr - * - * def construct_query( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_tuple__16 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_year, __pyx_n_s_month, __pyx_n_s_day, __pyx_n_s_weekday, __pyx_n_s_hours, __pyx_n_s_minutes, __pyx_n_s_seconds, __pyx_n_s_date, __pyx_n_s_departure_time, __pyx_n_s_query, __pyx_n_s_src_vec, __pyx_n_s_tgt_vec, __pyx_n_s_inc_src, __pyx_n_s_inc_tgt); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); - __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(5, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_construct_query, 71, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) __PYX_ERR(0, 71, __pyx_L1_error) - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); - - /* "PyPTRouter.pyx":121 - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - * - * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_tuple__19 = PyTuple_Pack(11, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journeys, __pyx_n_s_journeys_list, __pyx_n_s_i, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); - __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_pt_journeys_1to1, 121, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 121, __pyx_L1_error) - __pyx_tuple__21 = PyTuple_Pack(2, __pyx_int_neg_1, Py_False); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__21); - __Pyx_GIVEREF(__pyx_tuple__21); - - /* "PyPTRouter.pyx":167 - * return journeys_list - * - * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_tuple__22 = PyTuple_Pack(10, __pyx_n_s_self, __pyx_n_s_source_station_departure_datetim, __pyx_n_s_included_sources, __pyx_n_s_included_targets, __pyx_n_s_max_transfers, __pyx_n_s_detailed, __pyx_n_s_query, __pyx_n_s_journey_opt, __pyx_n_s_journey, __pyx_n_s_journey_dict); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 167, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__22); - __Pyx_GIVEREF(__pyx_tuple__22); - __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(6, 0, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_PyPTRouter_pyx, __pyx_n_s_return_fastest_pt_journey_1to1, 167, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 167, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_tuple__24 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__24); - __Pyx_GIVEREF(__pyx_tuple__24); - __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) __PYX_ERR(1, 1, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __pyx_tuple__26 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__26); - __Pyx_GIVEREF(__pyx_tuple__26); - __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) __PYX_ERR(1, 3, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} -/* #### Code section: init_constants ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) { - if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} -/* #### Code section: init_globals ### */ - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - return 0; -} -/* #### Code section: init_module ### */ - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - __pyx_vtabptr_10PyPTRouter_PyPTRouter = &__pyx_vtable_10PyPTRouter_PyPTRouter; - __pyx_vtable_10PyPTRouter_PyPTRouter._convert_journey_to_dict = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct Journey, bool))__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_to_dict; - __pyx_vtable_10PyPTRouter_PyPTRouter._day_to_str = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, __PYX_ENUM_CLASS_DECL Day))__pyx_f_10PyPTRouter_10PyPTRouter__day_to_str; - __pyx_vtable_10PyPTRouter_PyPTRouter._convert_journey_step = (PyObject *(*)(struct __pyx_obj_10PyPTRouter_PyPTRouter *, struct JourneyStep))__pyx_f_10PyPTRouter_10PyPTRouter__convert_journey_step; - #if CYTHON_USE_TYPE_SPECS - __pyx_ptype_10PyPTRouter_PyPTRouter = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_10PyPTRouter_PyPTRouter_spec, NULL); if (unlikely(!__pyx_ptype_10PyPTRouter_PyPTRouter)) __PYX_ERR(0, 10, __pyx_L1_error) - if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_10PyPTRouter_PyPTRouter_spec, __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #else - __pyx_ptype_10PyPTRouter_PyPTRouter = &__pyx_type_10PyPTRouter_PyPTRouter; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - #endif - #if !CYTHON_USE_TYPE_SPECS - if (__Pyx_PyType_Ready(__pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #endif - #if PY_MAJOR_VERSION < 3 - __pyx_ptype_10PyPTRouter_PyPTRouter->tp_print = 0; - #endif - #if !CYTHON_COMPILING_IN_LIMITED_API - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_10PyPTRouter_PyPTRouter->tp_dictoffset && __pyx_ptype_10PyPTRouter_PyPTRouter->tp_getattro == PyObject_GenericGetAttr)) { - __pyx_ptype_10PyPTRouter_PyPTRouter->tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #endif - if (__Pyx_SetVtable(__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_vtabptr_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_MergeVtables(__pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #endif - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_PyPTRouter, (PyObject *) __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #if !CYTHON_COMPILING_IN_LIMITED_API - if (__Pyx_setup_reduce((PyObject *) __pyx_ptype_10PyPTRouter_PyPTRouter) < 0) __PYX_ERR(0, 10, __pyx_L1_error) - #endif - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_PyPTRouter(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_PyPTRouter}, - {0, NULL} -}; -#endif - -#ifdef __cplusplus -namespace { - struct PyModuleDef __pyx_moduledef = - #else - static struct PyModuleDef __pyx_moduledef = - #endif - { - PyModuleDef_HEAD_INIT, - "PyPTRouter", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #elif CYTHON_USE_MODULE_STATE - sizeof(__pyx_mstate), /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - #if CYTHON_USE_MODULE_STATE - __pyx_m_traverse, /* m_traverse */ - __pyx_m_clear, /* m_clear */ - NULL /* m_free */ - #else - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ - #endif - }; - #ifdef __cplusplus -} /* anonymous namespace */ -#endif -#endif - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC initPyPTRouter(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC initPyPTRouter(void) -#else -__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -#if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none) -#else -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) -#endif -{ - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { -#if CYTHON_COMPILING_IN_LIMITED_API - result = PyModule_AddObject(module, to_name, value); -#else - result = PyDict_SetItemString(moddict, to_name, value); -#endif - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - CYTHON_UNUSED_VAR(def); - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; -#if CYTHON_COMPILING_IN_LIMITED_API - moddict = module; -#else - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; -#endif - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec_PyPTRouter(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - int stringtab_initialized = 0; - #if CYTHON_USE_MODULE_STATE - int pystate_addmodule_run = 0; - #endif - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module 'PyPTRouter' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("PyPTRouter", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #elif CYTHON_USE_MODULE_STATE - __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - { - int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef); - __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "PyPTRouter" pseudovariable */ - if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - pystate_addmodule_run = 1; - } - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #endif - CYTHON_UNUSED_VAR(__pyx_t_1); - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_PyPTRouter(void)", 0); - if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - PyEval_InitThreads(); - #endif - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - stringtab_initialized = 1; - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_PyPTRouter) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "PyPTRouter")) { - if (unlikely((PyDict_SetItemString(modules, "PyPTRouter", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely((__Pyx_modinit_type_init_code() < 0))) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_type_import_code(); - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "PyPTRouter.pyx":7 - * from libcpp.utility cimport pair - * from libcpp.optional cimport optional - * import json # <<<<<<<<<<<<<< - * from datetime import datetime - * - */ - __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_json, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_json, __pyx_t_2) < 0) __PYX_ERR(0, 7, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "PyPTRouter.pyx":8 - * from libcpp.optional cimport optional - * import json - * from datetime import datetime # <<<<<<<<<<<<<< - * - * cdef class PyPTRouter: - */ - __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_datetime); - __Pyx_GIVEREF(__pyx_n_s_datetime); - if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_datetime)) __PYX_ERR(0, 8, __pyx_L1_error); - __pyx_t_3 = __Pyx_Import(__pyx_n_s_datetime, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_datetime); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":71 - * del self.raptor_ptr - * - * def construct_query( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_5construct_query, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_construct_query, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__17)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__18); - if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_construct_query, __pyx_t_3) < 0) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); - - /* "PyPTRouter.pyx":121 - * return Query(src_vec, tgt_vec, date, departure_time, max_transfers) - * - * def return_pt_journeys_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_7return_pt_journeys_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_pt_journeys_1t, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__20)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__21); - if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_return_pt_journeys_1to1, __pyx_t_3) < 0) __PYX_ERR(0, 121, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); - - /* "PyPTRouter.pyx":167 - * return journeys_list - * - * def return_fastest_pt_journey_1to1( # <<<<<<<<<<<<<< - * self, - * source_station_departure_datetime, - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_9return_fastest_pt_journey_1to1, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter_return_fastest_pt_jou, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 167, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_tuple__21); - if (__Pyx_SetItemOnTypeDict((PyObject *)__pyx_ptype_10PyPTRouter_PyPTRouter, __pyx_n_s_return_fastest_pt_journey_1to1, __pyx_t_3) < 0) __PYX_ERR(0, 167, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_10PyPTRouter_PyPTRouter); - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_11__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter___reduce_cython, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__25)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_3) < 0) __PYX_ERR(1, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError, "no default __reduce__ due to non-trivial __cinit__" - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_10PyPTRouter_10PyPTRouter_13__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_PyPTRouter___setstate_cython, NULL, __pyx_n_s_PyPTRouter, __pyx_d, ((PyObject *)__pyx_codeobj__27)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_3) < 0) __PYX_ERR(1, 3, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "PyPTRouter.pyx":1 - * # cython: language_level=3 # <<<<<<<<<<<<<< - * from libcpp.string cimport string - * from libcpp.vector cimport vector - */ - __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_3) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - if (__pyx_m) { - if (__pyx_d && stringtab_initialized) { - __Pyx_AddTraceback("init PyPTRouter", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - #if !CYTHON_USE_MODULE_STATE - Py_CLEAR(__pyx_m); - #else - Py_DECREF(__pyx_m); - if (pystate_addmodule_run) { - PyObject *tp, *value, *tb; - PyErr_Fetch(&tp, &value, &tb); - PyState_RemoveModule(&__pyx_moduledef); - PyErr_Restore(tp, value, tb); - } - #endif - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init PyPTRouter"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} -/* #### Code section: cleanup_globals ### */ -/* #### Code section: cleanup_module ### */ -/* #### Code section: main_method ### */ -/* #### Code section: utility_code_pragmas ### */ -#ifdef _MSC_VER -#pragma warning( push ) -/* Warning 4127: conditional expression is constant - * Cython uses constant conditional expressions to allow in inline functions to be optimized at - * compile-time, so this warning is not useful - */ -#pragma warning( disable : 4127 ) -#endif - - - -/* #### Code section: utility_code_def ### */ - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; i= 0x030C00A6 - PyObject *current_exception = tstate->current_exception; - if (unlikely(!current_exception)) return 0; - exc_type = (PyObject*) Py_TYPE(current_exception); - if (exc_type == err) return 1; -#else - exc_type = tstate->curexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; -#endif - #if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(exc_type); - #endif - if (unlikely(PyTuple_Check(err))) { - result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - } else { - result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); - } - #if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(exc_type); - #endif - return result; -} -#endif - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { -#if PY_VERSION_HEX >= 0x030C00A6 - PyObject *tmp_value; - assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); - if (value) { - #if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) - #endif - PyException_SetTraceback(value, tb); - } - tmp_value = tstate->current_exception; - tstate->current_exception = value; - Py_XDECREF(tmp_value); - Py_XDECREF(type); - Py_XDECREF(tb); -#else - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#endif -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { -#if PY_VERSION_HEX >= 0x030C00A6 - PyObject* exc_value; - exc_value = tstate->current_exception; - tstate->current_exception = 0; - *value = exc_value; - *type = NULL; - *tb = NULL; - if (exc_value) { - *type = (PyObject*) Py_TYPE(exc_value); - Py_INCREF(*type); - #if CYTHON_COMPILING_IN_CPYTHON - *tb = ((PyBaseExceptionObject*) exc_value)->traceback; - Py_XINCREF(*tb); - #else - *tb = PyException_GetTraceback(exc_value); - #endif - } -#else - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#endif -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* PyObjectGetAttrStrNoError */ -#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1 -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -#endif -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1 - (void) PyObject_GetOptionalAttr(obj, attr_name, &result); - return result; -#else -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -#endif -} - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name); - if (unlikely(!result) && !PyErr_Occurred()) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* IterFinish */ -static CYTHON_INLINE int __Pyx_IterFinish(void) { - PyObject* exc_type; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - exc_type = __Pyx_PyErr_CurrentExceptionType(); - if (unlikely(exc_type)) { - if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) - return -1; - __Pyx_PyErr_Clear(); - return 0; - } - return 0; -} - -/* UnpackItemEndCheck */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { - if (unlikely(retval)) { - Py_DECREF(retval); - __Pyx_RaiseTooManyValuesError(expected); - return -1; - } - return __Pyx_IterFinish(); -} - -/* DictGetItem */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { - PyObject *value; - value = PyDict_GetItemWithError(d, key); - if (unlikely(!value)) { - if (!PyErr_Occurred()) { - if (unlikely(PyTuple_Check(key))) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) { - PyErr_SetObject(PyExc_KeyError, args); - Py_DECREF(args); - } - } else { - PyErr_SetObject(PyExc_KeyError, key); - } - } - return NULL; - } - Py_INCREF(value); - return value; -} -#endif - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - PyObject *exc_value = exc_info->exc_value; - if (exc_value == NULL || exc_value == Py_None) { - *value = NULL; - *type = NULL; - *tb = NULL; - } else { - *value = exc_value; - Py_INCREF(*value); - *type = (PyObject*) Py_TYPE(exc_value); - Py_INCREF(*type); - *tb = PyException_GetTraceback(exc_value); - } - #elif CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); - #endif -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4 - _PyErr_StackItem *exc_info = tstate->exc_info; - PyObject *tmp_value = exc_info->exc_value; - exc_info->exc_value = value; - Py_XDECREF(tmp_value); - Py_XDECREF(type); - Py_XDECREF(tb); - #else - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); - #endif -} -#endif - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type = NULL, *local_value, *local_tb = NULL; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030C00A6 - local_value = tstate->current_exception; - tstate->current_exception = 0; - if (likely(local_value)) { - local_type = (PyObject*) Py_TYPE(local_value); - Py_INCREF(local_type); - local_tb = PyException_GetTraceback(local_value); - } - #else - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - #endif -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6 - if (unlikely(tstate->current_exception)) -#elif CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - #if PY_VERSION_HEX >= 0x030B00a4 - tmp_value = exc_info->exc_value; - exc_info->exc_value = local_value; - tmp_type = NULL; - tmp_tb = NULL; - Py_XDECREF(local_type); - Py_XDECREF(local_tb); - #else - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - #endif - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = Py_TYPE(func)->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) - return NULL; - #endif - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - __Pyx_PyThreadState_declare - CYTHON_UNUSED_VAR(cause); - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { - #if PY_VERSION_HEX >= 0x030C00A6 - PyException_SetTraceback(value, tb); - #elif CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#else - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* TupleAndListFromArray */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { - PyObject *v; - Py_ssize_t i; - for (i = 0; i < length; i++) { - v = dest[i] = src[i]; - Py_INCREF(v); - } -} -static CYTHON_INLINE PyObject * -__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) -{ - PyObject *res; - if (n <= 0) { - Py_INCREF(__pyx_empty_tuple); - return __pyx_empty_tuple; - } - res = PyTuple_New(n); - if (unlikely(res == NULL)) return NULL; - __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); - return res; -} -static CYTHON_INLINE PyObject * -__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) -{ - PyObject *res; - if (n <= 0) { - return PyList_New(0); - } - res = PyList_New(n); - if (unlikely(res == NULL)) return NULL; - __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); - return res; -} -#endif - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* fastcall */ -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) -{ - Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames); - for (i = 0; i < n; i++) - { - if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i]; - } - for (i = 0; i < n; i++) - { - int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ); - if (unlikely(eq != 0)) { - if (unlikely(eq < 0)) return NULL; - return kwvalues[i]; - } - } - return NULL; -} -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 -CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { - Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames); - PyObject *dict; - dict = PyDict_New(); - if (unlikely(!dict)) - return NULL; - for (i=0; i= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject *const *kwvalues, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds)); - while (1) { - Py_XDECREF(key); key = NULL; - Py_XDECREF(value); value = NULL; - if (kwds_is_tuple) { - Py_ssize_t size; -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(kwds); -#else - size = PyTuple_Size(kwds); - if (size < 0) goto bad; -#endif - if (pos >= size) break; -#if CYTHON_AVOID_BORROWED_REFS - key = __Pyx_PySequence_ITEM(kwds, pos); - if (!key) goto bad; -#elif CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kwds, pos); -#else - key = PyTuple_GetItem(kwds, pos); - if (!key) goto bad; -#endif - value = kwvalues[pos]; - pos++; - } - else - { - if (!PyDict_Next(kwds, &pos, &key, &value)) break; -#if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(key); -#endif - } - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - Py_INCREF(value); - Py_DECREF(key); -#endif - key = NULL; - value = NULL; - continue; - } -#if !CYTHON_AVOID_BORROWED_REFS - Py_INCREF(key); -#endif - Py_INCREF(value); - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - value = NULL; -#endif - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = ( - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key) - ); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; -#if CYTHON_AVOID_BORROWED_REFS - value = NULL; -#endif - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - Py_XDECREF(key); - Py_XDECREF(value); - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - #if PY_MAJOR_VERSION < 3 - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - PyErr_Format(PyExc_TypeError, - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - Py_XDECREF(key); - Py_XDECREF(value); - return -1; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - __Pyx_TypeName type_name; - __Pyx_TypeName obj_type_name; - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - type_name = __Pyx_PyType_GetName(type); - obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME - ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name); - __Pyx_DECREF_TypeName(type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return 0; -} - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) { - return NULL; - } - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) { - return NULL; - } - #endif - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); - self = __Pyx_CyOrPyCFunction_GET_SELF(func); - #if PY_MAJOR_VERSION < 3 - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - #else - if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) - return NULL; - #endif - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectFastCall */ -#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API -static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) { - PyObject *argstuple; - PyObject *result = 0; - size_t i; - argstuple = PyTuple_New((Py_ssize_t)nargs); - if (unlikely(!argstuple)) return NULL; - for (i = 0; i < nargs; i++) { - Py_INCREF(args[i]); - if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad; - } - result = __Pyx_PyObject_Call(func, argstuple, kwargs); - bad: - Py_DECREF(argstuple); - return result; -} -#endif -static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) { - Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); -#if CYTHON_COMPILING_IN_CPYTHON - if (nargs == 0 && kwargs == NULL) { - if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) - return __Pyx_PyObject_CallMethO(func, NULL); - } - else if (nargs == 1 && kwargs == NULL) { - if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) - return __Pyx_PyObject_CallMethO(func, args[0]); - } -#endif - #if PY_VERSION_HEX < 0x030800B1 - #if CYTHON_FAST_PYCCALL - if (PyCFunction_Check(func)) { - if (kwargs) { - return _PyCFunction_FastCallDict(func, args, nargs, kwargs); - } else { - return _PyCFunction_FastCallKeywords(func, args, nargs, NULL); - } - } - #if PY_VERSION_HEX >= 0x030700A1 - if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) { - return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL); - } - #endif - #endif - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs); - } - #endif - #endif - if (kwargs == NULL) { - #if CYTHON_VECTORCALL - #if PY_VERSION_HEX < 0x03090000 - vectorcallfunc f = _PyVectorcall_Function(func); - #else - vectorcallfunc f = PyVectorcall_Function(func); - #endif - if (f) { - return f(func, args, (size_t)nargs, NULL); - } - #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL - if (__Pyx_CyFunction_CheckExact(func)) { - __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func); - if (f) return f(func, args, (size_t)nargs, NULL); - } - #endif - } - if (nargs == 0) { - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs); - } - #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API - return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); - #else - return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); - #endif -} - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (unlikely(!j)) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping; - PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence; - if (mm && mm->mp_subscript) { - PyObject *r, *key = PyInt_FromSsize_t(i); - if (unlikely(!key)) return NULL; - r = mm->mp_subscript(o, key); - Py_DECREF(key); - return r; - } - if (likely(sm && sm->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) { - Py_ssize_t l = sm->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return sm->sq_item(o, i); - } - } -#else - if (is_list || !PyMapping_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* PyObjectCallOneArg */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *args[2] = {NULL, arg}; - return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); -} - -/* PyObjectCall2Args */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args[3] = {NULL, arg1, arg2}; - return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); -} - -/* PyObjectGetMethod */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - __Pyx_TypeName type_name; - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR - if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) -#elif PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (likely(descr != NULL)) { - *method = descr; - return 0; - } - type_name = __Pyx_PyType_GetName(tp); - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", - type_name, name); -#else - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", - type_name, PyString_AS_STRING(name)); -#endif - __Pyx_DECREF_TypeName(type_name); - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod1 */ -#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2) -static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { - PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); - Py_DECREF(method); - return result; -} -#endif -static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { -#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2 - PyObject *args[2] = {obj, arg}; - (void) __Pyx_PyObject_GetMethod; - (void) __Pyx_PyObject_CallOneArg; - (void) __Pyx_PyObject_Call2Args; - return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); -#else - PyObject *method = NULL, *result; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_Call2Args(method, obj, arg); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) return NULL; - return __Pyx__PyObject_CallMethod1(method, arg); -#endif -} - -/* append */ -static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { - if (likely(PyList_CheckExact(L))) { - if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; - } else { - PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x); - if (unlikely(!retval)) - return -1; - Py_DECREF(retval); - } - return 0; -} - -/* decode_c_bytes */ -static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( - const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, - const char* encoding, const char* errors, - PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { - if (unlikely((start < 0) | (stop < 0))) { - if (start < 0) { - start += length; - if (start < 0) - start = 0; - } - if (stop < 0) - stop += length; - } - if (stop > length) - stop = length; - if (unlikely(stop <= start)) - return __Pyx_NewRef(__pyx_empty_unicode); - length = stop - start; - cstring += start; - if (decode_func) { - return decode_func(cstring, length, errors); - } else { - return PyUnicode_Decode(cstring, length, encoding, errors); - } -} - -/* KeywordStringCheck */ -static int __Pyx_CheckKeywordStrings( - PyObject *kw, - const char* function_name, - int kw_allowed) -{ - PyObject* key = 0; - Py_ssize_t pos = 0; -#if CYTHON_COMPILING_IN_PYPY - if (!kw_allowed && PyDict_Next(kw, &pos, &key, 0)) - goto invalid_keyword; - return 1; -#else - if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kw))) { - Py_ssize_t kwsize; -#if CYTHON_ASSUME_SAFE_MACROS - kwsize = PyTuple_GET_SIZE(kw); -#else - kwsize = PyTuple_Size(kw); - if (kwsize < 0) return 0; -#endif - if (unlikely(kwsize == 0)) - return 1; - if (!kw_allowed) { -#if CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kw, 0); -#else - key = PyTuple_GetItem(kw, pos); - if (!key) return 0; -#endif - goto invalid_keyword; - } -#if PY_VERSION_HEX < 0x03090000 - for (pos = 0; pos < kwsize; pos++) { -#if CYTHON_ASSUME_SAFE_MACROS - key = PyTuple_GET_ITEM(kw, pos); -#else - key = PyTuple_GetItem(kw, pos); - if (!key) return 0; -#endif - if (unlikely(!PyUnicode_Check(key))) - goto invalid_keyword_type; - } -#endif - return 1; - } - while (PyDict_Next(kw, &pos, &key, 0)) { - #if PY_MAJOR_VERSION < 3 - if (unlikely(!PyString_Check(key))) - #endif - if (unlikely(!PyUnicode_Check(key))) - goto invalid_keyword_type; - } - if (!kw_allowed && unlikely(key)) - goto invalid_keyword; - return 1; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - return 0; -#endif -invalid_keyword: - #if PY_MAJOR_VERSION < 3 - PyErr_Format(PyExc_TypeError, - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - PyErr_Format(PyExc_TypeError, - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif - return 0; -} - -/* FixUpExtensionType */ -#if CYTHON_USE_TYPE_SPECS -static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { -#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - CYTHON_UNUSED_VAR(spec); - CYTHON_UNUSED_VAR(type); -#else - const PyType_Slot *slot = spec->slots; - while (slot && slot->slot && slot->slot != Py_tp_members) - slot++; - if (slot && slot->slot == Py_tp_members) { - int changed = 0; -#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON) - const -#endif - PyMemberDef *memb = (PyMemberDef*) slot->pfunc; - while (memb && memb->name) { - if (memb->name[0] == '_' && memb->name[1] == '_') { -#if PY_VERSION_HEX < 0x030900b1 - if (strcmp(memb->name, "__weaklistoffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); - type->tp_weaklistoffset = memb->offset; - changed = 1; - } - else if (strcmp(memb->name, "__dictoffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); - type->tp_dictoffset = memb->offset; - changed = 1; - } -#if CYTHON_METH_FASTCALL - else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); -#if PY_VERSION_HEX >= 0x030800b4 - type->tp_vectorcall_offset = memb->offset; -#else - type->tp_print = (printfunc) memb->offset; -#endif - changed = 1; - } -#endif -#else - if ((0)); -#endif -#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON - else if (strcmp(memb->name, "__module__") == 0) { - PyObject *descr; - assert(memb->type == T_OBJECT); - assert(memb->flags == 0 || memb->flags == READONLY); - descr = PyDescr_NewMember(type, memb); - if (unlikely(!descr)) - return -1; - if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - changed = 1; - } -#endif - } - memb++; - } - if (changed) - PyType_Modified(type); - } -#endif - return 0; -} -#endif - -/* PyObjectCallNoArg */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { - PyObject *arg[2] = {NULL, NULL}; - return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); -} - -/* PyObjectCallMethod0 */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { - PyObject *method = NULL, *result = NULL; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_CallOneArg(method, obj); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) goto bad; - result = __Pyx_PyObject_CallNoArg(method); - Py_DECREF(method); -bad: - return result; -} - -/* ValidateBasesTuple */ -#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS -static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) { - Py_ssize_t i, n; -#if CYTHON_ASSUME_SAFE_MACROS - n = PyTuple_GET_SIZE(bases); -#else - n = PyTuple_Size(bases); - if (n < 0) return -1; -#endif - for (i = 1; i < n; i++) - { -#if CYTHON_AVOID_BORROWED_REFS - PyObject *b0 = PySequence_GetItem(bases, i); - if (!b0) return -1; -#elif CYTHON_ASSUME_SAFE_MACROS - PyObject *b0 = PyTuple_GET_ITEM(bases, i); -#else - PyObject *b0 = PyTuple_GetItem(bases, i); - if (!b0) return -1; -#endif - PyTypeObject *b; -#if PY_MAJOR_VERSION < 3 - if (PyClass_Check(b0)) - { - PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class", - PyString_AS_STRING(((PyClassObject*)b0)->cl_name)); -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } -#endif - b = (PyTypeObject*) b0; - if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) - { - __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); - PyErr_Format(PyExc_TypeError, - "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name); - __Pyx_DECREF_TypeName(b_name); -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } - if (dictoffset == 0) - { - Py_ssize_t b_dictoffset = 0; -#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY - b_dictoffset = b->tp_dictoffset; -#else - PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__"); - if (!py_b_dictoffset) goto dictoffset_return; - b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset); - Py_DECREF(py_b_dictoffset); - if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return; -#endif - if (b_dictoffset) { - { - __Pyx_TypeName b_name = __Pyx_PyType_GetName(b); - PyErr_Format(PyExc_TypeError, - "extension type '%.200s' has no __dict__ slot, " - "but base type '" __Pyx_FMT_TYPENAME "' has: " - "either add 'cdef dict __dict__' to the extension type " - "or add '__slots__ = [...]' to the base type", - type_name, b_name); - __Pyx_DECREF_TypeName(b_name); - } -#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY) - dictoffset_return: -#endif -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - return -1; - } - } -#if CYTHON_AVOID_BORROWED_REFS - Py_DECREF(b0); -#endif - } - return 0; -} -#endif - -/* PyType_Ready */ -static int __Pyx_PyType_Ready(PyTypeObject *t) { -#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION) - (void)__Pyx_PyObject_CallMethod0; -#if CYTHON_USE_TYPE_SPECS - (void)__Pyx_validate_bases_tuple; -#endif - return PyType_Ready(t); -#else - int r; - PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*); - if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1)) - return -1; -#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) - { - int gc_was_enabled; - #if PY_VERSION_HEX >= 0x030A00b1 - gc_was_enabled = PyGC_Disable(); - (void)__Pyx_PyObject_CallMethod0; - #else - PyObject *ret, *py_status; - PyObject *gc = NULL; - #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) - gc = PyImport_GetModule(__pyx_kp_u_gc); - #endif - if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc); - if (unlikely(!gc)) return -1; - py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled); - if (unlikely(!py_status)) { - Py_DECREF(gc); - return -1; - } - gc_was_enabled = __Pyx_PyObject_IsTrue(py_status); - Py_DECREF(py_status); - if (gc_was_enabled > 0) { - ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable); - if (unlikely(!ret)) { - Py_DECREF(gc); - return -1; - } - Py_DECREF(ret); - } else if (unlikely(gc_was_enabled == -1)) { - Py_DECREF(gc); - return -1; - } - #endif - t->tp_flags |= Py_TPFLAGS_HEAPTYPE; -#if PY_VERSION_HEX >= 0x030A0000 - t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; -#endif -#else - (void)__Pyx_PyObject_CallMethod0; -#endif - r = PyType_Ready(t); -#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION) - t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; - #if PY_VERSION_HEX >= 0x030A00b1 - if (gc_was_enabled) - PyGC_Enable(); - #else - if (gc_was_enabled) { - PyObject *tp, *v, *tb; - PyErr_Fetch(&tp, &v, &tb); - ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable); - if (likely(ret || r == -1)) { - Py_XDECREF(ret); - PyErr_Restore(tp, v, tb); - } else { - Py_XDECREF(tp); - Py_XDECREF(v); - Py_XDECREF(tb); - r = -1; - } - } - Py_DECREF(gc); - #endif - } -#endif - return r; -#endif -} - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp); - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", - type_name, attr_name); -#else - "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'", - type_name, PyString_AS_STRING(attr_name)); -#endif - __Pyx_DECREF_TypeName(type_name); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* SetVTable */ -static int __Pyx_SetVtable(PyTypeObject *type, void *vtable) { - PyObject *ob = PyCapsule_New(vtable, 0, 0); - if (unlikely(!ob)) - goto bad; -#if CYTHON_COMPILING_IN_LIMITED_API - if (unlikely(PyObject_SetAttr((PyObject *) type, __pyx_n_s_pyx_vtable, ob) < 0)) -#else - if (unlikely(PyDict_SetItem(type->tp_dict, __pyx_n_s_pyx_vtable, ob) < 0)) -#endif - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* GetVTable */ -static void* __Pyx_GetVtable(PyTypeObject *type) { - void* ptr; -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *ob = PyObject_GetAttr((PyObject *)type, __pyx_n_s_pyx_vtable); -#else - PyObject *ob = PyObject_GetItem(type->tp_dict, __pyx_n_s_pyx_vtable); -#endif - if (!ob) - goto bad; - ptr = PyCapsule_GetPointer(ob, 0); - if (!ptr && !PyErr_Occurred()) - PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type"); - Py_DECREF(ob); - return ptr; -bad: - Py_XDECREF(ob); - return NULL; -} - -/* MergeVTables */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_MergeVtables(PyTypeObject *type) { - int i; - void** base_vtables; - __Pyx_TypeName tp_base_name; - __Pyx_TypeName base_name; - void* unknown = (void*)-1; - PyObject* bases = type->tp_bases; - int base_depth = 0; - { - PyTypeObject* base = type->tp_base; - while (base) { - base_depth += 1; - base = base->tp_base; - } - } - base_vtables = (void**) malloc(sizeof(void*) * (size_t)(base_depth + 1)); - base_vtables[0] = unknown; - for (i = 1; i < PyTuple_GET_SIZE(bases); i++) { - void* base_vtable = __Pyx_GetVtable(((PyTypeObject*)PyTuple_GET_ITEM(bases, i))); - if (base_vtable != NULL) { - int j; - PyTypeObject* base = type->tp_base; - for (j = 0; j < base_depth; j++) { - if (base_vtables[j] == unknown) { - base_vtables[j] = __Pyx_GetVtable(base); - base_vtables[j + 1] = unknown; - } - if (base_vtables[j] == base_vtable) { - break; - } else if (base_vtables[j] == NULL) { - goto bad; - } - base = base->tp_base; - } - } - } - PyErr_Clear(); - free(base_vtables); - return 0; -bad: - tp_base_name = __Pyx_PyType_GetName(type->tp_base); - base_name = __Pyx_PyType_GetName((PyTypeObject*)PyTuple_GET_ITEM(bases, i)); - PyErr_Format(PyExc_TypeError, - "multiple bases have vtable conflict: '" __Pyx_FMT_TYPENAME "' and '" __Pyx_FMT_TYPENAME "'", tp_base_name, base_name); - __Pyx_DECREF_TypeName(tp_base_name); - __Pyx_DECREF_TypeName(base_name); - free(base_vtables); - return -1; -} -#endif - -/* SetupReduce */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, __pyx_n_s_name); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_getstate = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; - PyObject *getstate = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); -#else - getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); - if (!getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (getstate) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); -#else - object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); - if (!object_getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (object_getstate != getstate) { - goto __PYX_GOOD; - } - } -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) { - __Pyx_TypeName type_obj_name = - __Pyx_PyType_GetName((PyTypeObject*)type_obj); - PyErr_Format(PyExc_RuntimeError, - "Unable to initialize pickling for " __Pyx_FMT_TYPENAME, type_obj_name); - __Pyx_DECREF_TypeName(type_obj_name); - } - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); - Py_XDECREF(object_getstate); - Py_XDECREF(getstate); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *module = 0; - PyObject *empty_dict = 0; - PyObject *empty_list = 0; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (unlikely(!py_import)) - goto bad; - if (!from_list) { - empty_list = PyList_New(0); - if (unlikely(!empty_list)) - goto bad; - from_list = empty_list; - } - #endif - empty_dict = PyDict_New(); - if (unlikely(!empty_dict)) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if (strchr(__Pyx_MODULE_NAME, '.') != NULL) { - module = PyImport_ImportModuleLevelObject( - name, __pyx_d, empty_dict, from_list, 1); - if (unlikely(!module)) { - if (unlikely(!PyErr_ExceptionMatches(PyExc_ImportError))) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (unlikely(!py_level)) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, __pyx_d, empty_dict, from_list, level); - #endif - } - } -bad: - Py_XDECREF(empty_dict); - Py_XDECREF(empty_list); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - return module; -} - -/* ImportDottedModule */ -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) { - PyObject *partial_name = NULL, *slice = NULL, *sep = NULL; - if (unlikely(PyErr_Occurred())) { - PyErr_Clear(); - } - if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) { - partial_name = name; - } else { - slice = PySequence_GetSlice(parts_tuple, 0, count); - if (unlikely(!slice)) - goto bad; - sep = PyUnicode_FromStringAndSize(".", 1); - if (unlikely(!sep)) - goto bad; - partial_name = PyUnicode_Join(sep, slice); - } - PyErr_Format( -#if PY_MAJOR_VERSION < 3 - PyExc_ImportError, - "No module named '%s'", PyString_AS_STRING(partial_name)); -#else -#if PY_VERSION_HEX >= 0x030600B1 - PyExc_ModuleNotFoundError, -#else - PyExc_ImportError, -#endif - "No module named '%U'", partial_name); -#endif -bad: - Py_XDECREF(sep); - Py_XDECREF(slice); - Py_XDECREF(partial_name); - return NULL; -} -#endif -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) { - PyObject *imported_module; -#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) - PyObject *modules = PyImport_GetModuleDict(); - if (unlikely(!modules)) - return NULL; - imported_module = __Pyx_PyDict_GetItemStr(modules, name); - Py_XINCREF(imported_module); -#else - imported_module = PyImport_GetModule(name); -#endif - return imported_module; -} -#endif -#if PY_MAJOR_VERSION >= 3 -static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) { - Py_ssize_t i, nparts; - nparts = PyTuple_GET_SIZE(parts_tuple); - for (i=1; i < nparts && module; i++) { - PyObject *part, *submodule; -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - part = PyTuple_GET_ITEM(parts_tuple, i); -#else - part = PySequence_ITEM(parts_tuple, i); -#endif - submodule = __Pyx_PyObject_GetAttrStrNoError(module, part); -#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF(part); -#endif - Py_DECREF(module); - module = submodule; - } - if (unlikely(!module)) { - return __Pyx__ImportDottedModule_Error(name, parts_tuple, i); - } - return module; -} -#endif -static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) { -#if PY_MAJOR_VERSION < 3 - PyObject *module, *from_list, *star = __pyx_n_s__14; - CYTHON_UNUSED_VAR(parts_tuple); - from_list = PyList_New(1); - if (unlikely(!from_list)) - return NULL; - Py_INCREF(star); - PyList_SET_ITEM(from_list, 0, star); - module = __Pyx_Import(name, from_list, 0); - Py_DECREF(from_list); - return module; -#else - PyObject *imported_module; - PyObject *module = __Pyx_Import(name, NULL, 0); - if (!parts_tuple || unlikely(!module)) - return module; - imported_module = __Pyx__ImportDottedModule_Lookup(name); - if (likely(imported_module)) { - Py_DECREF(module); - return imported_module; - } - PyErr_Clear(); - return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple); -#endif -} -static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) { -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1 - PyObject *module = __Pyx__ImportDottedModule_Lookup(name); - if (likely(module)) { - PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec); - if (likely(spec)) { - PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing); - if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) { - Py_DECREF(spec); - spec = NULL; - } - Py_XDECREF(unsafe); - } - if (likely(!spec)) { - PyErr_Clear(); - return module; - } - Py_DECREF(spec); - Py_DECREF(module); - } else if (PyErr_Occurred()) { - PyErr_Clear(); - } -#endif - return __Pyx__ImportDottedModule(name, parts_tuple); -} - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - const char* module_name_str = 0; - PyObject* module_name = 0; - PyObject* module_dot = 0; - PyObject* full_name = 0; - PyErr_Clear(); - module_name_str = PyModule_GetName(module); - if (unlikely(!module_name_str)) { goto modbad; } - module_name = PyUnicode_FromString(module_name_str); - if (unlikely(!module_name)) { goto modbad; } - module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__15); - if (unlikely(!module_dot)) { goto modbad; } - full_name = PyUnicode_Concat(module_dot, name); - if (unlikely(!full_name)) { goto modbad; } - #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) - { - PyObject *modules = PyImport_GetModuleDict(); - if (unlikely(!modules)) - goto modbad; - value = PyObject_GetItem(modules, full_name); - } - #else - value = PyImport_GetModule(full_name); - #endif - modbad: - Py_XDECREF(full_name); - Py_XDECREF(module_dot); - Py_XDECREF(module_name); - } - if (unlikely(!value)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* FetchSharedCythonModule */ -static PyObject *__Pyx_FetchSharedCythonABIModule(void) { - return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME); -} - -/* FetchCommonType */ -static int __Pyx_VerifyCachedType(PyObject *cached_type, - const char *name, - Py_ssize_t basicsize, - Py_ssize_t expected_basicsize) { - if (!PyType_Check(cached_type)) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s is not a type object", name); - return -1; - } - if (basicsize != expected_basicsize) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s has the wrong size, try recompiling", - name); - return -1; - } - return 0; -} -#if !CYTHON_USE_TYPE_SPECS -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { - PyObject* abi_module; - const char* object_name; - PyTypeObject *cached_type = NULL; - abi_module = __Pyx_FetchSharedCythonABIModule(); - if (!abi_module) return NULL; - object_name = strrchr(type->tp_name, '.'); - object_name = object_name ? object_name+1 : type->tp_name; - cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name); - if (cached_type) { - if (__Pyx_VerifyCachedType( - (PyObject *)cached_type, - object_name, - cached_type->tp_basicsize, - type->tp_basicsize) < 0) { - goto bad; - } - goto done; - } - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - if (PyType_Ready(type) < 0) goto bad; - if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0) - goto bad; - Py_INCREF(type); - cached_type = type; -done: - Py_DECREF(abi_module); - return cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} -#else -static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) { - PyObject *abi_module, *cached_type = NULL; - const char* object_name = strrchr(spec->name, '.'); - object_name = object_name ? object_name+1 : spec->name; - abi_module = __Pyx_FetchSharedCythonABIModule(); - if (!abi_module) return NULL; - cached_type = PyObject_GetAttrString(abi_module, object_name); - if (cached_type) { - Py_ssize_t basicsize; -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *py_basicsize; - py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); - if (unlikely(!py_basicsize)) goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; -#else - basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1; -#endif - if (__Pyx_VerifyCachedType( - cached_type, - object_name, - basicsize, - spec->basicsize) < 0) { - goto bad; - } - goto done; - } - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - CYTHON_UNUSED_VAR(module); - cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases); - if (unlikely(!cached_type)) goto bad; - if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; - if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad; -done: - Py_DECREF(abi_module); - assert(cached_type == NULL || PyType_Check(cached_type)); - return (PyTypeObject *) cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} -#endif - -/* PyVectorcallFastCallDict */ -#if CYTHON_METH_FASTCALL -static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) -{ - PyObject *res = NULL; - PyObject *kwnames; - PyObject **newargs; - PyObject **kwvalues; - Py_ssize_t i, pos; - size_t j; - PyObject *key, *value; - unsigned long keys_are_strings; - Py_ssize_t nkw = PyDict_GET_SIZE(kw); - newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); - if (unlikely(newargs == NULL)) { - PyErr_NoMemory(); - return NULL; - } - for (j = 0; j < nargs; j++) newargs[j] = args[j]; - kwnames = PyTuple_New(nkw); - if (unlikely(kwnames == NULL)) { - PyMem_Free(newargs); - return NULL; - } - kwvalues = newargs + nargs; - pos = i = 0; - keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; - while (PyDict_Next(kw, &pos, &key, &value)) { - keys_are_strings &= Py_TYPE(key)->tp_flags; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(kwnames, i, key); - kwvalues[i] = value; - i++; - } - if (unlikely(!keys_are_strings)) { - PyErr_SetString(PyExc_TypeError, "keywords must be strings"); - goto cleanup; - } - res = vc(func, newargs, nargs, kwnames); -cleanup: - Py_DECREF(kwnames); - for (i = 0; i < nkw; i++) - Py_DECREF(kwvalues[i]); - PyMem_Free(newargs); - return res; -} -static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) -{ - if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) { - return vc(func, args, nargs, NULL); - } - return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); -} -#endif - -/* CythonFunctionShared */ -#if CYTHON_COMPILING_IN_LIMITED_API -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { - if (__Pyx_CyFunction_Check(func)) { - return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; - } else if (PyCFunction_Check(func)) { - return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; - } - return 0; -} -#else -static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) { - return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; -} -#endif -static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - __Pyx_Py_XDECREF_SET( - __Pyx_CyFunction_GetClassObj(f), - ((classobj) ? __Pyx_NewRef(classobj) : NULL)); -#else - __Pyx_Py_XDECREF_SET( - ((PyCMethodObject *) (f))->mm_class, - (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); -#endif -} -static PyObject * -__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) -{ - CYTHON_UNUSED_VAR(closure); - if (unlikely(op->func_doc == NULL)) { -#if CYTHON_COMPILING_IN_LIMITED_API - op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); - if (unlikely(!op->func_doc)) return NULL; -#else - if (((PyCFunctionObject*)op)->m_ml->ml_doc) { -#if PY_MAJOR_VERSION >= 3 - op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); -#else - op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); -#endif - if (unlikely(op->func_doc == NULL)) - return NULL; - } else { - Py_INCREF(Py_None); - return Py_None; - } -#endif - } - Py_INCREF(op->func_doc); - return op->func_doc; -} -static int -__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (value == NULL) { - value = Py_None; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_doc, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(op->func_name == NULL)) { -#if CYTHON_COMPILING_IN_LIMITED_API - op->func_name = PyObject_GetAttrString(op->func, "__name__"); -#elif PY_MAJOR_VERSION >= 3 - op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); -#else - op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); -#endif - if (unlikely(op->func_name == NULL)) - return NULL; - } - Py_INCREF(op->func_name); - return op->func_name; -} -static int -__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__name__ must be set to a string object"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_name, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - Py_INCREF(op->func_qualname); - return op->func_qualname; -} -static int -__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__qualname__ must be set to a string object"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_qualname, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(op->func_dict == NULL)) { - op->func_dict = PyDict_New(); - if (unlikely(op->func_dict == NULL)) - return NULL; - } - Py_INCREF(op->func_dict); - return op->func_dict; -} -static int -__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, void *context) -{ - CYTHON_UNUSED_VAR(context); - if (unlikely(value == NULL)) { - PyErr_SetString(PyExc_TypeError, - "function's dictionary may not be deleted"); - return -1; - } - if (unlikely(!PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "setting function's dictionary to a non-dict"); - return -1; - } - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->func_dict, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(context); - Py_INCREF(op->func_globals); - return op->func_globals; -} -static PyObject * -__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) -{ - CYTHON_UNUSED_VAR(op); - CYTHON_UNUSED_VAR(context); - Py_INCREF(Py_None); - return Py_None; -} -static PyObject * -__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) -{ - PyObject* result = (op->func_code) ? op->func_code : Py_None; - CYTHON_UNUSED_VAR(context); - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { - int result = 0; - PyObject *res = op->defaults_getter((PyObject *) op); - if (unlikely(!res)) - return -1; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - op->defaults_tuple = PyTuple_GET_ITEM(res, 0); - Py_INCREF(op->defaults_tuple); - op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); - Py_INCREF(op->defaults_kwdict); - #else - op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); - if (unlikely(!op->defaults_tuple)) result = -1; - else { - op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); - if (unlikely(!op->defaults_kwdict)) result = -1; - } - #endif - Py_DECREF(res); - return result; -} -static int -__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value) { - value = Py_None; - } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__defaults__ must be set to a tuple object"); - return -1; - } - PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " - "currently affect the values used in function calls", 1); - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->defaults_tuple; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - if (op->defaults_getter) { - if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; - result = op->defaults_tuple; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value) { - value = Py_None; - } else if (unlikely(value != Py_None && !PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__kwdefaults__ must be set to a dict object"); - return -1; - } - PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " - "currently affect the values used in function calls", 1); - Py_INCREF(value); - __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->defaults_kwdict; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - if (op->defaults_getter) { - if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; - result = op->defaults_kwdict; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - if (!value || value == Py_None) { - value = NULL; - } else if (unlikely(!PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "__annotations__ must be set to a dict object"); - return -1; - } - Py_XINCREF(value); - __Pyx_Py_XDECREF_SET(op->func_annotations, value); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { - PyObject* result = op->func_annotations; - CYTHON_UNUSED_VAR(context); - if (unlikely(!result)) { - result = PyDict_New(); - if (unlikely(!result)) return NULL; - op->func_annotations = result; - } - Py_INCREF(result); - return result; -} -static PyObject * -__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { - int is_coroutine; - CYTHON_UNUSED_VAR(context); - if (op->func_is_coroutine) { - return __Pyx_NewRef(op->func_is_coroutine); - } - is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; -#if PY_VERSION_HEX >= 0x03050000 - if (is_coroutine) { - PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine; - fromlist = PyList_New(1); - if (unlikely(!fromlist)) return NULL; - Py_INCREF(marker); -#if CYTHON_ASSUME_SAFE_MACROS - PyList_SET_ITEM(fromlist, 0, marker); -#else - if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { - Py_DECREF(marker); - Py_DECREF(fromlist); - return NULL; - } -#endif - module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0); - Py_DECREF(fromlist); - if (unlikely(!module)) goto ignore; - op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker); - Py_DECREF(module); - if (likely(op->func_is_coroutine)) { - return __Pyx_NewRef(op->func_is_coroutine); - } -ignore: - PyErr_Clear(); - } -#endif - op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine); - return __Pyx_NewRef(op->func_is_coroutine); -} -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject * -__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { - CYTHON_UNUSED_VAR(context); - return PyObject_GetAttrString(op->func, "__module__"); -} -static int -__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { - CYTHON_UNUSED_VAR(context); - return PyObject_SetAttrString(op->func, "__module__", value); -} -#endif -static PyGetSetDef __pyx_CyFunction_getsets[] = { - {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, - {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, - {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, - {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, -#if CYTHON_COMPILING_IN_LIMITED_API - {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, -#endif - {0, 0, 0, 0, 0} -}; -static PyMemberDef __pyx_CyFunction_members[] = { -#if !CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, -#endif -#if CYTHON_USE_TYPE_SPECS - {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, -#if CYTHON_METH_FASTCALL -#if CYTHON_BACKPORT_VECTORCALL - {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, -#else -#if !CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, -#endif -#endif -#endif -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API - {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, -#else - {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, -#endif -#endif - {0, 0, 0, 0, 0} -}; -static PyObject * -__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) -{ - CYTHON_UNUSED_VAR(args); -#if PY_MAJOR_VERSION >= 3 - Py_INCREF(m->func_qualname); - return m->func_qualname; -#else - return PyString_FromString(((PyCFunctionObject*)m)->m_ml->ml_name); -#endif -} -static PyMethodDef __pyx_CyFunction_methods[] = { - {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, - {0, 0, 0, 0} -}; -#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API -#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) -#else -#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) -#endif -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { -#if !CYTHON_COMPILING_IN_LIMITED_API - PyCFunctionObject *cf = (PyCFunctionObject*) op; -#endif - if (unlikely(op == NULL)) - return NULL; -#if CYTHON_COMPILING_IN_LIMITED_API - op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); - if (unlikely(!op->func)) return NULL; -#endif - op->flags = flags; - __Pyx_CyFunction_weakreflist(op) = NULL; -#if !CYTHON_COMPILING_IN_LIMITED_API - cf->m_ml = ml; - cf->m_self = (PyObject *) op; -#endif - Py_XINCREF(closure); - op->func_closure = closure; -#if !CYTHON_COMPILING_IN_LIMITED_API - Py_XINCREF(module); - cf->m_module = module; -#endif - op->func_dict = NULL; - op->func_name = NULL; - Py_INCREF(qualname); - op->func_qualname = qualname; - op->func_doc = NULL; -#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API - op->func_classobj = NULL; -#else - ((PyCMethodObject*)op)->mm_class = NULL; -#endif - op->func_globals = globals; - Py_INCREF(op->func_globals); - Py_XINCREF(code); - op->func_code = code; - op->defaults_pyobjects = 0; - op->defaults_size = 0; - op->defaults = NULL; - op->defaults_tuple = NULL; - op->defaults_kwdict = NULL; - op->defaults_getter = NULL; - op->func_annotations = NULL; - op->func_is_coroutine = NULL; -#if CYTHON_METH_FASTCALL - switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { - case METH_NOARGS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; - break; - case METH_O: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; - break; - case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; - break; - case METH_FASTCALL | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; - break; - case METH_VARARGS | METH_KEYWORDS: - __Pyx_CyFunction_func_vectorcall(op) = NULL; - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); - Py_DECREF(op); - return NULL; - } -#endif - return (PyObject *) op; -} -static int -__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) -{ - Py_CLEAR(m->func_closure); -#if CYTHON_COMPILING_IN_LIMITED_API - Py_CLEAR(m->func); -#else - Py_CLEAR(((PyCFunctionObject*)m)->m_module); -#endif - Py_CLEAR(m->func_dict); - Py_CLEAR(m->func_name); - Py_CLEAR(m->func_qualname); - Py_CLEAR(m->func_doc); - Py_CLEAR(m->func_globals); - Py_CLEAR(m->func_code); -#if !CYTHON_COMPILING_IN_LIMITED_API -#if PY_VERSION_HEX < 0x030900B1 - Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); -#else - { - PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; - ((PyCMethodObject *) (m))->mm_class = NULL; - Py_XDECREF(cls); - } -#endif -#endif - Py_CLEAR(m->defaults_tuple); - Py_CLEAR(m->defaults_kwdict); - Py_CLEAR(m->func_annotations); - Py_CLEAR(m->func_is_coroutine); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_XDECREF(pydefaults[i]); - PyObject_Free(m->defaults); - m->defaults = NULL; - } - return 0; -} -static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - if (__Pyx_CyFunction_weakreflist(m) != NULL) - PyObject_ClearWeakRefs((PyObject *) m); - __Pyx_CyFunction_clear(m); - __Pyx_PyHeapTypeObject_GC_Del(m); -} -static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - PyObject_GC_UnTrack(m); - __Pyx__CyFunction_dealloc(m); -} -static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) -{ - Py_VISIT(m->func_closure); -#if CYTHON_COMPILING_IN_LIMITED_API - Py_VISIT(m->func); -#else - Py_VISIT(((PyCFunctionObject*)m)->m_module); -#endif - Py_VISIT(m->func_dict); - Py_VISIT(m->func_name); - Py_VISIT(m->func_qualname); - Py_VISIT(m->func_doc); - Py_VISIT(m->func_globals); - Py_VISIT(m->func_code); -#if !CYTHON_COMPILING_IN_LIMITED_API - Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); -#endif - Py_VISIT(m->defaults_tuple); - Py_VISIT(m->defaults_kwdict); - Py_VISIT(m->func_is_coroutine); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_VISIT(pydefaults[i]); - } - return 0; -} -static PyObject* -__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) -{ -#if PY_MAJOR_VERSION >= 3 - return PyUnicode_FromFormat("", - op->func_qualname, (void *)op); -#else - return PyString_FromFormat("", - PyString_AsString(op->func_qualname), (void *)op); -#endif -} -static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { -#if CYTHON_COMPILING_IN_LIMITED_API - PyObject *f = ((__pyx_CyFunctionObject*)func)->func; - PyObject *py_name = NULL; - PyCFunction meth; - int flags; - meth = PyCFunction_GetFunction(f); - if (unlikely(!meth)) return NULL; - flags = PyCFunction_GetFlags(f); - if (unlikely(flags < 0)) return NULL; -#else - PyCFunctionObject* f = (PyCFunctionObject*)func; - PyCFunction meth = f->m_ml->ml_meth; - int flags = f->m_ml->ml_flags; -#endif - Py_ssize_t size; - switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { - case METH_VARARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) - return (*meth)(self, arg); - break; - case METH_VARARGS | METH_KEYWORDS: - return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); - case METH_NOARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(arg); -#else - size = PyTuple_Size(arg); - if (unlikely(size < 0)) return NULL; -#endif - if (likely(size == 0)) - return (*meth)(self, NULL); -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, - "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - py_name, size); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); -#endif - return NULL; - } - break; - case METH_O: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { -#if CYTHON_ASSUME_SAFE_MACROS - size = PyTuple_GET_SIZE(arg); -#else - size = PyTuple_Size(arg); - if (unlikely(size < 0)) return NULL; -#endif - if (likely(size == 1)) { - PyObject *result, *arg0; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - arg0 = PyTuple_GET_ITEM(arg, 0); - #else - arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; - #endif - result = (*meth)(self, arg0); - #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF(arg0); - #endif - return result; - } -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, - "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - py_name, size); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); -#endif - return NULL; - } - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); - return NULL; - } -#if CYTHON_COMPILING_IN_LIMITED_API - py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL); - if (!py_name) return NULL; - PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments", - py_name); - Py_DECREF(py_name); -#else - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - f->m_ml->ml_name); -#endif - return NULL; -} -static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *self, *result; -#if CYTHON_COMPILING_IN_LIMITED_API - self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); - if (unlikely(!self) && PyErr_Occurred()) return NULL; -#else - self = ((PyCFunctionObject*)func)->m_self; -#endif - result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); - return result; -} -static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { - PyObject *result; - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; -#if CYTHON_METH_FASTCALL - __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); - if (vc) { -#if CYTHON_ASSUME_SAFE_MACROS - return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); -#else - (void) &__Pyx_PyVectorcall_FastCallDict; - return PyVectorcall_Call(func, args, kw); -#endif - } -#endif - if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { - Py_ssize_t argc; - PyObject *new_args; - PyObject *self; -#if CYTHON_ASSUME_SAFE_MACROS - argc = PyTuple_GET_SIZE(args); -#else - argc = PyTuple_Size(args); - if (unlikely(!argc) < 0) return NULL; -#endif - new_args = PyTuple_GetSlice(args, 1, argc); - if (unlikely(!new_args)) - return NULL; - self = PyTuple_GetItem(args, 0); - if (unlikely(!self)) { - Py_DECREF(new_args); -#if PY_MAJOR_VERSION > 2 - PyErr_Format(PyExc_TypeError, - "unbound method %.200S() needs an argument", - cyfunc->func_qualname); -#else - PyErr_SetString(PyExc_TypeError, - "unbound method needs an argument"); -#endif - return NULL; - } - result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); - Py_DECREF(new_args); - } else { - result = __Pyx_CyFunction_Call(func, args, kw); - } - return result; -} -#if CYTHON_METH_FASTCALL -static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) -{ - int ret = 0; - if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { - if (unlikely(nargs < 1)) { - PyErr_Format(PyExc_TypeError, "%.200s() needs an argument", - ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); - return -1; - } - ret = 1; - } - if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name); - return -1; - } - return ret; -} -static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - if (unlikely(nargs != 0)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - def->ml_name, nargs); - return NULL; - } - return def->ml_meth(self, NULL); -} -static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - if (unlikely(nargs != 1)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - def->ml_name, nargs); - return NULL; - } - return def->ml_meth(self, args[0]); -} -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames); -} -static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) -{ - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; - PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml; - PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); -#if CYTHON_BACKPORT_VECTORCALL - Py_ssize_t nargs = (Py_ssize_t)nargsf; -#else - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); -#endif - PyObject *self; - switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { - case 1: - self = args[0]; - args += 1; - nargs -= 1; - break; - case 0: - self = ((PyCFunctionObject*)cyfunc)->m_self; - break; - default: - return NULL; - } - return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames); -} -#endif -#if CYTHON_USE_TYPE_SPECS -static PyType_Slot __pyx_CyFunctionType_slots[] = { - {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, - {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, - {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, - {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, - {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, - {Py_tp_methods, (void *)__pyx_CyFunction_methods}, - {Py_tp_members, (void *)__pyx_CyFunction_members}, - {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, - {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, - {0, 0}, -}; -static PyType_Spec __pyx_CyFunctionType_spec = { - __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", - sizeof(__pyx_CyFunctionObject), - 0, -#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR - Py_TPFLAGS_METHOD_DESCRIPTOR | -#endif -#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL) - _Py_TPFLAGS_HAVE_VECTORCALL | -#endif - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - __pyx_CyFunctionType_slots -}; -#else -static PyTypeObject __pyx_CyFunctionType_type = { - PyVarObject_HEAD_INIT(0, 0) - __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", - sizeof(__pyx_CyFunctionObject), - 0, - (destructor) __Pyx_CyFunction_dealloc, -#if !CYTHON_METH_FASTCALL - 0, -#elif CYTHON_BACKPORT_VECTORCALL - (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall), -#else - offsetof(PyCFunctionObject, vectorcall), -#endif - 0, - 0, -#if PY_MAJOR_VERSION < 3 - 0, -#else - 0, -#endif - (reprfunc) __Pyx_CyFunction_repr, - 0, - 0, - 0, - 0, - __Pyx_CyFunction_CallAsMethod, - 0, - 0, - 0, - 0, -#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR - Py_TPFLAGS_METHOD_DESCRIPTOR | -#endif -#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL - _Py_TPFLAGS_HAVE_VECTORCALL | -#endif - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - 0, - (traverseproc) __Pyx_CyFunction_traverse, - (inquiry) __Pyx_CyFunction_clear, - 0, -#if PY_VERSION_HEX < 0x030500A0 - offsetof(__pyx_CyFunctionObject, func_weakreflist), -#else - offsetof(PyCFunctionObject, m_weakreflist), -#endif - 0, - 0, - __pyx_CyFunction_methods, - __pyx_CyFunction_members, - __pyx_CyFunction_getsets, - 0, - 0, - __Pyx_PyMethod_New, - 0, - offsetof(__pyx_CyFunctionObject, func_dict), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -#if PY_VERSION_HEX >= 0x030400a1 - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, -#endif -#if __PYX_NEED_TP_PRINT_SLOT - 0, -#endif -#if PY_VERSION_HEX >= 0x030C0000 - 0, -#endif -#if PY_VERSION_HEX >= 0x030d00A4 - 0, -#endif -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000 - 0, -#endif -}; -#endif -static int __pyx_CyFunction_init(PyObject *module) { -#if CYTHON_USE_TYPE_SPECS - __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL); -#else - CYTHON_UNUSED_VAR(module); - __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); -#endif - if (unlikely(__pyx_CyFunctionType == NULL)) { - return -1; - } - return 0; -} -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults = PyObject_Malloc(size); - if (unlikely(!m->defaults)) - return PyErr_NoMemory(); - memset(m->defaults, 0, size); - m->defaults_pyobjects = pyobjects; - m->defaults_size = size; - return m->defaults; -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_tuple = tuple; - Py_INCREF(tuple); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_kwdict = dict; - Py_INCREF(dict); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->func_annotations = dict; - Py_INCREF(dict); -} - -/* CythonFunction */ -static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { - PyObject *op = __Pyx_CyFunction_Init( - PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), - ml, flags, qualname, closure, module, globals, code - ); - if (likely(op)) { - PyObject_GC_Track(op); - } - return op; -} - -/* PyDictVersioning */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - CYTHON_MAYBE_UNUSED_VAR(tstate); - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -#if !CYTHON_COMPILING_IN_LIMITED_API -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} -#endif - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif -#if CYTHON_COMPILING_IN_LIMITED_API -static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, - PyObject *firstlineno, PyObject *name) { - PyObject *replace = NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; - replace = PyObject_GetAttrString(code, "replace"); - if (likely(replace)) { - PyObject *result; - result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict); - Py_DECREF(replace); - return result; - } - PyErr_Clear(); - #if __PYX_LIMITED_VERSION_HEX < 0x030780000 - { - PyObject *compiled = NULL, *result = NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL; - if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL; - compiled = Py_CompileString( - "out = type(code)(\n" - " code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n" - " code.co_flags, code.co_code, code.co_consts, code.co_names,\n" - " code.co_varnames, code.co_filename, co_name, co_firstlineno,\n" - " code.co_lnotab)\n", "", Py_file_input); - if (!compiled) return NULL; - result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict); - Py_DECREF(compiled); - if (!result) PyErr_Print(); - Py_DECREF(result); - result = PyDict_GetItemString(scratch_dict, "out"); - if (result) Py_INCREF(result); - return result; - } - #else - return NULL; - #endif -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; - PyObject *replace = NULL, *getframe = NULL, *frame = NULL; - PyObject *exc_type, *exc_value, *exc_traceback; - int success = 0; - if (c_line) { - (void) __pyx_cfilenm; - (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); - } - PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); - code_object = Py_CompileString("_getframe()", filename, Py_eval_input); - if (unlikely(!code_object)) goto bad; - py_py_line = PyLong_FromLong(py_line); - if (unlikely(!py_py_line)) goto bad; - py_funcname = PyUnicode_FromString(funcname); - if (unlikely(!py_funcname)) goto bad; - dict = PyDict_New(); - if (unlikely(!dict)) goto bad; - { - PyObject *old_code_object = code_object; - code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); - Py_DECREF(old_code_object); - } - if (unlikely(!code_object)) goto bad; - getframe = PySys_GetObject("_getframe"); - if (unlikely(!getframe)) goto bad; - if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; - frame = PyEval_EvalCode(code_object, dict, dict); - if (unlikely(!frame) || frame == Py_None) goto bad; - success = 1; - bad: - PyErr_Restore(exc_type, exc_value, exc_traceback); - Py_XDECREF(code_object); - Py_XDECREF(py_py_line); - Py_XDECREF(py_funcname); - Py_XDECREF(dict); - Py_XDECREF(replace); - if (success) { - PyTraceBack_Here( - (struct _frame*)frame); - } - Py_XDECREF(frame); -} -#else -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = NULL; - PyObject *py_funcname = NULL; - #if PY_MAJOR_VERSION < 3 - PyObject *py_srcfile = NULL; - py_srcfile = PyString_FromString(filename); - if (!py_srcfile) goto bad; - #endif - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - funcname = PyUnicode_AsUTF8(py_funcname); - if (!funcname) goto bad; - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - if (!py_funcname) goto bad; - #endif - } - #if PY_MAJOR_VERSION < 3 - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - #else - py_code = PyCode_NewEmpty(filename, funcname, py_line); - #endif - Py_XDECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_funcname); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_srcfile); - #endif - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject *ptype, *pvalue, *ptraceback; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) { - /* If the code object creation fails, then we should clear the - fetched exception references and propagate the new exception */ - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - goto bad; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} -#endif - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -static PyObject* __pyx_convert__to_py_struct__Date(struct Date s) { - PyObject* res; - PyObject* member; - res = __Pyx_PyDict_NewPresized(4); if (unlikely(!res)) return NULL; - member = __Pyx_PyInt_From_int(s.year); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_year, member) < 0)) goto bad; - Py_DECREF(member); - member = __Pyx_PyInt_From_int(s.month); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_month, member) < 0)) goto bad; - Py_DECREF(member); - member = __Pyx_PyInt_From_int(s.day); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_day, member) < 0)) goto bad; - Py_DECREF(member); - member = __Pyx_PyInt_From_int(s.weekday); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_weekday, member) < 0)) goto bad; - Py_DECREF(member); - return res; - bad: - Py_XDECREF(member); - Py_DECREF(res); - return NULL; -} -static PyObject* __pyx_convert__to_py_struct__Time(struct Time s) { - PyObject* res; - PyObject* member; - res = __Pyx_PyDict_NewPresized(3); if (unlikely(!res)) return NULL; - member = __Pyx_PyInt_From_int(s.hours); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_hours, member) < 0)) goto bad; - Py_DECREF(member); - member = __Pyx_PyInt_From_int(s.minutes); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_minutes, member) < 0)) goto bad; - Py_DECREF(member); - member = __Pyx_PyInt_From_int(s.seconds); if (unlikely(!member)) goto bad; - if (unlikely(PyDict_SetItem(res, __pyx_n_s_seconds, member) < 0)) goto bad; - Py_DECREF(member); - return res; - bad: - Py_XDECREF(member); - Py_DECREF(res); - return NULL; -} -/* RaiseUnexpectedTypeError */ -static int -__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) -{ - __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj)); - PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, - expected, obj_type_name); - __Pyx_DECREF_TypeName(obj_type_name); - return 0; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(int) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } -#endif - if (unlikely(!PyLong_Check(x))) { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(int) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(int) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - int val; - int ret = -1; -#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API - Py_ssize_t bytes_copied = PyLong_AsNativeBytes( - x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); - if (unlikely(bytes_copied == -1)) { - } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { - goto raise_overflow; - } else { - ret = 0; - } -#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)x, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *v; - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (likely(PyLong_CheckExact(x))) { - v = __Pyx_NewRef(x); - } else { - v = PyNumber_Long(x); - if (unlikely(!v)) return (int) -1; - assert(PyLong_CheckExact(v)); - } - { - int result = PyObject_RichCompareBool(v, Py_False, Py_LT); - if (unlikely(result < 0)) { - Py_DECREF(v); - return (int) -1; - } - is_negative = result == 1; - } - if (is_unsigned && unlikely(is_negative)) { - Py_DECREF(v); - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - Py_DECREF(v); - if (unlikely(!stepval)) - return (int) -1; - } else { - stepval = v; - } - v = NULL; - val = (int) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - long idigit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - val |= ((int) idigit) << bits; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - } - Py_DECREF(shift); shift = NULL; - Py_DECREF(mask); mask = NULL; - { - long idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((int) idigit) << bits; - } - if (!is_unsigned) { - if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - if (unlikely(ret)) - return (int) -1; - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - unsigned char *bytes = (unsigned char *)&value; -#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 - if (is_unsigned) { - return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); - } else { - return PyLong_FromNativeBytes(bytes, sizeof(value), -1); - } -#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 - int one = 1; int little = (int)*(unsigned char *)&one; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); -#else - int one = 1; int little = (int)*(unsigned char *)&one; - PyObject *from_bytes, *result = NULL; - PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; - from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); - if (!from_bytes) return NULL; - py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(int)); - if (!py_bytes) goto limited_bad; - order_str = PyUnicode_FromString(little ? "little" : "big"); - if (!order_str) goto limited_bad; - arg_tuple = PyTuple_Pack(2, py_bytes, order_str); - if (!arg_tuple) goto limited_bad; - if (!is_unsigned) { - kwds = PyDict_New(); - if (!kwds) goto limited_bad; - if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; - } - result = PyObject_Call(from_bytes, arg_tuple, kwds); - limited_bad: - Py_XDECREF(kwds); - Py_XDECREF(arg_tuple); - Py_XDECREF(order_str); - Py_XDECREF(py_bytes); - Py_XDECREF(from_bytes); - return result; -#endif - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - unsigned char *bytes = (unsigned char *)&value; -#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 - if (is_unsigned) { - return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); - } else { - return PyLong_FromNativeBytes(bytes, sizeof(value), -1); - } -#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 - int one = 1; int little = (int)*(unsigned char *)&one; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); -#else - int one = 1; int little = (int)*(unsigned char *)&one; - PyObject *from_bytes, *result = NULL; - PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL; - from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); - if (!from_bytes) return NULL; - py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); - if (!py_bytes) goto limited_bad; - order_str = PyUnicode_FromString(little ? "little" : "big"); - if (!order_str) goto limited_bad; - arg_tuple = PyTuple_Pack(2, py_bytes, order_str); - if (!arg_tuple) goto limited_bad; - if (!is_unsigned) { - kwds = PyDict_New(); - if (!kwds) goto limited_bad; - if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad; - } - result = PyObject_Call(from_bytes, arg_tuple, kwds); - limited_bad: - Py_XDECREF(kwds); - Py_XDECREF(arg_tuple); - Py_XDECREF(order_str); - Py_XDECREF(py_bytes); - Py_XDECREF(from_bytes); - return result; -#endif - } -} - -/* CIntFromPy */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(size_t) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (size_t) val; - } - } -#endif - if (unlikely(!PyLong_Check(x))) { - size_t val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (size_t) -1; - val = __Pyx_PyInt_As_size_t(tmp); - Py_DECREF(tmp); - return val; - } - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(size_t, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(size_t) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) >= 2 * PyLong_SHIFT)) { - return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(size_t) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) >= 3 * PyLong_SHIFT)) { - return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(size_t) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) >= 4 * PyLong_SHIFT)) { - return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (size_t) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(size_t) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(size_t, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { - return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(size_t) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { - return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { - return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(size_t) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { - return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT)) { - return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(size_t) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT)) { - return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(size_t) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(size_t) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - size_t val; - int ret = -1; -#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API - Py_ssize_t bytes_copied = PyLong_AsNativeBytes( - x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); - if (unlikely(bytes_copied == -1)) { - } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { - goto raise_overflow; - } else { - ret = 0; - } -#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)x, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *v; - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (likely(PyLong_CheckExact(x))) { - v = __Pyx_NewRef(x); - } else { - v = PyNumber_Long(x); - if (unlikely(!v)) return (size_t) -1; - assert(PyLong_CheckExact(v)); - } - { - int result = PyObject_RichCompareBool(v, Py_False, Py_LT); - if (unlikely(result < 0)) { - Py_DECREF(v); - return (size_t) -1; - } - is_negative = result == 1; - } - if (is_unsigned && unlikely(is_negative)) { - Py_DECREF(v); - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - Py_DECREF(v); - if (unlikely(!stepval)) - return (size_t) -1; - } else { - stepval = v; - } - v = NULL; - val = (size_t) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(size_t) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - long idigit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - val |= ((size_t) idigit) << bits; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - } - Py_DECREF(shift); shift = NULL; - Py_DECREF(mask); mask = NULL; - { - long idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(size_t) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((size_t) idigit) << bits; - } - if (!is_unsigned) { - if (unlikely(val & (((size_t) 1) << (sizeof(size_t) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - if (unlikely(ret)) - return (size_t) -1; - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to size_t"); - return (size_t) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to size_t"); - return (size_t) -1; -} - -/* FormatTypeName */ -#if CYTHON_COMPILING_IN_LIMITED_API -static __Pyx_TypeName -__Pyx_PyType_GetName(PyTypeObject* tp) -{ - PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, - __pyx_n_s_name); - if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) { - PyErr_Clear(); - Py_XDECREF(name); - name = __Pyx_NewRef(__pyx_n_s__28); - } - return name; -} -#endif - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if ((sizeof(long) < sizeof(long))) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } -#endif - if (unlikely(!PyLong_Check(x))) { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - if (unlikely(__Pyx_PyLong_IsNeg(x))) { - goto raise_neg_overflow; - } else if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_DigitCount(x)) { - case 2: - if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if ((sizeof(long) <= sizeof(unsigned long))) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - if (__Pyx_PyLong_IsCompact(x)) { - __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) - } else { - const digit* digits = __Pyx_PyLong_Digits(x); - assert(__Pyx_PyLong_DigitCount(x) > 1); - switch (__Pyx_PyLong_SignedDigitCount(x)) { - case -2: - if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { - if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } - } -#endif - if ((sizeof(long) <= sizeof(long))) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { - long val; - int ret = -1; -#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API - Py_ssize_t bytes_copied = PyLong_AsNativeBytes( - x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); - if (unlikely(bytes_copied == -1)) { - } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { - goto raise_overflow; - } else { - ret = 0; - } -#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - ret = _PyLong_AsByteArray((PyLongObject *)x, - bytes, sizeof(val), - is_little, !is_unsigned); -#else - PyObject *v; - PyObject *stepval = NULL, *mask = NULL, *shift = NULL; - int bits, remaining_bits, is_negative = 0; - int chunk_size = (sizeof(long) < 8) ? 30 : 62; - if (likely(PyLong_CheckExact(x))) { - v = __Pyx_NewRef(x); - } else { - v = PyNumber_Long(x); - if (unlikely(!v)) return (long) -1; - assert(PyLong_CheckExact(v)); - } - { - int result = PyObject_RichCompareBool(v, Py_False, Py_LT); - if (unlikely(result < 0)) { - Py_DECREF(v); - return (long) -1; - } - is_negative = result == 1; - } - if (is_unsigned && unlikely(is_negative)) { - Py_DECREF(v); - goto raise_neg_overflow; - } else if (is_negative) { - stepval = PyNumber_Invert(v); - Py_DECREF(v); - if (unlikely(!stepval)) - return (long) -1; - } else { - stepval = v; - } - v = NULL; - val = (long) 0; - mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; - shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; - for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { - PyObject *tmp, *digit; - long idigit; - digit = PyNumber_And(stepval, mask); - if (unlikely(!digit)) goto done; - idigit = PyLong_AsLong(digit); - Py_DECREF(digit); - if (unlikely(idigit < 0)) goto done; - val |= ((long) idigit) << bits; - tmp = PyNumber_Rshift(stepval, shift); - if (unlikely(!tmp)) goto done; - Py_DECREF(stepval); stepval = tmp; - } - Py_DECREF(shift); shift = NULL; - Py_DECREF(mask); mask = NULL; - { - long idigit = PyLong_AsLong(stepval); - if (unlikely(idigit < 0)) goto done; - remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); - if (unlikely(idigit >= (1L << remaining_bits))) - goto raise_overflow; - val |= ((long) idigit) << bits; - } - if (!is_unsigned) { - if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) - goto raise_overflow; - if (is_negative) - val = ~val; - } - ret = 0; - done: - Py_XDECREF(shift); - Py_XDECREF(mask); - Py_XDECREF(stepval); -#endif - if (unlikely(ret)) - return (long) -1; - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (cls == a || cls == b) return 1; - mro = cls->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(mro, i); - if (base == (PyObject *)a || base == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - if (exc_type1) { - return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); - } else { - return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; i= 0x030B00A4 - return Py_Version & ~0xFFUL; -#else - const char* rt_version = Py_GetVersion(); - unsigned long version = 0; - unsigned long factor = 0x01000000UL; - unsigned int digit = 0; - int i = 0; - while (factor) { - while ('0' <= rt_version[i] && rt_version[i] <= '9') { - digit = digit * 10 + (unsigned int) (rt_version[i] - '0'); - ++i; - } - version += factor * digit; - if (rt_version[i] != '.') - break; - digit = 0; - factor >>= 8; - ++i; - } - return version; -#endif -} -static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { - const unsigned long MAJOR_MINOR = 0xFFFF0000UL; - if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) - return 0; - if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) - return 1; - { - char message[200]; - PyOS_snprintf(message, sizeof(message), - "compile time Python version %d.%d " - "of module '%.100s' " - "%s " - "runtime version %d.%d", - (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), - __Pyx_MODULE_NAME, - (allow_newer) ? "was newer than" : "does not match", - (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) - ); - return PyErr_WarnEx(NULL, message, 1); - } -} - -/* InitStrings */ -#if PY_MAJOR_VERSION >= 3 -static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) { - if (t.is_unicode | t.is_str) { - if (t.intern) { - *str = PyUnicode_InternFromString(t.s); - } else if (t.encoding) { - *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL); - } else { - *str = PyUnicode_FromStringAndSize(t.s, t.n - 1); - } - } else { - *str = PyBytes_FromStringAndSize(t.s, t.n - 1); - } - if (!*str) - return -1; - if (PyObject_Hash(*str) == -1) - return -1; - return 0; -} -#endif -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION >= 3 - __Pyx_InitString(*t, t->p); - #else - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - #endif - ++t; - } - return 0; -} - -#include -static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { - size_t len = strlen(s); - if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { - PyErr_SetString(PyExc_OverflowError, "byte string is too long"); - return -1; - } - return (Py_ssize_t) len; -} -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - Py_ssize_t len = __Pyx_ssize_strlen(c_str); - if (unlikely(len < 0)) return NULL; - return __Pyx_PyUnicode_FromStringAndSize(c_str, len); -} -static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { - Py_ssize_t len = __Pyx_ssize_strlen(c_str); - if (unlikely(len < 0)) return NULL; - return PyByteArray_FromStringAndSize(c_str, len); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY && !CYTHON_COMPILING_IN_LIMITED_API) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { - __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result)); -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " - "The ability to return an instance of a strict subclass of int is deprecated, " - "and may be removed in a future version of Python.", - result_type_name)) { - __Pyx_DECREF_TypeName(result_type_name); - Py_DECREF(result); - return NULL; - } - __Pyx_DECREF_TypeName(result_type_name); - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")", - type_name, type_name, result_type_name); - __Pyx_DECREF_TypeName(result_type_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(__Pyx_PyLong_IsCompact(b))) { - return __Pyx_PyLong_CompactValue(b); - } else { - const digit* digits = __Pyx_PyLong_Digits(b); - const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { - if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { - return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); -#if PY_MAJOR_VERSION < 3 - } else if (likely(PyInt_CheckExact(o))) { - return PyInt_AS_LONG(o); -#endif - } else { - Py_ssize_t ival; - PyObject *x; - x = PyNumber_Index(o); - if (!x) return -1; - ival = PyInt_AsLong(x); - Py_DECREF(x); - return ival; - } -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -/* #### Code section: utility_code_pragmas_end ### */ -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - - - -/* #### Code section: end ### */ -#endif /* Py_PYTHON_H */ From 089116b910554365133545b5a7e579630d68e2d2 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 12 Dec 2025 10:31:55 +0100 Subject: [PATCH 06/31] Update gitignore file --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 46ec7886..8d4920b8 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,9 @@ src/routing/road/cpp_router/build/* src/routing/road/cpp_router/PyNetwork.cpp src/routing/road/extractors/cache/* +src/routing/pt/cpp_raptor_router/PyPTRouter.cpp +src/routing/pt/cpp_raptor_router/build/* + # IDE-related files *.idea .vscode/* From 8f5773255dd0676833820dabeb7de6e387c97415 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 12 Dec 2025 12:54:13 +0100 Subject: [PATCH 07/31] Add PT Offer class --- src/misc/globals.py | 9 +++++ src/routing/pt/RaptorRouterCpp.py | 4 +- src/simulation/Offers.py | 63 ++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/misc/globals.py b/src/misc/globals.py index 7217373d..57107345 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -553,6 +553,15 @@ G_OFFER_ZONAL_ORIGIN_ZONE = "origin_zone" G_OFFER_ZONAL_DESTINATION_ZONE = "destination_zone" +G_PT_OFFER_SOURCE_STATION = "source_station_id" +G_PT_OFFER_TARGET_STATION = "target_station_id" +G_PT_OFFER_SOURCE_WALKING_TIME = "source_walking_time" +G_PT_OFFER_SOURCE_TRANSFER_TIME = "source_transfer_time" +G_PT_OFFER_TRIP_TIME = "pt_trip_time" +G_PT_OFFER_TARGET_TRANSFER_TIME = "target_transfer_time" +G_PT_OFFER_TARGET_WALKING_TIME = "target_walking_time" +G_PT_OFFER_NUM_TRANSFERS = "num_transfers" + # additional parameters for intermodal solutions # ---------------------------------------------- G_IM_OFFER_PT_START = "im_pt_t_start" diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py index 1f0bf5fa..7365c3e5 100644 --- a/src/routing/pt/RaptorRouterCpp.py +++ b/src/routing/pt/RaptorRouterCpp.py @@ -163,9 +163,9 @@ def _get_included_stops_and_transfer_times(self, station_id: str) -> tp.Tuple[tp if __name__ == "__main__": - # Test the pt router class: python -m src.routing.pt.CppTester + # Test/run the pt router module: python -m src.routing.pt.RaptorRouterCpp - gtfs_dir = r"data\pubtrans\example_network\example_gtfs\matched" + gtfs_dir = "data/pubtrans/example_network/example_gtfs/matched" router = RaptorRouterCpp(gtfs_dir) source_station_departure_datetime = datetime(2024, 1, 1, 0, 4, 0) diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index 09ccba97..bb64581d 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -1,5 +1,6 @@ # src imports # ----------- +import typing as tp from src.routing.road.NetworkBase import return_position_str from src.misc.globals import * @@ -135,4 +136,64 @@ def __str__(self): class Rejection(TravellerOffer): """This class takes minimal input and creates an offer that represents a rejection.""" def __init__(self, traveler_id, operator_id): - super().__init__(traveler_id, operator_id, offered_waiting_time=None, offered_driving_time=None, fare=None) \ No newline at end of file + super().__init__(traveler_id, operator_id, offered_waiting_time=None, offered_driving_time=None, fare=None) + + +class PTOffer(TravellerOffer): + """This class represents a public transport offer. + + A PT offer contains the following information: + - traveler_id (str): sub-request id struct of the parent request + - operator_id (int): id of PT operator (-2) + - source_station_id (str): id of the source station + - target_station_id (str): id of the target station + - origin_node_arrival_time (int): absolute time [s] of the arrival at the origin street node + - source_walking_time (int): walking time [s] from origin street node to source station + - source_station_departure_time (int): absolute time [s] of the departure at the source station + - source_transfer_time (int): transfer time [s] from the source station to the source stop + - waiting_time (int): waiting time [s] from arrival at the source stop until departure; this value is used as the 'offered_waiting_time' in the TravellerOffer + - pt_trip_time (int): travel time [s] from departure at the source stop until arrival at the target stop + - fare (int): fare of the offer + - target_transfer_time (int): transfer time [s] from the target stop to the target station + - target_station_arrival_time (int): absolute time [s] of the arrival at the target station + - target_walking_time (int): walking time [s] from target station to destination street node + - destination_node_arrival_time (int): absolute time [s] of the arrival at the destination street node + - num_transfers (int): number of transfers in the PT journey + - pt_journey_duration (int): duration [s] from departure at the source station to arrival at the target station + - pt_segment_duration (int): duration [s] from arrival at the origin street node to arrival at the destination street node + - detailed_journey_plan (dict): detailed journey plan (only if requested) + """ + def __init__( + self, + traveler_id: str, operator_id: int, + source_station_id: str, target_station_id: str, + source_walking_time: int, source_station_departure_time: int, source_transfer_time: int, + waiting_time: int, pt_trip_time: int, fare: int, + target_transfer_time: int, target_station_arrival_time: int, target_walking_time: int, + num_transfers: int, pt_journey_duration: int, detailed_journey_plan: tp.List[tp.Dict[str, tp.Any]], + ): + self.origin_node_arrival_time = source_station_departure_time - source_walking_time + self.source_station_departure_time = source_station_departure_time + + self.target_station_arrival_time = target_station_arrival_time + self.destination_node_arrival_time = self.target_station_arrival_time + target_walking_time + + self.pt_journey_duration = pt_journey_duration + pt_segment_duration = self.destination_node_arrival_time - self.origin_node_arrival_time + + self.detailed_journey_plan = detailed_journey_plan + + offered_driving_time = pt_segment_duration - waiting_time + + additional_parameters = { + G_PT_OFFER_SOURCE_STATION: source_station_id, + G_PT_OFFER_TARGET_STATION: target_station_id, + G_PT_OFFER_SOURCE_WALKING_TIME: source_walking_time, + G_PT_OFFER_SOURCE_TRANSFER_TIME: source_transfer_time, + G_PT_OFFER_TRIP_TIME: pt_trip_time, + G_PT_OFFER_TARGET_TRANSFER_TIME: target_transfer_time, + G_PT_OFFER_TARGET_WALKING_TIME: target_walking_time, + G_PT_OFFER_NUM_TRANSFERS: num_transfers, + } + + super().__init__(traveler_id, operator_id, waiting_time, offered_driving_time, fare, additional_parameters=additional_parameters) \ No newline at end of file From e27f2a5986c69c8029b05e3ff781fc26da05342d Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 12 Dec 2025 16:08:59 +0100 Subject: [PATCH 08/31] Add Intermodal Offer class --- src/misc/globals.py | 74 ++++++++++++++++++++++++++---- src/simulation/Offers.py | 99 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 11 deletions(-) diff --git a/src/misc/globals.py b/src/misc/globals.py index 57107345..894f7eba 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -470,6 +470,44 @@ G_RQ_PA_EDT = "parcel_earliest_dropoff_time" G_RQ_PA_LDT = "parcel_latest_dropoff_time" +# intermodal specific +G_RQ_RID_STRUCT = "rid_struct" +G_RQ_IS_PARENT_REQUEST = "is_parent_request" +G_RQ_MODAL_STATE = "modal_state" +G_RQ_MODAL_STATE_VALUE = "modal_state_value" +G_RQ_TRANSFER_STATION_IDS = "transfer_station_ids" +G_RQ_MAX_TRANSFERS = "max_transfers" +G_RQ_SUB_TRIP_ID = "sub_trip_id" + +class RQ_MODAL_STATE(Enum): + """ This enum is used to identify different modal states of a traveler request. + MONOMODAL: only amod is used + FIRSTMILE: amod first mile and pt last mile + LASTMILE: amod last mile and pt first mile + FIRSTLASTMILE: amod first and last miles, pt in between + PT: only pt is used + ALL_OPTIONS: all options are used + """ + MONOMODAL: int = 0 + FIRSTMILE: int = 1 + LASTMILE: int = 2 + FIRSTLASTMILE: int = 3 + PT: int = 4 + ALL_OPTIONS: int = 5 + +class RQ_SUB_TRIP_ID(Enum): + """ This enum is used to identify different sub-trip ids of a traveler request. + """ + AMOD: int = 0 + FM_AMOD: int = 1 + FM_PT: int = 2 + LM_PT: int = 3 + LM_AMOD: int = 4 + FLM_AMOD_0: int = 5 + FLM_PT: int = 6 + FLM_AMOD_1: int = 7 + PT: int = 8 + # output general # -------------- G_RQ_TYPE = "rq_type" @@ -485,7 +523,6 @@ G_RQ_FARE = "fare" G_RQ_ACCESS = "access_time" G_RQ_EGRESS = "egress_time" -G_RQ_MODAL_STATE = "modal_state" # (see traveler modal state -> indicates monomodal/intermodal) # output environment specific # --------------------------- @@ -553,15 +590,6 @@ G_OFFER_ZONAL_ORIGIN_ZONE = "origin_zone" G_OFFER_ZONAL_DESTINATION_ZONE = "destination_zone" -G_PT_OFFER_SOURCE_STATION = "source_station_id" -G_PT_OFFER_TARGET_STATION = "target_station_id" -G_PT_OFFER_SOURCE_WALKING_TIME = "source_walking_time" -G_PT_OFFER_SOURCE_TRANSFER_TIME = "source_transfer_time" -G_PT_OFFER_TRIP_TIME = "pt_trip_time" -G_PT_OFFER_TARGET_TRANSFER_TIME = "target_transfer_time" -G_PT_OFFER_TARGET_WALKING_TIME = "target_walking_time" -G_PT_OFFER_NUM_TRANSFERS = "num_transfers" - # additional parameters for intermodal solutions # ---------------------------------------------- G_IM_OFFER_PT_START = "im_pt_t_start" @@ -571,6 +599,32 @@ G_IM_OFFER_MOD_COST = "im_mod_fare" G_IM_OFFER_MOD_SUB = "im_mod_subsidy" +G_IM_OFFER_OPERATOR_SUB_TRIP_TUPLE = "im_operator_sub_trip_tuple" # tuple of operator ids for each sub-trip: ((operator_id, sub_trip_id),) +G_IM_OFFER_TYPE = "im_offer_type" # type of multi offer: "default firstlastmile", "3phase firstlastmile" +G_IM_OFFER_FLM_WAIT_0 = "im_t_wait_flm_0" # Only used for FM AMoD segment in FLM +G_IM_OFFER_FLM_WAIT_1 = "im_t_wait_flm_1" # Only used for LM AMoD segment in FLM +G_IM_OFFER_FLM_DRIVE_0 = "im_t_drive_flm_0" # Only used for FM AMoD segment in FLM +G_IM_OFFER_FLM_DRIVE_1 = "im_t_drive_flm_1" # Only used for LM AMoD segment in FLM +G_IM_OFFER_FM_WAIT = "im_t_wait_fm" # Only used for AMoD segment in FM +G_IM_OFFER_LM_WAIT = "im_t_wait_lm" # Only used fot AMoD segment in LM +G_IM_OFFER_FM_DRIVE = "im_t_drive_fm" # Only used for AMoD segment in FM +G_IM_OFFER_LM_DRIVE = "im_t_drive_lm" # Only used fot AMoD segment in LM +G_IM_OFFER_DURATION = "im_t_duration" # total duration of intermodal offer + +# additional parameters for pt offers +# ------------------------------------------ +G_PT_OFFER_SOURCE_STATION = "source_station_id" +G_PT_OFFER_TARGET_STATION = "target_station_id" +G_PT_OFFER_SOURCE_WALKING_TIME = "source_walking_time" +G_PT_OFFER_SOURCE_TRANSFER_TIME = "source_transfer_time" +G_PT_OFFER_TRIP_TIME = "pt_trip_time" +G_PT_OFFER_TARGET_TRANSFER_TIME = "target_transfer_time" +G_PT_OFFER_TARGET_WALKING_TIME = "target_walking_time" +G_PT_OFFER_NUM_TRANSFERS = "num_transfers" +G_PT_OFFER_WAIT = "pt_t_wait" # PT segment waiting time +G_PT_OFFER_DURATION = "pt_duration" # PT segment total duration +G_PT_OFFER_DRIVE = "pt_t_drive" # PT segment driving time --> total pt segment duration - pt waiting time + # -------------------------------------------------------------------------------------------------------------------- # # Fleet Simulation Pattern # ######################## diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index bb64581d..fc4dc5cb 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -196,4 +196,101 @@ def __init__( G_PT_OFFER_NUM_TRANSFERS: num_transfers, } - super().__init__(traveler_id, operator_id, waiting_time, offered_driving_time, fare, additional_parameters=additional_parameters) \ No newline at end of file + super().__init__(traveler_id, operator_id, waiting_time, offered_driving_time, fare, additional_parameters=additional_parameters) + + +class IntermodalOffer(TravellerOffer): + """This class represents an intermodal offer that consists of multiple segments served by different operators.""" + def __init__( + self, + traveler_id: int, + sub_trip_offers: tp.Dict[int, TravellerOffer], + rq_modal_state: RQ_MODAL_STATE, + ): + """Initialize an intermodal offer that can include multiple sub-trips from different operators. + + :param traveler_id: traveler_id this offer is sent to + :type traveler_id: int + :param sub_trip_offers: dictionary of sub-trip offers {sub_trip_id: TravellerOffer} + :type sub_trip_offers: dict + :param rq_modal_state: modal state of the parent request + :type rq_modal_state: RQ_MODAL_STATE + :param additional_parameters: dictionary of other offer attributes + :type additional_parameters: dict or None + """ + self.rq_modal_state = rq_modal_state + self.sub_trip_offers: tp.Dict[int, TravellerOffer] = sub_trip_offers + + self.additional_offer_parameters: tp.Dict[str, tp.Any] = {} + + # merge sub-trip offers + aggregated_offer: tp.Dict[str, tp.Any] = self._merge_sub_trip_offers() + operator_sub_trip_tuple: tp.Tuple[tp.Tuple[int, int]] = aggregated_offer[G_IM_OFFER_OPERATOR_SUB_TRIP_TUPLE] # ((operator_id, sub_trip_id), ...) + self.operator_sub_trip_tuple_str = self.convert_operator_sub_trip_tuple_to_str(operator_sub_trip_tuple) + offered_waiting_time: int = aggregated_offer[G_OFFER_WAIT] + offered_driving_time: int = aggregated_offer[G_OFFER_DRIVE] + fare: int = aggregated_offer[G_OFFER_FARE] + + super().__init__(traveler_id, operator_sub_trip_tuple, offered_waiting_time, offered_driving_time, fare, self.additional_offer_parameters) + + def get_sub_trip_offers(self) -> tp.Dict[int, TravellerOffer]: + """Get the sub-trip offers for the multimodal offer.""" + return self.sub_trip_offers + + def convert_operator_sub_trip_tuple_to_str( + self, + operator_sub_trip: tp.Tuple[tp.Tuple[int, int]] + ) -> str: + """Convert the operator sub-trip tuple to a string representation.""" + return "#".join([f"{op_id}_{sub_trip_id}" for op_id, sub_trip_id in operator_sub_trip]) + + def _merge_sub_trip_offers(self) -> tp.Dict[str, tp.Any]: + """Merge sub-trip offers: calculate totals and map specific attributes.""" + # State -> [(SubTripID, WaitKey, DriveKey)] + amod_state_mapping = { + RQ_MODAL_STATE.FIRSTMILE: [ + (RQ_SUB_TRIP_ID.FM_AMOD.value, G_IM_OFFER_FM_WAIT, G_IM_OFFER_FM_DRIVE) + ], + RQ_MODAL_STATE.LASTMILE: [ + (RQ_SUB_TRIP_ID.LM_AMOD.value, G_IM_OFFER_LM_WAIT, G_IM_OFFER_LM_DRIVE) + ], + RQ_MODAL_STATE.FIRSTLASTMILE: [ + (RQ_SUB_TRIP_ID.FLM_AMOD_0.value, G_IM_OFFER_FLM_WAIT_0, G_IM_OFFER_FLM_DRIVE_0), + (RQ_SUB_TRIP_ID.FLM_AMOD_1.value, G_IM_OFFER_FLM_WAIT_1, G_IM_OFFER_FLM_DRIVE_1) + ] + } + + pt_attributes_to_extract = [G_PT_OFFER_WAIT, G_PT_OFFER_DRIVE, G_PT_OFFER_NUM_TRANSFERS] + + # calculate totals + operator_sub_trip_list = [] + total_fare = 0 + total_wait = 0 + total_drive = 0 + + for sub_trip_id, sub_trip_offer in self.sub_trip_offers.items(): + operator_sub_trip_list.append((sub_trip_offer.operator_id, sub_trip_id)) + total_fare += sub_trip_offer.get(G_OFFER_FARE, 0) + total_wait += sub_trip_offer.get(G_OFFER_WAIT, 0) + total_drive += sub_trip_offer.get(G_OFFER_DRIVE, 0) + + # add pt attributes into additional parameters + pt_offer = self.sub_trip_offers.get(RQ_SUB_TRIP_ID.FLM_PT.value, {}) + for key in pt_attributes_to_extract: + if key in pt_offer: + self.additional_offer_parameters[key] = pt_offer[key] + + # map amod attributes into additional parameters + mapping_configs = amod_state_mapping.get(self.rq_modal_state, []) + + for sub_trip_id, wait_key, drive_key in mapping_configs: + offer = self.sub_trip_offers.get(sub_trip_id, {}) + self.additional_offer_parameters[wait_key] = offer.get(G_OFFER_WAIT) + self.additional_offer_parameters[drive_key] = offer.get(G_OFFER_DRIVE) + + return { + G_IM_OFFER_OPERATOR_SUB_TRIP_TUPLE: tuple(operator_sub_trip_list), + G_OFFER_FARE: total_fare, + G_OFFER_WAIT: total_wait, + G_OFFER_DRIVE: total_drive + } \ No newline at end of file From 832529b867c69766a62e25e83da4048f818b0020 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 15 Dec 2025 10:59:28 +0100 Subject: [PATCH 09/31] Add BasicIntermodalRequest class --- src/demand/TravelerModels.py | 127 +++++++++++++++++++++++++++++++++++ src/misc/init_modules.py | 1 + 2 files changed, 128 insertions(+) diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index f0dc5dd6..6efd3b88 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -5,6 +5,7 @@ import os from copy import deepcopy from abc import abstractmethod, ABCMeta +import typing as tp # additional module imports (> requirements) # ------------------------------------------ @@ -722,6 +723,132 @@ def user_boards_vehicle(self, simulation_time, op_id, vid, pu_pos, t_access): #LOG.info(f"user boards vehicle: {self.rid} | {self.sub_rid_struct} | {self.offer}") self.fare = self.offer[op_id].get(G_OFFER_FARE, 0) return super().user_boards_vehicle(simulation_time, op_id, vid, pu_pos, t_access) + +# -------------------------------------------------------------------------------------------------------------------- # + +INPUT_PARAMETERS_BasicIntermodalRequest = { + "doc" : """This request class is used for intermodal requests. + It is used to model requests that can be served by multiple operators for different modes. + """, + "inherit" : "RequestBase", + "input_parameters_mandatory": [], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +class BasicIntermodalRequest(RequestBase): + """This request class is used for intermodal requests. + It is used to model requests that can be served by one amod operator and one pt operator.""" + type = "BasicIntermodalRequest" + def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parameters): + super().__init__(rq_row, routing_engine, simulation_time_step, scenario_parameters) + # intermodal attributes + modal_state_int: int = rq_row.get(G_RQ_MODAL_STATE, RQ_MODAL_STATE.MONOMODAL.value) # mono-modal trip by default + self.modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE(modal_state_int) + self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) + self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit + + def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: + raw_transfer_station_ids = rq_row.get(G_RQ_TRANSFER_STATION_IDS, None) + if raw_transfer_station_ids is None or pd.isnull(raw_transfer_station_ids) or raw_transfer_station_ids == "": + return None + else: + return raw_transfer_station_ids.split(";") # in FLM case, two transfer station ids are given + + def get_transfer_station_ids(self) -> tp.Optional[tp.List[str]]: + return self.transfer_station_ids + + def get_max_transfers(self) -> int: + return self.max_transfers + + def record_data(self): + record_dict = {} + # input + record_dict[G_RQ_ID] = f"{self.rid}" + record_dict[G_RQ_SUB_TRIP_ID] = self.subtrip_id + record_dict[G_RQ_IS_PARENT_REQUEST] = self.sub_rid_struct is None + record_dict[G_RQ_TYPE] = self.type + record_dict[G_RQ_PAX] = self.nr_pax + record_dict[G_RQ_TIME] = self.rq_time + record_dict[G_RQ_EPT] = self.earliest_start_time + # node output + record_dict[G_RQ_ORIGIN] = self.o_node + record_dict[G_RQ_DESTINATION] = self.d_node + # position output + if self.pu_pos is None or self.pu_pos == self.o_pos: + record_dict[G_RQ_PUL] = "" + else: + record_dict[G_RQ_PUL] = return_position_str(self.pu_pos) + if self.do_pos is None or self.do_pos == self.d_pos: + record_dict[G_RQ_DOL] = "" + else: + record_dict[G_RQ_DOL] = return_position_str(self.do_pos) + if self.t_access is None: + record_dict[G_RQ_ACCESS] = "" + else: + record_dict[G_RQ_ACCESS] = self.t_access + if self.t_egress is None: + record_dict[G_RQ_EGRESS] = "" + else: + record_dict[G_RQ_EGRESS] = self.t_egress + if self.direct_route_travel_time is not None: + record_dict[G_RQ_DRT] = self.direct_route_travel_time + if self.direct_route_travel_distance is not None: + record_dict[G_RQ_DRD] = self.direct_route_travel_distance + # offers + all_offer_info = [] + for op_id, operator_offer in self.offer.items(): + all_offer_info.append(f"{op_id}:" + operator_offer.to_output_str()) + record_dict[G_RQ_OFFERS] = "|".join(all_offer_info) + # decision-dependent + record_dict[G_RQ_LEAVE_TIME] = self.leave_system_time + record_dict[G_RQ_CHOSEN_OP_ID] = self.chosen_operator_id + record_dict[G_RQ_OP_ID] = self.service_opid + record_dict[G_RQ_VID] = self.service_vid + record_dict[G_RQ_PU] = self.pu_time + record_dict[G_RQ_DO] = self.do_time + record_dict[G_RQ_FARE] = self.fare + record_dict[G_RQ_MODAL_STATE] = self.modal_state + return self._add_record(record_dict) + + def choose_offer(self, scenario_parameters, simulation_time): + """This method returns the operator id of the chosen mode. If both a PT-only and an AMoD+PT offer is available, + the AMoD+PT offer is always chosen. If only one offer is available, this offer is chosen. + For intermodal offers, the operator id is a tuple: ((operator_id, sub_trip_id), ...) + 0..n: MoD fleet provider + None: not decided yet + -1: decline all MoD + -2: PT operator + :param scenario_parameters: scenario parameter dictionary + :param simulation_time: current simulation time + :return: operator_id of chosen offer; or -1 if all MoD offers are declined; None if decision not defined yet + """ + test_all_decline = super().choose_offer(scenario_parameters, simulation_time) + if test_all_decline is not None and test_all_decline < 0: + return -1 + if len(self.offer) == 0: + return None + opts = [offer_id for offer_id, operator_offer in self.offer.items() if + operator_offer is not None and not operator_offer.service_declined()] + if len(opts) == 0: + return None + elif len(opts) == 1: # only one offer: pure pt or amod+pt + self.fare = self.offer[opts[0]].get(G_OFFER_FARE, 0) + self.chosen_operator_id = opts[0] + return opts[0] + elif len(opts) == 2: # two offers: pure pt and amod+pt + # always choose amod+pt + for offer_id, operator_offer in self.offer.items(): + op_id = operator_offer.operator_id + if op_id != -2: + self.fare = operator_offer.get(G_OFFER_FARE, 0) + self.chosen_operator_id = op_id + return offer_id + else: + LOG.error(f"not implemented {offer_str(self.offer)}") + raise NotImplementedError + # -------------------------------------------------------------------------------------------------------------------- # # Parcel Requests # diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index 2b7baccd..d76981da 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -87,6 +87,7 @@ def get_src_request_modules(): rm_dict["BrokerDecisionRequest"] = ("src.demand.TravelerModels", "BrokerDecisionRequest") rm_dict["UserDecisionRequest"] = ("src.demand.TravelerModels", "UserDecisionRequest") rm_dict["PreferredOperatorRequest"] = ("src.demand.TravelerModels", "PreferredOperatorRequest") + rm_dict["BasicIntermodalRequest"] = ("src.demand.TravelerModels", "BasicIntermodalRequest") # add development content if dev_content is not None: dev_rm_dict = dev_content.add_request_models() From aab0f94e92c5bb976a24b9e58d09a71a0b968f3b Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 15 Dec 2025 16:34:13 +0100 Subject: [PATCH 10/31] Add PTControl class to simulate PT operator behaviors --- src/misc/globals.py | 12 +- src/misc/init_modules.py | 23 ++++ src/ptctrl/PTControlBase.py | 78 +++++++++++++ src/ptctrl/PTControlBasic.py | 183 ++++++++++++++++++++++++++++++ src/routing/pt/RaptorRouterCpp.py | 21 +++- src/simulation/Offers.py | 39 ++++--- 6 files changed, 331 insertions(+), 25 deletions(-) create mode 100644 src/ptctrl/PTControlBase.py create mode 100644 src/ptctrl/PTControlBasic.py diff --git a/src/misc/globals.py b/src/misc/globals.py index 894f7eba..4a31960d 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -609,6 +609,8 @@ class RQ_SUB_TRIP_ID(Enum): G_IM_OFFER_LM_WAIT = "im_t_wait_lm" # Only used fot AMoD segment in LM G_IM_OFFER_FM_DRIVE = "im_t_drive_fm" # Only used for AMoD segment in FM G_IM_OFFER_LM_DRIVE = "im_t_drive_lm" # Only used fot AMoD segment in LM +G_IM_OFFER_PT_WAIT = "im_t_wait_pt" # total pt waiting time +G_IM_OFFER_PT_DRIVE = "im_t_drive_pt" # total pt driving time G_IM_OFFER_DURATION = "im_t_duration" # total duration of intermodal offer # additional parameters for pt offers @@ -616,14 +618,16 @@ class RQ_SUB_TRIP_ID(Enum): G_PT_OFFER_SOURCE_STATION = "source_station_id" G_PT_OFFER_TARGET_STATION = "target_station_id" G_PT_OFFER_SOURCE_WALKING_TIME = "source_walking_time" +G_PT_OFFER_SOURCE_STATION_DEPARTURE_TIME = "source_station_departure_time" G_PT_OFFER_SOURCE_TRANSFER_TIME = "source_transfer_time" -G_PT_OFFER_TRIP_TIME = "pt_trip_time" +G_PT_OFFER_SOURCE_WAITING_TIME = "source_waiting_time" +G_PT_OFFER_TRIP_TIME = "trip_time" G_PT_OFFER_TARGET_TRANSFER_TIME = "target_transfer_time" +G_PT_OFFER_TARGET_STATION_ARRIVAL_TIME = "target_station_arrival_time" G_PT_OFFER_TARGET_WALKING_TIME = "target_walking_time" G_PT_OFFER_NUM_TRANSFERS = "num_transfers" -G_PT_OFFER_WAIT = "pt_t_wait" # PT segment waiting time -G_PT_OFFER_DURATION = "pt_duration" # PT segment total duration -G_PT_OFFER_DRIVE = "pt_t_drive" # PT segment driving time --> total pt segment duration - pt waiting time +G_PT_OFFER_STEPS = "steps" +G_PT_OFFER_DURATION = "duration" # PT segment total duration # -------------------------------------------------------------------------------------------------------------------- # # Fleet Simulation Pattern diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index d76981da..3827bd1c 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -8,6 +8,7 @@ from src.routing.road.NetworkBase import NetworkBase from src.fleetctrl.FleetControlBase import FleetControlBase from src.broker.BrokerBase import BrokerBase + from src.ptctrl.PTControlBase import PTControlBase from src.demand.TravelerModels import RequestBase from src.fleetctrl.repositioning.RepositioningBase import RepositioningBase from src.fleetctrl.charging.ChargingBase import ChargingBase @@ -123,6 +124,16 @@ def get_src_broker_modules(): broker_dict.update(dev_broker_dict) return broker_dict +def get_src_pt_control_modules(): + # FleetPy pt control options + ptc_dict = {} # str -> (module path, class name) + ptc_dict["PTControlBasic"] = ("src.ptctrl.PTControlBasic", "PTControlBasic") + # add development content + if dev_content is not None: + dev_ptc_dict = dev_content.add_pt_control_modules() + ptc_dict.update(dev_ptc_dict) + return ptc_dict + def get_src_repositioning_strategies(): repo_dict = {} # str -> (module path, class name) repo_dict["PavoneFC"] = ("src.fleetctrl.repositioning.PavoneHailingFC", "PavoneHailingRepositioningFC") @@ -285,6 +296,18 @@ def load_broker_module(broker_type) -> BrokerBase: # get broker class return load_module(broker_dict, broker_type, "Broker module") +def load_pt_control_module(pt_control_type) -> PTControlBase: + """This function initiates the required pt control module and returns the PTControl class, which can be used + to generate a pt operator instance. + + :param pt_control_type: string that determines which pt control should be used + :return: PTControl class + """ + # FleetPy pt control options + ptc_dict = get_src_pt_control_modules() + # get pt control class + return load_module(ptc_dict, pt_control_type, "PT control module") + def load_repositioning_strategy(op_repo_class_string) -> RepositioningBase: """This function chooses the repositioning module that should be loaded. diff --git a/src/ptctrl/PTControlBase.py b/src/ptctrl/PTControlBase.py new file mode 100644 index 00000000..f6715973 --- /dev/null +++ b/src/ptctrl/PTControlBase.py @@ -0,0 +1,78 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import logging +import typing as tp +from abc import abstractmethod, ABCMeta + +# additional module imports (> requirements) +# ------------------------------------------ + +# src imports +# ----------- + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) + +INPUT_PARAMETERS_PTControlBase = { + "doc" : "this class is the base class representing an PT operator", + "inherit" : None, + "input_parameters_mandatory": [], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTControlBase(metaclass=ABCMeta): + @abstractmethod + def __init__(self): + pass + + @abstractmethod + def _load_pt_router(self): + """This method will load and initialize the pt router instance. + """ + pass + + @abstractmethod + def return_fastest_pt_journey_1to1(self): + """This method will return the fastest pt journey between an origin and a destination. + """ + pass + + @abstractmethod + def create_and_record_pt_offer_db(self): + """This method will create a TravellerOffer for the pt request and record it in the pt offer database. + """ + pass + + @abstractmethod + def get_current_offer(self): + """This method will return the current offer for the pt request. + """ + pass + + @abstractmethod + def user_confirms_booking(self): + """This method is used to confirm a customer booking. This can trigger some database processes. + """ + pass + + @abstractmethod + def _compute_fare(self): + """This method will compute the fare for the pt request. + """ + pass + + @abstractmethod + def _update_gtfs_data(self): + """This method will update the gtfs data of the pt router to reflect any changes in the pt network or schedule. + """ + pass \ No newline at end of file diff --git a/src/ptctrl/PTControlBasic.py b/src/ptctrl/PTControlBasic.py new file mode 100644 index 00000000..3fea2ddc --- /dev/null +++ b/src/ptctrl/PTControlBasic.py @@ -0,0 +1,183 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import os +import logging +from datetime import datetime +import ast +import typing as tp +import pandas as pd + +# additional module imports (> requirements) +# ------------------------------------------ + +# src imports +# ----------- +from src.ptctrl.PTControlBase import PTControlBase +from src.routing.pt.RaptorRouterCpp import RaptorRouterCpp +from src.simulation.Offers import Rejection, PTOffer +if tp.TYPE_CHECKING: + from src.demand.TravelerModels import BasicIntermodalRequest + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) + +INPUT_PARAMETERS_PTControlBasic = { + "doc" : "this class is the basic PT control class using C++ Raptor implementation", + "inherit" : PTControlBase, + "input_parameters_mandatory": [], + "input_parameters_optional": [], + "mandatory_modules": [RaptorRouterCpp, PTControlBase, Rejection, PTOffer], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTControlBasic(PTControlBase): + def __init__(self, gtfs_dir: str, pt_operator_id: int = -2): + super().__init__() + + self.pt_router: RaptorRouterCpp = self._load_pt_router(gtfs_dir) + self.pt_operator_id: int = pt_operator_id + + self.pt_offer_db: tp.Dict[str, 'PTOffer'] = {} # rid_struct -> PTOffer + + LOG.info("PT operator initialized successfully.") + + def _load_pt_router(self, gtfs_dir: str) -> RaptorRouterCpp: + """This method will load and initialize the pt router instance. + + Args: + gtfs_dir (str): the directory path where the GTFS files are stored. + """ + return RaptorRouterCpp(gtfs_dir) + + def return_fastest_pt_journey_1to1( + self, + source_station_id: str, target_station_id: str, + source_station_departure_time: int, + max_transfers: int = 999, + detailed: bool = False, + ) -> tp.Union[tp.Dict[str, tp.Any], None]: + """This method will return the fastest pt journey between an origin and a destination. + + Args: + source_station_id (str): id of the source station. + target_station_id (str): id of the target station. + source_station_departure_time (int): departure timestamp [s] from source station. + max_transfers (int, optional): maximum number of transfers allowed. Defaults to 999 (no limit). + detailed (bool, optional): whether to return a detailed journey plan. Defaults to False. + Returns: + tp.Union[tp.Dict[str, tp.Any], None]: The pt journey plan dictionary or None if no journey is found. + """ + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_router.find_fastest_pt_journey_1to1( + source_station_id = source_station_id, + target_station_id = target_station_id, + source_station_departure_time = source_station_departure_time, + max_transfers = max_transfers, + detailed = detailed, + ) + return pt_journey_plan_dict + + def create_and_record_pt_offer_db( + self, + rid_struct: str, operator_id: int, + source_station_id: str, target_station_id: str, + source_walking_time: int,target_walking_time: int, + source_station_departure_time: int, + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None], + previous_amod_operator_id: int = None, + ): + """This method will create a PTOffer for the pt request and record it in the pt offer database. + + Args: + rid_struct (str): sub-request id struct of the journey. + operator_id (int): id of PT operator (-2). + source_station_id (str): id of the source station. + target_station_id (str): id of the target station. + source_walking_time (int): walking time [s] from origin street node to source station. + target_walking_time (int): walking time [s] from target station to destination street node. + source_station_departure_time (int): departure timestamp [s] from source station. + pt_journey_plan_dict (tp.Union[tp.Dict[str, tp.Any], None]): The pt journey plan dictionary or None if no journey is found. + previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + """ + if pt_journey_plan_dict is None: + self.pt_offer_db[(rid_struct, previous_amod_operator_id)] = Rejection(rid_struct, operator_id) + else: + fare: int = self._compute_fare() + # old offer will always be overwritten + self.pt_offer_db[(rid_struct, previous_amod_operator_id)] = PTOffer( + traveler_id = rid_struct, operator_id = operator_id, + source_station_id = source_station_id, target_station_id = target_station_id, + source_walking_time = source_walking_time, source_station_departure_time = source_station_departure_time, + source_transfer_time = pt_journey_plan_dict.get(G_PT_OFFER_SOURCE_TRANSFER_TIME, None), + waiting_time = pt_journey_plan_dict.get(G_PT_OFFER_SOURCE_WAITING_TIME, None), + trip_time = pt_journey_plan_dict.get(G_PT_OFFER_TRIP_TIME, None), + fare = fare, + target_transfer_time = pt_journey_plan_dict.get(G_PT_OFFER_TARGET_TRANSFER_TIME, None), + target_station_arrival_time = pt_journey_plan_dict.get(G_PT_OFFER_TARGET_STATION_ARRIVAL_TIME, None), + target_walking_time = target_walking_time, + num_transfers = pt_journey_plan_dict.get(G_PT_OFFER_NUM_TRANSFERS, None), + pt_journey_duration = pt_journey_plan_dict.get(G_PT_OFFER_DURATION, None), + detailed_journey_plan = pt_journey_plan_dict.get(G_PT_OFFER_STEPS, None), + ) + + def _compute_fare(self) -> int: + """This method will compute the fare for the pt request. + + For the basic implementation, this method returns 0. + """ + return 0 + + def get_current_offer( + self, + rid_struct: str, + previous_amod_operator_id: int = None, + ) -> tp.Optional[PTOffer]: + """This method will return the current offer for the pt request. + + Args: + rid_struct (str): The sub-request id struct of the journey. + previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + Returns: + tp.Optional[PTOffer]: The current offer for the pt request. + """ + return self.pt_offer_db.get((rid_struct, previous_amod_operator_id), None) + + def user_confirms_booking( + self, + pt_sub_rq_obj: 'BasicIntermodalRequest', + previous_amod_operator_id: int = None + ): + """This method is used to confirm a customer booking. This can trigger some database processes. + + Args: + pt_sub_rq_obj (BasicMultimodalRequest): The pt sub-request object. + previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + """ + pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() + pt_offer: 'PTOffer' = self.get_current_offer(pt_rid_struct, previous_amod_operator_id) + pt_sub_rq_obj.user_boards_vehicle( + simulation_time = pt_offer.get(G_PT_OFFER_SOURCE_STATION_DEPARTURE_TIME, None), + op_id = self.pt_operator_id, + vid = -1, + pu_pos = None, + t_access = pt_offer.get(G_PT_OFFER_SOURCE_WALKING_TIME, None), + ) + pt_sub_rq_obj.user_leaves_vehicle( + simulation_time = pt_offer.get(G_PT_OFFER_TARGET_STATION_ARRIVAL_TIME, None), + do_pos = None, + t_egress = pt_offer.get(G_PT_OFFER_TARGET_WALKING_TIME, None), + ) + + def _update_gtfs_data(self): + """This method will update the gtfs data of the pt router to reflect any changes in the pt network or schedule. + + For the basic implementation, this method does nothing. + """ + pass diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py index 7365c3e5..adc0b94b 100644 --- a/src/routing/pt/RaptorRouterCpp.py +++ b/src/routing/pt/RaptorRouterCpp.py @@ -112,7 +112,7 @@ def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFram } return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) - def return_fastest_pt_journey_1to1( + def find_fastest_pt_journey_1to1( self, source_station_id: str, target_station_id: str, @@ -131,6 +131,25 @@ def return_fastest_pt_journey_1to1( detailed (bool): Whether to return the detailed journey plan. Returns: tp.Union[tp.Dict[str, tp.Any], None]: The fastest PT journey plan or None if no journey is found. + + The returned dictionary contains the following keys: + * 'duration' (int): duration [s] from departure at the source station to arrival at the target station. + * 'trip_time' (int): travel time [s] from departure at the source stop until arrival at the target stop. + * 'num_transfers' (int): number of transfers. + * 'source_station_departure_time' (int): departure timestamp [s] at the source station. + * 'source_station_departure_day' (str): 'current_day' or 'next_day' depending on the departure time. + * 'source_transfer_time' (int): transfer time [s] from the source station to the source stop. + * 'source_waiting_time' (int): waiting time [s] from arrival at the source stop until departure of the trip., + * 'target_transfer_time' (int): transfer time [s] from the target stop to the target station. + * 'target_station_arrival_time' (int):arrival timestamp [s] at the target station. + * 'target_station_arrival_day' (str): 'current_day' or 'next_day' depending on the arrival time. + * 'steps' (List[dict]): a list of journey steps, where each step contains: + - 'duration' (int): step duration [s] from departure at the start stop until arrival at the end stop. + - 'departure_time' (int): departure timestamp [s] at the start stop. + - 'arrival_time' (int): arrival timestamp [s] at the end stop. + - 'from_stop_id' (str): ID of the start stop. + - 'to_stop_id' (str): ID of the end stop. + - ... (other step keys, check the C++ Raptor router documentation for more details). """ # get all included stops for the source and target station included_sources = self._get_included_stops_and_transfer_times(source_station_id) diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index fc4dc5cb..95d0c412 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -152,7 +152,7 @@ class PTOffer(TravellerOffer): - source_station_departure_time (int): absolute time [s] of the departure at the source station - source_transfer_time (int): transfer time [s] from the source station to the source stop - waiting_time (int): waiting time [s] from arrival at the source stop until departure; this value is used as the 'offered_waiting_time' in the TravellerOffer - - pt_trip_time (int): travel time [s] from departure at the source stop until arrival at the target stop + - trip_time (int): travel time [s] from departure at the source stop until arrival at the target stop - fare (int): fare of the offer - target_transfer_time (int): transfer time [s] from the target stop to the target station - target_station_arrival_time (int): absolute time [s] of the arrival at the target station @@ -168,32 +168,30 @@ def __init__( traveler_id: str, operator_id: int, source_station_id: str, target_station_id: str, source_walking_time: int, source_station_departure_time: int, source_transfer_time: int, - waiting_time: int, pt_trip_time: int, fare: int, + waiting_time: int, trip_time: int, fare: int, target_transfer_time: int, target_station_arrival_time: int, target_walking_time: int, num_transfers: int, pt_journey_duration: int, detailed_journey_plan: tp.List[tp.Dict[str, tp.Any]], ): self.origin_node_arrival_time = source_station_departure_time - source_walking_time - self.source_station_departure_time = source_station_departure_time + self.destination_node_arrival_time = target_station_arrival_time + target_walking_time - self.target_station_arrival_time = target_station_arrival_time - self.destination_node_arrival_time = self.target_station_arrival_time + target_walking_time - - self.pt_journey_duration = pt_journey_duration - pt_segment_duration = self.destination_node_arrival_time - self.origin_node_arrival_time + self.pt_segment_duration = self.destination_node_arrival_time - self.origin_node_arrival_time + offered_driving_time = self.pt_segment_duration - waiting_time self.detailed_journey_plan = detailed_journey_plan - offered_driving_time = pt_segment_duration - waiting_time - additional_parameters = { G_PT_OFFER_SOURCE_STATION: source_station_id, G_PT_OFFER_TARGET_STATION: target_station_id, G_PT_OFFER_SOURCE_WALKING_TIME: source_walking_time, + G_PT_OFFER_SOURCE_STATION_DEPARTURE_TIME: source_station_departure_time, G_PT_OFFER_SOURCE_TRANSFER_TIME: source_transfer_time, - G_PT_OFFER_TRIP_TIME: pt_trip_time, + G_PT_OFFER_TRIP_TIME: trip_time, G_PT_OFFER_TARGET_TRANSFER_TIME: target_transfer_time, + G_PT_OFFER_TARGET_STATION_ARRIVAL_TIME: target_station_arrival_time, G_PT_OFFER_TARGET_WALKING_TIME: target_walking_time, G_PT_OFFER_NUM_TRANSFERS: num_transfers, + G_PT_OFFER_DURATION: pt_journey_duration, } super().__init__(traveler_id, operator_id, waiting_time, offered_driving_time, fare, additional_parameters=additional_parameters) @@ -249,18 +247,21 @@ def _merge_sub_trip_offers(self) -> tp.Dict[str, tp.Any]: # State -> [(SubTripID, WaitKey, DriveKey)] amod_state_mapping = { RQ_MODAL_STATE.FIRSTMILE: [ - (RQ_SUB_TRIP_ID.FM_AMOD.value, G_IM_OFFER_FM_WAIT, G_IM_OFFER_FM_DRIVE) + (RQ_SUB_TRIP_ID.FM_AMOD.value, G_IM_OFFER_FM_WAIT, G_IM_OFFER_FM_DRIVE), + (RQ_SUB_TRIP_ID.FM_PT.value, G_IM_OFFER_PT_WAIT, G_IM_OFFER_PT_DRIVE) ], RQ_MODAL_STATE.LASTMILE: [ - (RQ_SUB_TRIP_ID.LM_AMOD.value, G_IM_OFFER_LM_WAIT, G_IM_OFFER_LM_DRIVE) + (RQ_SUB_TRIP_ID.LM_AMOD.value, G_IM_OFFER_LM_WAIT, G_IM_OFFER_LM_DRIVE), + (RQ_SUB_TRIP_ID.LM_PT.value, G_IM_OFFER_PT_WAIT, G_IM_OFFER_PT_DRIVE) ], RQ_MODAL_STATE.FIRSTLASTMILE: [ (RQ_SUB_TRIP_ID.FLM_AMOD_0.value, G_IM_OFFER_FLM_WAIT_0, G_IM_OFFER_FLM_DRIVE_0), + (RQ_SUB_TRIP_ID.FLM_PT.value, G_IM_OFFER_PT_WAIT, G_IM_OFFER_PT_DRIVE), (RQ_SUB_TRIP_ID.FLM_AMOD_1.value, G_IM_OFFER_FLM_WAIT_1, G_IM_OFFER_FLM_DRIVE_1) ] } - pt_attributes_to_extract = [G_PT_OFFER_WAIT, G_PT_OFFER_DRIVE, G_PT_OFFER_NUM_TRANSFERS] + pt_attributes_to_extract = [G_PT_OFFER_NUM_TRANSFERS] # calculate totals operator_sub_trip_list = [] @@ -274,17 +275,15 @@ def _merge_sub_trip_offers(self) -> tp.Dict[str, tp.Any]: total_wait += sub_trip_offer.get(G_OFFER_WAIT, 0) total_drive += sub_trip_offer.get(G_OFFER_DRIVE, 0) - # add pt attributes into additional parameters - pt_offer = self.sub_trip_offers.get(RQ_SUB_TRIP_ID.FLM_PT.value, {}) - for key in pt_attributes_to_extract: - if key in pt_offer: - self.additional_offer_parameters[key] = pt_offer[key] - # map amod attributes into additional parameters mapping_configs = amod_state_mapping.get(self.rq_modal_state, []) for sub_trip_id, wait_key, drive_key in mapping_configs: offer = self.sub_trip_offers.get(sub_trip_id, {}) + # map pt specific attributes + if sub_trip_id == RQ_SUB_TRIP_ID.FM_PT.value or sub_trip_id == RQ_SUB_TRIP_ID.PT_LM.value or sub_trip_id == RQ_SUB_TRIP_ID.FLM_PT.value: + for attr in pt_attributes_to_extract: + self.additional_offer_parameters[attr] = offer.get(attr) self.additional_offer_parameters[wait_key] = offer.get(G_OFFER_WAIT) self.additional_offer_parameters[drive_key] = offer.get(G_OFFER_DRIVE) From 48339d530bacbfe38ed9fbb7d00469946e54d7f6 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Wed, 17 Dec 2025 21:13:00 +0100 Subject: [PATCH 11/31] feat: introduce RAPTOR-based PT router and TPCS PTBroker This update enables full intermodal simulation capabilities in FleetPy by introducing a high-performance C++ routing engine and a new broker strategy. Detailed changes are documented in CHANGELOG.md. --- .gitignore | 6 +- changelog.md | 77 ++ .../example_100_intermodal.csv | 101 ++ run_examples.py | 8 +- src/FleetSimulationBase.py | 105 +- src/ImmediateDecisionsSimulation.py | 2 +- src/broker/BrokerBase.py | 2 +- src/broker/BrokerBasic.py | 3 +- src/broker/PTBrokerTPCS.py | 945 ++++++++++++++++++ src/demand/TravelerModels.py | 56 +- src/demand/demand.py | 43 +- src/evaluation/intermodal.py | 204 ++++ src/fleetctrl/PoolingIRSOnly.py | 33 +- src/fleetctrl/planning/PlanRequest.py | 5 + src/fleetctrl/pooling/immediate/insertion.py | 25 +- src/fleetctrl/reservation/RollingHorizon.py | 9 +- src/misc/globals.py | 16 +- src/misc/init_modules.py | 1 + .../pubtrans/PTRouterGTFSPreperation.ipynb | 651 ++++++++++++ src/ptctrl/PTControlBase.py | 8 +- src/ptctrl/PTControlBasic.py | 44 +- src/routing/pt/RaptorRouterCpp.py | 23 +- src/simulation/Offers.py | 7 +- src/simulation/Vehicles.py | 4 +- .../example_study/scenarios/example_im.csv | 3 + studies/module_tests/run_module_tests.py | 7 + .../module_tests/scenarios/sc_config_im.csv | 3 + 27 files changed, 2263 insertions(+), 128 deletions(-) create mode 100644 data/demand/example_demand/matched/example_network/example_100_intermodal.csv create mode 100644 src/broker/PTBrokerTPCS.py create mode 100644 src/evaluation/intermodal.py create mode 100644 src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb create mode 100644 studies/example_study/scenarios/example_im.csv create mode 100644 studies/module_tests/scenarios/sc_config_im.csv diff --git a/.gitignore b/.gitignore index 8d4920b8..2fac21a2 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,8 @@ data/zones/* studies/* !studies/example_study studies/example_study/results/* -!studies/module_tests/* +!studies/module_tests +studies/module_tests/benchmark_comparison.csv studies/module_tests/results/* !studies/module_tests/results/benchmark.csv !studies/manhattan_case_study @@ -194,3 +195,6 @@ dmypy.json # MacOS .DS_Store +# GTFS preprocessing file +!src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb + diff --git a/changelog.md b/changelog.md index 306d9a82..b3a0093d 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,83 @@ All notable changes to this project will be documented in this file. +## [1.1.0] - 2025-12-18 + +Key update: +1. Refactored routing file structure: road-related routing modules are moved to the `road` subdirectory, and PT-related routing modules are moved to the `pt` subdirectory. +2. Introduced a C++ routing module based on the RAPTOR algorithm for querying the fastest PT travel plans between two stations. +3. Introduced the PTControl module to simulate PT operator behavior, such as recording offer information and dynamically updating GTFS files. +4. Introduced the PTBroker module based on the TPCS strategy to simulate MaaS platform planning for intermodal requests. +5. Introduced subrequest ID coding rules for intermodal scenarios, using unique integers to classify legs and `{parent_rid}_{subtrip_id}` to define new subrequest IDs. + +### Added +- cpp_raptor_router: C++ implementation of the PT router based on the RAPTOR algorithm + +- RaptorRouterCpp: Python entry point for the PT router, responsible for activating the cpp_raptor_router instance and regularizing PT requests + +- PTControlBase & PTControlBasic: Modules to simulate PT operator behavior, such as recording offer information and dynamically updating GTFS files + +- PTOffer: Class for recording PT offer information + +- IntermodalOffer: Class for recording offer information for intermodal requests + +- BasicIntermodalRequest: Class to simulate travel behavior of travelers with intermodal requests + +- example_100_intermodal.csv: Intermodal demand based on example_100.csv, containing 25 monomodal, 25 first-mile, 25 last-mile, and 25 first-last-mile requests + +- example_gtfs: Public transport design based on example_network + +- PTBrokerTPCS: PTBroker module based on TPCS strategy for intermodal planning. Use `G_BROKER_TPCS_USE_DEFAULT` to toggle between full three-stage or first-stage only + +- intermodal_evaluation: Evaluation methods designed for intermodal scenarios + +- example_study & module_tests: Added intermodal scenario example experiments + +- globals: Added subrequest ID coding rules for intermodal scenarios and global variables for PT, Intermodal, and TPCS + +- init_modules: Added initialization code for PTControl and PTBroker modules + +- FleetSimulationBase: Added code to load PTControl and PTBroker modules + +- PlanRequest: Added `set_new_dropoff_time_constraint` method to update the passenger's latest drop-off time constraint + +- Demand: Added `create_sub_requests` method to establish sub-requests for corresponding legs of intermodal requests + +- RequestBase: Added `modal state` attribute (default: monomodal) and `get_modal_state` method + +- PTRouterGTFSPreperation: Jupyter notebook for cleaning and formatting raw GTFS data for RaptorRouterCpp + +### Changed +- BrokerBase & BrokerBasic: `collect_offers` method now accepts an input variable `sim_time` (int, default: None) + +- ImmediateDecisionsSimulation: Added `sim_time` input variable when calling `self.broker.collect_offers` + +- RequestBase: Updated `create_SubTripRequest` method to create intermodal sub-requests + +- insertion: `insertion_with_heuristics` and `reservation_insertion_with_heuristics` methods added `excluded_vid` input (list of vehicle IDs that should not be considered for assignment) + +- RollingHorizon: `return_immediate_reservation_offer` method added `excluded_vid` input + +- PoolingIRSOnly: `user_request` method now adds the vehicle used for the FM leg to `excluded_vid` when processing FLM requests, ignoring this vehicle for the LM leg of the same parent request + +- Vehicles: `assign_vehicle_plan` method now uses `rid_struct` to obtain request information + +- FleetSimulationBase: Modified public transportation module loading code; modified `evaluate` method to use `G_EVAL_METHOD` to specify standard result evaluation (default: standard_evaluation) + +- gitignore: Ignored specific C++ Router files + +### Deprecated +- globals: Traveler modal state global variables are no longer used (G_RQ_STATE_MONOMODAL, G_RQ_STATE_FIRSTMILE, G_RQ_STATE_LASTMILE, G_RQ_STATE_FIRSTLASTMILE) + +### Removed +- globals: Traveler modal state global variable names + +### Fixed +- RollingHorizon: Correctly retrieve `vid` and `veh_obj` in `user_cancels_request` method + +- FleetSimulationBase: In `update_sim_state_fleets`, ensured `rid_struct` is the actual key of the dictionary returned by `veh_obj.update_veh_state` + + ## [1.0.0] - 2025-04-DD diff --git a/data/demand/example_demand/matched/example_network/example_100_intermodal.csv b/data/demand/example_demand/matched/example_network/example_100_intermodal.csv new file mode 100644 index 00000000..05314130 --- /dev/null +++ b/data/demand/example_demand/matched/example_network/example_100_intermodal.csv @@ -0,0 +1,101 @@ +rq_time,start,end,request_id,is_multimodal,modal_state_value,transfer_station_ids,max_transfers +194,2966,2977,0,1,2,s15,1 +217,2966,2973,1,0,0,-1,1 +301,2976,2966,2,1,1,s15,1 +388,2982,2980,3,0,0,-1,1 +397,2977,2968,4,1,3,s15;s1,1 +679,2966,2985,5,1,2,s15,1 +890,2993,2988,6,0,0,-1,1 +896,2966,2973,7,1,2,s15,1 +933,2977,2986,8,1,3,s15;s1,1 +959,2976,2982,9,0,0,-1,1 +983,2977,2966,10,1,1,s15,1 +1085,2966,2981,11,1,2,s15,1 +1092,2992,2980,12,0,0,-1,1 +1185,2987,2984,13,0,0,-1,1 +1204,2966,2981,14,1,2,s15,1 +1320,2993,2980,15,1,1,s1,1 +1449,2977,2967,16,1,3,s15;s1,1 +1511,2984,2966,17,1,1,s15,1 +1514,2989,2977,18,1,3,s1;s15,1 +1558,2989,2975,19,1,3,s1;s15,1 +1587,2981,2979,20,0,0,-1,1 +1659,2978,2966,21,1,1,s15,1 +1668,2966,2982,22,1,2,s15,1 +1681,2967,2980,23,1,1,s1,1 +1725,2966,2977,24,1,2,s15,1 +1735,2990,2982,25,1,3,s1;s15,1 +2045,2980,2993,26,1,2,s1,1 +2045,2969,2993,27,0,0,-1,1 +2127,2973,2966,28,1,1,s15,1 +2198,2966,2976,29,1,2,s15,1 +2309,2986,2966,30,1,1,s15,1 +2383,2989,2978,31,1,3,s1;s15,1 +2416,2981,2969,32,1,3,s15;s1,1 +2494,2992,2980,33,1,1,s1,1 +2540,2980,2970,34,1,2,s1,1 +2626,2990,2988,35,1,3,s1;s15,1 +2727,2972,2985,36,0,0,-1,1 +2803,2970,2972,37,0,0,-1,1 +2881,2993,2980,38,1,1,s1,1 +2912,2992,2982,39,1,3,s1;s15,1 +2947,2990,2981,40,0,0,-1,1 +3008,2966,2982,41,1,2,s15,1 +3064,2986,2970,42,0,0,-1,1 +3088,2973,2966,43,1,1,s15,1 +3109,2967,2981,44,1,3,s1;s15,1 +3303,2980,2971,45,1,2,s1,1 +3373,2976,2987,46,0,0,-1,1 +3437,2971,2966,47,1,1,s15,1 +3616,2966,2982,48,1,2,s15,1 +3637,2983,2966,49,1,1,s15,1 +3725,2974,2966,50,1,1,s15,1 +3846,2966,2988,51,1,2,s15,1 +3855,2969,2979,52,1,3,s1;s15,1 +3881,2980,2990,53,1,2,s1,1 +4260,2980,2992,54,1,2,s1,1 +4325,2972,2991,55,0,0,-1,1 +4341,2979,2969,56,1,3,s15;s1,1 +4394,2983,2967,57,1,3,s15;s1,1 +4464,2981,2971,58,0,0,-1,1 +4476,2966,2981,59,1,2,s15,1 +4564,2980,2969,60,1,2,s1,1 +4621,2979,2968,61,1,3,s15;s1,1 +4642,2991,2980,62,1,1,s1,1 +4722,2989,2967,63,0,0,-1,1 +4877,2978,2992,64,1,3,s15;s1,1 +4944,2980,2972,65,1,2,s1,1 +4960,2979,2966,66,1,1,s15,1 +4984,2987,2966,67,1,1,s15,1 +4997,2980,2992,68,1,2,s1,1 +5118,2968,2980,69,1,1,s1,1 +5177,2993,2977,70,1,3,s1;s15,1 +5237,2985,2967,71,1,3,s15;s1,1 +5401,2967,2981,72,0,0,-1,1 +5459,2980,2969,73,1,2,s1,1 +5470,2969,2979,74,0,0,-1,1 +5486,2984,2993,75,1,3,s15;s1,1 +5505,2984,2992,76,1,3,s15;s1,1 +5531,2986,2966,77,1,1,s15,1 +5541,2970,2981,78,1,3,s1;s15,1 +5563,2978,2975,79,0,0,-1,1 +5571,2980,2993,80,1,2,s1,1 +5580,2984,2969,81,0,0,-1,1 +5622,2970,2980,82,1,1,s1,1 +5637,2975,2976,83,0,0,-1,1 +5701,2966,2987,84,1,2,s15,1 +5726,2971,2978,85,0,0,-1,1 +5788,2969,2982,86,1,3,s1;s15,1 +6062,2978,2993,87,1,3,s15;s1,1 +6252,2966,2982,88,1,2,s15,1 +6437,2992,2980,89,0,0,-1,1 +6580,2982,2966,90,1,1,s15,1 +6617,2973,2982,91,0,0,-1,1 +6648,2973,2966,92,1,1,s15,1 +6685,2967,2974,93,1,3,s1;s15,1 +6707,2968,2991,94,0,0,-1,1 +6850,2966,2987,95,1,2,s15,1 +6886,2991,2980,96,1,1,s1,1 +6910,2983,2993,97,1,3,s15;s1,1 +6944,2976,2966,98,1,1,s15,1 +7152,2988,2980,99,1,1,s1,1 diff --git a/run_examples.py b/run_examples.py index 5f9f6541..58748628 100644 --- a/run_examples.py +++ b/run_examples.py @@ -317,9 +317,15 @@ def check_assertions(list_eval_df, all_scenario_assertion_dict): sc = os.path.join(scs_path, "example_rpp.csv") run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=1) + # n) Pooling with Intermodal demand + log_level = "info" + cc = os.path.join(scs_path, "constant_config_ir.csv") + sc = os.path.join(scs_path, "example_im.csv") + run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=1) + # i) Semi-on-Demand Public Transit example # Run PTScheduleGen.py to generate required PT files first log_level = "info" cc = os.path.join(scs_path, "constant_config_sod.csv") sc = os.path.join(scs_path, "example_sod.csv") - run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=1) + run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=1) \ No newline at end of file diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index aec8ed26..b2835a9d 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -21,7 +21,7 @@ # src imports # ----------- -from src.misc.init_modules import load_fleet_control_module, load_routing_engine, load_broker_module +from src.misc.init_modules import load_fleet_control_module, load_routing_engine, load_broker_module, load_pt_control_module from src.demand.demand import Demand, SlaveDemand from src.simulation.Vehicles import SimulationVehicle if tp.TYPE_CHECKING: @@ -29,6 +29,7 @@ from src.routing.road.NetworkBase import NetworkBase from src.broker.BrokerBase import BrokerBase from src.python_plots.plot_classes import PyPlot + from src.ptctrl.PTControlBase import PTControlBase # -------------------------------------------------------------------------------------------------------------------- # # global variables @@ -251,21 +252,23 @@ def __init__(self, scenario_parameters: dict): self.network_stat_f) # public transportation module LOG.info("Initialization of line-based public transportation...") - pt_type = self.scenario_parameters.get(G_PT_TYPE) - self.gtfs_data_dir = self.dir_names.get(G_DIR_PT) - if pt_type is None or self.gtfs_data_dir is None: - self.pt = None - elif pt_type == "PTMatrixCrowding": - pt_module = importlib.import_module("src.pubtrans.PtTTMatrixCrowding") - self.pt = pt_module.PublicTransportTravelTimeMatrixWithCrowding(self.gtfs_data_dir, self.pt_stat_f, - self.scenario_parameters, - self.routing_engine, self.zones) - elif pt_type == "PtCrowding": - pt_module = importlib.import_module("src.pubtrans.PtCrowding") - self.pt = pt_module.PublicTransportWithCrowding(self.gtfs_data_dir, self.pt_stat_f, self.scenario_parameters, - self.routing_engine, self.zones) - else: - raise IOError(f"Public transport module {pt_type} not defined for current simulation environment.") + # pt_type = self.scenario_parameters.get(G_PT_TYPE) + # self.gtfs_data_dir = self.dir_names.get(G_DIR_PT) + # if pt_type is None or self.gtfs_data_dir is None: + # self.pt = None + # elif pt_type == "PTMatrixCrowding": + # pt_module = importlib.import_module("src.pubtrans.PtTTMatrixCrowding") + # self.pt = pt_module.PublicTransportTravelTimeMatrixWithCrowding(self.gtfs_data_dir, self.pt_stat_f, + # self.scenario_parameters, + # self.routing_engine, self.zones) + # elif pt_type == "PtCrowding": + # pt_module = importlib.import_module("src.pubtrans.PtCrowding") + # self.pt = pt_module.PublicTransportWithCrowding(self.gtfs_data_dir, self.pt_stat_f, self.scenario_parameters, + # self.routing_engine, self.zones) + # else: + # raise IOError(f"Public transport module {pt_type} not defined for current simulation environment.") + self.pt_operator: PTControlBase = None + self._load_pt_operator() # attribute for demand, charging and zone module self.demand = None @@ -456,17 +459,36 @@ def _load_fleetctr_vehicles(self): def _load_broker_module(self): """ Loads the broker """ - - if self.scenario_parameters.get(G_BROKER_TYPE) is None: - LOG.info("No broker type specified, using default broker: BrokerBasic.") - op_broker_class_string = "BrokerBasic" - BrokerClass = load_broker_module(op_broker_class_string) + + broker_type: str = self.scenario_parameters.get(G_BROKER_TYPE, None) + if broker_type is None: + prt_msg: str = "No broker type specified, using default BrokerBasic" + LOG.info(prt_msg) + BrokerClass = load_broker_module("BrokerBasic") self.broker = BrokerClass(self.n_op, self.operators) + elif broker_type == "PTBrokerTPCS": + prt_msg: str = "PTBroker specified, using PTBrokerTPCS" + LOG.info(prt_msg) + if self.pt_operator is None: + raise ValueError("PT operator should be loaded before loading PTBroker.") + BrokerClass = load_broker_module("PTBrokerTPCS") + self.broker = BrokerClass(self.n_op, self.operators, self.pt_operator, self.demand, self.routing_engine, self.scenario_parameters) else: - LOG.info(f"Broker type specified: {self.scenario_parameters.get(G_BROKER_TYPE)}") - op_broker_class_string = self.scenario_parameters.get(G_BROKER_TYPE) - BrokerClass = load_broker_module(op_broker_class_string) - self.broker = BrokerClass(self.n_op, self.operators) + raise ValueError(f"Unknown broker type: {broker_type}!") + print('Broker: ' + prt_msg + '\n') + + def _load_pt_operator(self): + """ Loads the public transport operator """ + + pt_operator_type = self.scenario_parameters.get(G_PT_OPERATOR_TYPE, None) + gtfs_data_dir = self.dir_names.get(G_DIR_GTFS) + pt_operator_id = self.scenario_parameters.get(G_PT_OPERATOR_ID, -2) + if pt_operator_type is None or gtfs_data_dir is None: + return + else: + LOG.info(f"Public transport operator type specified: {pt_operator_type}") + PTControlClass = load_pt_control_module(pt_operator_type) + self.pt_operator = PTControlClass(gtfs_data_dir, pt_operator_id) @staticmethod def get_directory_dict(scenario_parameters, list_operator_dicts): @@ -491,9 +513,16 @@ def save_scenario_inputs(self): def evaluate(self): """Runs standard and simulation environment specific evaluations over simulation results.""" output_dir = self.dir_names[G_DIR_OUTPUT] - # standard evaluation - from src.evaluation.standard import standard_evaluation - standard_evaluation(output_dir) + evaluation_method = self.scenario_parameters.get(G_EVAL_METHOD, 'standard_evaluation') + if evaluation_method == 'standard_evaluation': + # standard evaluation + from src.evaluation.standard import standard_evaluation + standard_evaluation(output_dir) + elif evaluation_method == 'intermodal_evaluation': + from src.evaluation.intermodal import intermodal_evaluation + intermodal_evaluation(output_dir) + else: + raise ValueError(f"Unknown evaluation method {evaluation_method} specified!") self.add_evaluate() # def initialize_operators_and_vehicles(self): TODO I think this is depricated! @@ -684,20 +713,20 @@ def update_sim_state_fleets(self, last_time, next_time, force_update_plan=False) self.vehicle_update_order[opid_vid_tuple] = 0 else: self.vehicle_update_order[opid_vid_tuple] = 1 - for rid, boarding_time_and_pos in boarding_requests.items(): + for rid_struct, boarding_time_and_pos in boarding_requests.items(): # rid_struct is the actual key boarding_time, boarding_pos = boarding_time_and_pos - LOG.debug(f"rid {rid} boarding at {boarding_time} at pos {boarding_pos}") - self.demand.record_boarding(rid, vid, op_id, boarding_time, pu_pos=boarding_pos) - self.broker.acknowledge_user_boarding(op_id, rid, vid, boarding_time) - for rid, alighting_start_time_and_pos in dict_start_alighting.items(): + LOG.debug(f"rid {rid_struct} boarding at {boarding_time} at pos {boarding_pos}") + self.demand.record_boarding(rid_struct, vid, op_id, boarding_time, pu_pos=boarding_pos) + self.broker.acknowledge_user_boarding(op_id, rid_struct, vid, boarding_time) + for rid_struct, alighting_start_time_and_pos in dict_start_alighting.items(): # record user stats at beginning of alighting process alighting_start_time, alighting_pos = alighting_start_time_and_pos - LOG.debug(f"rid {rid} deboarding at {alighting_start_time} at pos {alighting_pos}") - self.demand.record_alighting_start(rid, vid, op_id, alighting_start_time, do_pos=alighting_pos) - for rid, alighting_end_time in alighting_requests.items(): + LOG.debug(f"rid {rid_struct} deboarding at {alighting_start_time} at pos {alighting_pos}") + self.demand.record_alighting_start(rid_struct, vid, op_id, alighting_start_time, do_pos=alighting_pos) + for rid_struct, alighting_end_time in alighting_requests.items(): # # record user stats at end of alighting process - self.demand.user_ends_alighting(rid, vid, op_id, alighting_end_time) - self.broker.acknowledge_user_alighting(op_id, rid, vid, alighting_end_time) + self.demand.user_ends_alighting(rid_struct, vid, op_id, alighting_end_time) + self.broker.acknowledge_user_alighting(op_id, rid_struct, vid, alighting_end_time) # send update to operator if len(boarding_requests) > 0 or len(dict_start_alighting) > 0: self.broker.receive_status_update(op_id, vid, next_time, passed_VRL, True) diff --git a/src/ImmediateDecisionsSimulation.py b/src/ImmediateDecisionsSimulation.py index 62ab061b..863e8531 100644 --- a/src/ImmediateDecisionsSimulation.py +++ b/src/ImmediateDecisionsSimulation.py @@ -88,7 +88,7 @@ def step(self, sim_time): # 3) for rid, rq_obj in list_undecided_travelers + list_new_traveler_rid_obj: self.broker.inform_request(rid, rq_obj, sim_time) - amod_offers = self.broker.collect_offers(rid) + amod_offers = self.broker.collect_offers(rid, sim_time) for op_id, amod_offer in amod_offers.items(): rq_obj.receive_offer(op_id, amod_offer, sim_time) self._rid_chooses_offer(rid, rq_obj, sim_time) diff --git a/src/broker/BrokerBase.py b/src/broker/BrokerBase.py index e04f74ca..266567ef 100644 --- a/src/broker/BrokerBase.py +++ b/src/broker/BrokerBase.py @@ -65,7 +65,7 @@ def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): pass @abstractmethod - def collect_offers(self, rid: int) -> tp.Dict[int, 'RequestBase']: + def collect_offers(self, rid: int, sim_time: int = None) -> tp.Dict[int, 'RequestBase']: """This method collects the offers from the operators. The return value is a list of tuples, where each tuple contains the operator id, the offer, and the simulation time. """ diff --git a/src/broker/BrokerBasic.py b/src/broker/BrokerBasic.py index 876d5491..79abd183 100644 --- a/src/broker/BrokerBasic.py +++ b/src/broker/BrokerBasic.py @@ -43,6 +43,7 @@ def __init__(self, n_amod_op: int, amod_operators: tp.List['FleetControlBase']): The general attributes for the broker are initialized. Args: + n_amod_op (int): number of AMoD operators amod_operators (tp.List['FleetControlBase']): list of AMoD operators """ super().__init__(n_amod_op, amod_operators) @@ -62,7 +63,7 @@ def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): LOG.debug(f"Request {rid}: To operator {op_id} ...") self.amod_operators[op_id].user_request(rq_obj, sim_time) - def collect_offers(self, rid: int) -> tp.Dict[int, 'RequestBase']: + def collect_offers(self, rid: int, sim_time: int = None) -> tp.Dict[int, 'RequestBase']: """This method collects the offers from the amod operators. The return value is a list of tuples, where each tuple contains the operator id, the offer, and the simulation time. """ diff --git a/src/broker/PTBrokerTPCS.py b/src/broker/PTBrokerTPCS.py new file mode 100644 index 00000000..a2ebeca5 --- /dev/null +++ b/src/broker/PTBrokerTPCS.py @@ -0,0 +1,945 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import logging +from datetime import datetime, timedelta +import typing as tp +import pandas as pd +# additional module imports (> requirements) +# ------------------------------------------ + + +# src imports +# ----------- +from src.broker.BrokerBasic import BrokerBasic +from src.simulation.Offers import IntermodalOffer +if tp.TYPE_CHECKING: + from src.fleetctrl.FleetControlBase import FleetControlBase + from src.fleetctrl.planning.PlanRequest import PlanRequest + from src.ptctrl.PTControlBase import PTControlBase + from src.demand.demand import Demand + from src.routing.road.NetworkBase import NetworkBase + from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest + from src.simulation.Offers import TravellerOffer, PTOffer + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) +LARGE_INT = 100000000 +BUFFER_SIZE = 100 + +INPUT_PARAMETERS_PTBroker = { + "doc" : "this class represents a broker platform which handles intermodal requests", + "inherit" : BrokerBasic, + "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTBrokerTPCS(BrokerBasic): + def __init__( + self, + n_amod_op: int, + amod_operators: tp.List['FleetControlBase'], + pt_operator: 'PTControlBase', + demand: 'Demand', + routing_engine: 'NetworkBase', + scenario_parameters: dict, + always_query_pt: bool = False, # TODO: make it a scenario parameter + ): + """ + The general attributes for the broker are initialized. + + Args: + n_amod_op (int): number of AMoD operators + amod_operators (tp.List['FleetControlBase']): list of AMoD operators + pt_operator (PTControlBase): PT operator + demand (Demand): demand object + routing_engine (NetworkBase): routing engine + scenario_parameters (dict): scenario parameters + always_query_pt (bool): if True, the pure PT offers are always requested + """ + super().__init__(n_amod_op, amod_operators) + + self.demand: Demand = demand + self.routing_engine: NetworkBase = routing_engine + self.pt_operator: PTControlBase = pt_operator + + self.pt_operator_id: int = self.pt_operator.pt_operator_id + self.scenario_parameters: dict = scenario_parameters + self.always_query_pt: bool = always_query_pt + + # set simulation start date for Raptor routing + self.sim_start_datetime: datetime = None + self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) + + # check whether only Phase 1 is used + self.use_phase_1_only: bool = self.scenario_parameters.get(G_BROKER_TPCS_USE_DEFAULT, False) + + # method for finding transfer stations + self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") + # read necessary files based on the transfer search method + if self.transfer_search_method == "closest": + # load the street-station transfers: used for finding closest station to a street node, or vice versa + try: + self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) + except FileNotFoundError: + LOG.error("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + raise FileNotFoundError("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + + + def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): + """This method informs the broker that a new request has been made. + Based on the request modal state, the broker will create the appropriate sub-requests + and inform the operators. + + Args: + rid (int): parent request id + rq_obj (RequestBase): request object + sim_time (int): simulation time + """ + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") + + if self.always_query_pt: + # 1. query the PT operator for the pure PT travel costs + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) + + # 2.1 pure AMoD request or PT request + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.2 AMoD as firstmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.3 AMoD as lastmile request + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.4 AMoD as firstlastmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: + """This method collects the offers from the operators. + + Args: + rid (int): parent request id + sim_time (int): simulation time + Returns: + tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators + """ + # get parent request modal state + parent_rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + offers: tp.Dict[int, TravellerOffer] = {} + LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") + + # 1. collect PT offers for multimodal requests + if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) + LOG.debug(f"pt offer {pt_offer}") + + if pt_offer is not None and not pt_offer.service_declined(): + offers[self.pt_operator_id] = pt_offer + # register the pt offer in the sub-request + self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) + + # 2.1 collect AMoD offers for MONOMODAL and PT requests + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) + + # 2.2 collect AMoD offers for FIRSTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + # 2.3 collect AMoD offers for LASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) + + # 2.4 collect AMoD offers for FIRSTLASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + return offers + + def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: + """This method informs the broker that the user has booked a trip. + """ + amod_confirmed_rids = [] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + # 1. Pure PT offer has been selected + if chosen_operator == self.pt_operator_id: + amod_confirmed_rids.append((rid, rq_obj)) + + # inform all AMoD operators that the request is cancelled + self.inform_user_leaving_system(rid, sim_time) + + # inform PT operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) + # 2. AMoD involved offer has been selected + else: + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int + operator.user_cancels_request(rid, sim_time) + else: + operator.user_confirms_booking(rid, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + # inform the pt operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{sub_trip_id}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + + if parent_modal_state == RQ_MODAL_STATE.LASTMILE: + previous_amod_operator_id = None # no previous amod operator + else: # firstmile or firstlastmile + previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) + else: + # inform the amod operator that the request is confirmed + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + for i, operator in enumerate(self.amod_operators): + if i != operator_id: + operator.user_cancels_request(amod_rid_struct, sim_time) + else: + operator.user_confirms_booking(amod_rid_struct, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + return amod_confirmed_rids + + def inform_user_leaving_system(self, rid: int, sim_time: int): + """This method informs the broker that the user is leaving the system. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(rid, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(fm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(lm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) + operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): + """This method informs the operators that the waiting requests have been cancelled. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if chosen_operator == self.pt_operator_id: + return + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) + + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + continue + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + operator_id = int(operator_id) + self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): + """This method processes the new monomodal request. + + Args: + rid (int): the request id + rq_obj ('RequestBase'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + for op_id in range(self.n_amod_op): + LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(rq_obj, sim_time) + + def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): + """This method processes the new firstmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] + # create sub-request for PT + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") + # estimate the earliest start time of the pt sub-request + fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, rq_obj.get_destination_node(), fm_est_pt_mod, parent_modal_state, op_id) + + def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): + """This method processes the new lastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # create sub-request for PT + lm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_PT.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state) + + if lm_pt_arrival is not None: + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_AMOD.value, transfer_street_node, rq_obj.get_destination_node(), lm_pt_arrival, parent_modal_state, op_id, sim_time) + else: + LOG.info(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.LM_PT.value}, so the lastmile AMoD sub-request will not be created.") + + def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): + """This method processes the new firstlastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + # firstmile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] + # create sub-request for PT + # estimate the dropoff time of the amod sub-request + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") + # estimate the earliest start time of the pt sub-request + flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0,transfer_street_node_1, flm_est_pt_mod,parent_modal_state,op_id) + + # create sub-request for the same AMoD operator + if flm_pt_arrival is None: + raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") + else: + # last mile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) + + def _inform_amod_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int + ): + """ + This method informs the AMoD operators that a new sub-request has been made. + + Args: + rq_obj ('RequestBase'): the parent request object + sub_trip_id (int): the sub-trip id + leg_o_node (int): the origin node of the sub-request + leg_d_node (int): the destination node of the sub-request + leg_start_time (int): the start time of the sub-request + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) + + def _inform_pt_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None + ) -> tp.Optional[int]: + """ + This method informs the PT operator that a new sub-request has been made. + + Args: + rq_obj (RequestBase): the parent request object + sub_trip_id (int): the sub_trip id + leg_o_node (int): the origin street node of the sub-request + leg_d_node (int): the destination street node of the sub-request + leg_start_time (int): the start time [s] of the sub-request at the origin street node + parent_modal_state (RQ_MODAL_STATE): the parent modal state + firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests + Returns: + t_d_node_arrival (tp.Optional[int]): + the pt arrival time of the sub-request at the destination street node + or None if the pt travel costs are not available + """ + pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") + + costs_info = self._query_street_node_pt_travel_costs_1to1( + pt_sub_rq_obj.get_origin_node(), + pt_sub_rq_obj.get_destination_node(), + pt_sub_rq_obj.earliest_start_time, + pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest + ) + + if costs_info is not None: + source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") + else: + source_pt_station_id = None + t_source_walk = None + target_pt_station_id = None + t_target_walk = None + pt_journey_plan_dict = None + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") + + pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() + + self.pt_operator.create_and_record_pt_offer_db( + rid_struct = pt_rid_struct, + operator_id = self.pt_operator_id, + source_station_id = source_pt_station_id, + target_station_id = target_pt_station_id, + source_walking_time = t_source_walk, + target_walking_time = t_target_walk, + pt_journey_plan_dict = pt_journey_plan_dict, + firstmile_amod_operator_id = firstmile_amod_operator_id, + ) + if pt_journey_plan_dict is not None: + t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer + return t_d_node_arrival + else: + return None + + def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of monomodal offers. + + Args: + rid (int): the request id + parent_modal_state (RQ_MODAL_STATE): the parent modal state + offers (tp.Dict[int, TravellerOffer]): the current offers dictionary + Returns: + tp.Dict[int, TravellerOffer]: the updated offers dictionary + """ + for amod_op_id in range(self.n_amod_op): + amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) + LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") + if amod_offer is not None and not amod_offer.service_declined(): + offers[amod_op_id] = amod_offer + return offers + + def _process_collect_firstmile_offers_tpcs_phase1( + self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. + """ + # collect all offers + fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) + LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") + + fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) + LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") + + if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") + return None, None + + if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): + LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") + return None, fm_amod_offer_p1 + + if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + return intermodal_offer_p1, fm_amod_offer_p1 + + def _process_collect_firstmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstmile offers using TPCS approach. + """ + # get rid struct for all sections + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" + + for amod_op_id in range(self.n_amod_op): + # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! + # 1. Phase 1 + intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + # No amod offer in phase 1, skip to next amod operator + if fm_amod_offer_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.1 re-query the pt offer + # 2.1.1 get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # 2.1.2 determine the earliest start time of the pt sub-request + fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) + # 2.1.3 create the pt sub-request and get the pt arrival time + fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FM_PT.value, + transfer_street_node, + parent_rq_obj.get_destination_node(), + fm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) + if fm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.2 create intermodal offer + sub_trip_offers: tp.Dict[int, TravellerOffer] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of lastmile offers. + """ + # get lastmile pt offer + lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" + lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) + LOG.debug(f"Collecting lm_pt offer for request {lm_pt_rid_struct} from PT operator {self.pt_operator_id}: {lm_pt_offer}") + + if lm_pt_offer is not None and not lm_pt_offer.service_declined(): + # register the pt offer in the sub-request + self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for amod_op_id in range(self.n_amod_op): + # get lastmile amod offer + lm_amod_offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) + LOG.debug(f"Collecting lm_amod offer for request {lm_amod_rid_struct} from operator {amod_op_id}: {lm_amod_offer}") + + if lm_amod_offer is not None and not lm_amod_offer.service_declined(): + # register the amod offer in the sub-request + self.demand[lm_amod_rid_struct].receive_offer(amod_op_id, lm_amod_offer, None) + + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.LM_PT.value] = lm_pt_offer + sub_trip_offers[RQ_SUB_TRIP_ID.LM_AMOD.value] = lm_amod_offer + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + offers[intermodal_offer.operator_id] = intermodal_offer + else: + LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}") + else: + LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") + return offers + + def _process_collect_firstlastmile_offers_tpcs_phase1( + self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. + """ + flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) + LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") + + flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) + LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") + + flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) + LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") + + if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") + return None, None + + if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + else: + LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") + intermodal_offer_p1 = None + return intermodal_offer_p1, flm_amod_offer_0_p1 + + def _process_collect_firstlastmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstlastmile offers using 3-phases approach. + """ + # get rid struct for all sections + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + + for amod_op_id in range(self.n_amod_op): + # 1. Phase 1 + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + # No firstmile amod offer in phase 1, skip to next amod operator + if flm_amod_offer_0_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.0 cancel lastmile amod sub-request + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + + # 2.2 re-query the pt offer + # 2.2.1 get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # 2.2.2 determine the earliest start time of the pt sub-request + flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) + + # 2.2.3 create the pt sub-request and get the pt arrival time + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_PT.value, + transfer_street_node_0, + transfer_street_node_1, + flm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) + if flm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.3 re-query the lastmile amod offer + self._inform_amod_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_AMOD_1.value, + transfer_street_node_1, + parent_rq_obj.get_destination_node(), + flm_pt_arrival, + parent_modal_state, + amod_op_id, + sim_time, + ) + flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) + if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.4 create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _set_sim_start_datetime(self, sim_start_date: str): + """This method sets the simulation start date. + Converts the date string (format YYYYMMDD) to a datetime object. + + Args: + sim_start_date (str): the simulation start date in format YYYYMMDD + """ + if sim_start_date is None: + LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + + if type(sim_start_date) is not str: + sim_start_date = str(int(sim_start_date)) + self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") + + def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: + """This method returns the current datetime based on the simulation time in seconds. + """ + return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) + + def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific street station transfers file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The transfer data between the street nodes and the PT stations. + """ + dtypes = { + 'node_id': 'int', + 'closest_station_id': 'str', + 'street_station_transfer_time': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) + + def _query_street_node_pt_travel_costs_1to1( + self, o_node: int, d_node: int, est: int, + max_transfers: int = 999, detailed: bool = False + ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + """This method queries the pt travel costs between two street nodes at a given datetime. + The pt station ids will be the closest pt station ids to the street nodes. + + Args: + o_node (int): The origin street node id. + d_node (int): The destination street node id. + est (int): The earliest start time of the request at the origin street node in seconds. + max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. + detailed (bool): Whether to return detailed journey information. Defaults to False. + Returns: + tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + Returns a tuple containing: + (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) + if a public transport journey plan is found. + Returns None if no public transport journey plan is available. + """ + # find pt transfer stations + source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") + target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") + + source_station_departure_seconds: int = est + t_source_walk + source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) + LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( + source_pt_station_id, target_pt_station_id, + source_station_departure_datetime, + max_transfers, detailed, + ) + if pt_journey_plan_dict is None: + return None + else: + return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict + + def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: + """This method finds the transfer possibility between pt station and street node. + + Args: + node_id (tp.Union[int, str]): The street node id. + direction (str): "pt2street" or "street2pt" + Returns: + tp.Tuple[str, int]: The transfer node id and the walking time. + """ + if self.transfer_search_method == "closest": # closest station or street node + if direction == "street2pt": # find closest pt station from street node + street_node_id: int = int(node_id) + # TODO: allow multiple closest stations? + street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] + if street_station_transfer.empty: + raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") + closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] + walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] + return closest_station_id, walking_time + elif direction == "pt2street": # find closest street node from pt station + pt_station_id: str = str(node_id) + street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] + if street_station_transfers.empty: + raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") + # find the record with the minimum street_station_transfer_time + # TODO: if multiple exist, return all? + min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] + closest_street_node_id: int = min_transfer["node_id"] + walking_time: int = min_transfer["street_station_transfer_time"] + return closest_street_node_id, walking_time + else: + raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") + else: + LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") + raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") + + def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest', estimation_type: str = "latest") -> tp.Optional[int]: + """This method estimates the dropoff time of an amod sub-request. + + Args: + amod_op_id (int): the id of the amod operator + sub_rq_obj (BasicIntermodalRequest): the sub-request object + estimation_type (str): the type of the estimation + Returns: + int: the dropoff time of the sub-request + """ + # get amod dropoff time range + # TODO: add estimation type key in global variables + if estimation_type == "latest": + sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) + return sub_prq_obj.t_do_latest + else: + raise NotImplementedError(f"PTBrokerTPCS: AMod dropoff estimation type not implemented: {estimation_type}") + + def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: + """This method determines the earliest start time for the pt sub-request. + """ + t_est_pt_mod: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + self.amod_operators[amod_op_id].const_bt + return t_est_pt_mod + + def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: 'TravellerOffer', pt_waiting_time: int, old_t_do_latest: int) -> tp.Optional[int]: + """This method determines the latest dropoff time for the amod sub-request. + """ + t_do_latest: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + pt_waiting_time + # add latest dropoff time constraint check + if t_do_latest > old_t_do_latest: + t_do_latest = old_t_do_latest + return t_do_latest + + def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': + """This method merges the amod and pt offers into an intermodal offer. + """ + return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) + + def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: + """This method compares two intermodal offers based on availability and arrival time at destination node. + If offer_1 and offer_2 are both None, it returns 0. + If offer_1 is None and offer_2 is not None, it returns 2. + If offer_1 is not None and offer_2 is None, it returns 1. + If offer_1 is better than offer_2, it returns 1. + If offer_1 is worse than offer_2, it returns 2. + If offer_1 and offer_2 are equally good, it returns 2. + """ + if offer_1 is None and offer_2 is None: + return 0 + elif offer_1 is None and offer_2 is not None: + return 2 + elif offer_1 is not None and offer_2 is None: + return 1 + else: + duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) + duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) + if duration_p1 <= duration_p2: + return 1 + elif duration_p1 > duration_p2: + return 2 + else: + raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 6efd3b88..344f2339 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -17,6 +17,9 @@ # ----------- from src.misc.functions import PiecewiseContinuousLinearFunction from src.routing.road.NetworkBase import return_position_str +if tp.TYPE_CHECKING: + from src.routing.road.NetworkBase import NetworkBase + # -------------------------------------------------------------------------------------------------------------------- # # global variables # ---------------- @@ -53,6 +56,7 @@ class RequestBase(metaclass=ABCMeta): def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parameters): # input self.rid = int(rq_row.get(G_RQ_ID, rq_row.name)) # request id is index of dataframe + self.subtrip_id: int = None self.sub_rid_struct = None self.is_parcel = False # requests are usually persons self.rq_time = rq_row[G_RQ_TIME] - rq_row[G_RQ_TIME] % simulation_time_step @@ -91,7 +95,7 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.direct_route_travel_time = None self.direct_route_travel_distance = None # - self.modal_state = G_RQ_STATE_MONOMODAL # mono-modal trip by default + self.modal_state = RQ_MODAL_STATE.MONOMODAL # mono-modal trip by default def get_rid(self): return self.rid @@ -113,6 +117,9 @@ def get_origin_node(self): def get_destination_node(self): return self.d_node + + def get_modal_state(self) -> RQ_MODAL_STATE: + return self.modal_state def return_offer(self, op_id): return self.offer.get(op_id) @@ -214,17 +221,25 @@ def user_leaves_vehicle(self, simulation_time, do_pos, t_egress): self.do_pos = do_pos self.t_egress = t_egress - def create_SubTripRequest(self, subtrip_id, mod_o_node=None, mod_d_node=None, mod_start_time=None, modal_state = None): + def create_SubTripRequest( + self, + subtrip_id: int, + leg_o_node: tp.Optional[int] = None, + leg_d_node: tp.Optional[int] = None, + leg_start_time: tp.Optional[int] = None, + modal_state: tp.Optional[RQ_MODAL_STATE] = None, + routing_engine : tp.Optional['NetworkBase'] = None, + ): """ this function creates subtriprequests (i.e. a customer sends multiple requests) based on a attributes of itself. different subtrip-customers can vary in start and target node, earlest start time and modal_state (monomodal, firstmile, lastmile, firstlastmile) :param subtrip_id: identifier of the subtrip (this is not the customer id!) :type subtrip_id: int - :param mod_o_node: new origin node index of subtrip - :type mod_o_node: int - :param mod_d_node: new destination node index of subtrip - :type mod_d_node: int - :param mod_start_time: new earliest start time of the trip - :type mod_start_time: int + :param leg_o_node: new origin node index of subtrip + :type leg_o_node: int + :param leg_d_node: new destination node index of subtrip + :type leg_d_node: int + :param leg_start_time: new earliest start time of the trip + :type leg_start_time: int :param modal_state: indicator of modality (indicator if monomodal, first, last or firstlast mile trip) :type modal_state: int in G_RQ_STATE_MONOMODAL, G_RQ_STATE_FIRSTMILE, G_RQ_STATE_LASTMILE, G_RQ_STATE_FIRSTLASTMILE (globals) :return: new traveler with specified attributes @@ -233,14 +248,22 @@ def create_SubTripRequest(self, subtrip_id, mod_o_node=None, mod_d_node=None, mo sub_rq_obj = deepcopy(self) old_rid = sub_rq_obj.get_rid() sub_rq_obj.sub_rid_struct = f"{old_rid}_{subtrip_id}" - if mod_o_node is not None: - sub_rq_obj.o_node = mod_o_node - if mod_d_node is not None: - sub_rq_obj.d_node = mod_d_node - if mod_start_time is not None: - sub_rq_obj.earliest_start_time = mod_start_time + sub_rq_obj.subtrip_id = subtrip_id + if leg_o_node is not None: + sub_rq_obj.o_node = leg_o_node + if leg_d_node is not None: + sub_rq_obj.d_node = leg_d_node + if leg_start_time is not None: + sub_rq_obj.earliest_start_time = leg_start_time if modal_state is not None: sub_rq_obj.modal_state = modal_state + # update travel times and distances + if routing_engine is not None: + sub_rq_obj.o_pos = routing_engine.return_node_position(leg_o_node) + sub_rq_obj.d_pos = routing_engine.return_node_position(leg_d_node) + _, tt, dis = routing_engine.return_travel_costs_1to1(sub_rq_obj.o_pos, sub_rq_obj.d_pos) + sub_rq_obj.direct_route_travel_distance = dis + sub_rq_obj.direct_route_travel_time = tt return sub_rq_obj def set_direct_route_travel_infos(self, routing_engine): @@ -744,8 +767,8 @@ class BasicIntermodalRequest(RequestBase): def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parameters): super().__init__(rq_row, routing_engine, simulation_time_step, scenario_parameters) # intermodal attributes - modal_state_int: int = rq_row.get(G_RQ_MODAL_STATE, RQ_MODAL_STATE.MONOMODAL.value) # mono-modal trip by default - self.modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE(modal_state_int) + self.modal_state_int: int = rq_row.get(G_RQ_MODAL_STATE_VALUE, RQ_MODAL_STATE.MONOMODAL.value) # mono-modal trip by default + self.modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE(self.modal_state_int) self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit @@ -810,6 +833,7 @@ def record_data(self): record_dict[G_RQ_DO] = self.do_time record_dict[G_RQ_FARE] = self.fare record_dict[G_RQ_MODAL_STATE] = self.modal_state + record_dict[G_RQ_MODAL_STATE_VALUE] = self.modal_state_int return self._add_record(record_dict) def choose_offer(self, scenario_parameters, simulation_time): diff --git a/src/demand/demand.py b/src/demand/demand.py index b9182f5d..c7cfd231 100644 --- a/src/demand/demand.py +++ b/src/demand/demand.py @@ -7,12 +7,15 @@ # ------------------------------------------ import numpy as np import pandas as pd +import typing as tp pd.options.mode.chained_assignment = None # src imports # ----------- from src.misc.distributions import draw_from_distribution_dict from src.misc.init_modules import load_request_module +if tp.TYPE_CHECKING: + from src.demand.TravelerModels import RequestBase # global variables # ---------------- @@ -216,6 +219,42 @@ def get_new_travelers(self, simulation_time, *, since=None): list_new_traveler_rid_obj.append((rid, rq)) LOG.debug(f"{len(list_new_traveler_rid_obj)} new travelers join the simulation at time {simulation_time}.") return list_new_traveler_rid_obj + + def create_sub_requests( + self, + rq_obj: 'RequestBase', + subtrip_id: int, + leg_o_node: int, + leg_d_node: int, + leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, + ) -> 'RequestBase': + """This method creates the sub-requests for the given request. + The new sub-request ids are created by the broker class for the intermodal request. + + Args: + rq_obj (RequestBase): the parent request object + subtrip_id (int): the subtrip id + mod_o_node (int): the origin node of the sub-request + mod_d_node (int): the destination node of the sub-request + mod_start_time (int): the start time of the sub-request + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # TODO: Check if the new sub-request ids should be added to the self.undecided_rq or somewhere else + + sub_rq_obj: 'RequestBase' = rq_obj.create_SubTripRequest( + subtrip_id, + leg_o_node, + leg_d_node, + leg_start_time, + parent_modal_state, + self.routing_engine + ) + # Use the sub_rid_struct as the key for the sub-request: rid_struct = rid_parent + "_" + subtrip_id + sub_rid_struct: str = sub_rq_obj.get_rid_struct() + self.rq_db[sub_rid_struct] = sub_rq_obj + LOG.debug(f"Created sub-request {sub_rid_struct} for request {rq_obj.get_rid_struct()}") + return sub_rq_obj def get_undecided_travelers(self, simulation_time): """This method returns the list of currently undecided requests. @@ -292,7 +331,7 @@ class SlaveDemand(Demand): """This class can be used when request are added from an external demand module.""" rq_class = load_request_module("SlaveRequest") rq_parcel_class = load_request_module("SlaveParcelRequest") - def add_request(self, rq_info_dict, offer_id, routing_engine, sim_time, modal_state = G_RQ_STATE_MONOMODAL): + def add_request(self, rq_info_dict, offer_id, routing_engine, sim_time, modal_state = RQ_MODAL_STATE.MONOMODAL): """ this function is used to add a new (person) request to the demand class :param rq_info_dict: dictionary with all information regarding the request input :param offer_id: used if there are different subrequests (TODO make optional? needed for moia) @@ -304,7 +343,7 @@ def add_request(self, rq_info_dict, offer_id, routing_engine, sim_time, modal_st rq_info_dict[G_RQ_TIME] = sim_time if rq_info_dict.get(G_RQ_LDT) is None: rq_info_dict[G_RQ_LDT] = 0 - if modal_state == G_RQ_STATE_MONOMODAL: + if modal_state == RQ_MODAL_STATE.MONOMODAL: # original request rq_obj = self.rq_class(rq_info_dict, routing_engine, 1, self.scenario_parameters) rq_obj.set_direct_route_travel_infos(routing_engine) diff --git a/src/evaluation/intermodal.py b/src/evaluation/intermodal.py new file mode 100644 index 00000000..791a96bd --- /dev/null +++ b/src/evaluation/intermodal.py @@ -0,0 +1,204 @@ +import pandas as pd +import numpy as np +import os +import re +import sys +import glob + +MAIN_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +sys.path.append(MAIN_DIR) +from src.evaluation.standard import read_op_output_file, read_user_output_file, create_vehicle_type_db +from src.misc.globals import * + +DEFAULT_AMOD_OP_ID = 0 + +EURO_PER_TON_OF_CO2 = 145 # from BVWP2030 Modulhandbuch (page 113) +EMISSION_CPG = 145 * 100 / 1000**2 +ENERGY_EMISSIONS = 112 # g/kWh from https://www.swm.de/dam/swm/dokumente/geschaeftskunden/broschuere-strom-erdgas-gk.pdf +PV_G_CO2_KM = 130 # g/km from https://www.ris-muenchen.de/RII/RII/DOK/ANTRAG/2337762.pdf with 60:38 benzin vs diesel + + +# TODO: extend evaluation with more KPIs +def intermodal_evaluation(output_dir, evaluation_start_time = None, evaluation_end_time = None, print_comments=False, dir_names_in = {}): + """This function runs a standard evaluation over a scenario output directory for intermodal scenarios. + Currently, only few KPIs are implemented and only for scenarios with one AMoD operator. + + :param output_dir: scenario output directory + :param start_time: start time of evaluation interval in s (if None, then evaluation of all data from sim start) + :param end_time: end time of evaluation interval in s (if None, then evaluation of all data until sim end) + :param print_comments: print some comments about status in between + """ + if not os.path.isdir(output_dir): + raise IOError(f"Could not find result directory {output_dir}!") + + scenario_parameters, list_operator_attributes, _ = load_scenario_inputs(output_dir) + dir_names = get_directory_dict(scenario_parameters, list_operator_attributes, abs_fleetpy_dir=MAIN_DIR) + if dir_names_in: + dir_names = dir_names_in + + # evaluation interval + if evaluation_start_time is None and scenario_parameters.get(G_EVAL_INT_START) is not None: + evaluation_start_time = int(scenario_parameters[G_EVAL_INT_START]) + if evaluation_end_time is None and scenario_parameters.get(G_EVAL_INT_END) is not None: + evaluation_end_time = int(scenario_parameters[G_EVAL_INT_END]) + + # vehicle type data + veh_type_db = create_vehicle_type_db(dir_names[G_DIR_VEH]) + veh_type_stats = pd.read_csv(os.path.join(output_dir, "2_vehicle_types.csv")) + + # user stats + if print_comments: + print(f"Evaluating {scenario_parameters[G_SCENARIO_NAME]}\nReading user stats ...") + + user_stats = read_user_output_file(output_dir, evaluation_start_time=evaluation_start_time, evaluation_end_time=evaluation_end_time) + parent_user_stats = user_stats[user_stats[G_RQ_IS_PARENT_REQUEST] == True].copy() + + if print_comments: + print(f"\t shape of user stats: {user_stats.shape}") + print(f"\t shape of parent user stats: {parent_user_stats.shape}") + + result_dict_list = [] + operator_names = [] + + result_dict = {} + + # ---------------------------- User stats -------------------------------- + num_parent_requests = parent_user_stats.shape[0] + served_parent_requests = parent_user_stats[parent_user_stats[G_RQ_CHOSEN_OP_ID].notna()].copy() + num_served_parent_requests = served_parent_requests.shape[0] + + # Average service rate + average_service_rate = num_served_parent_requests / num_parent_requests if num_parent_requests > 0 else 0.0 + result_dict["average_service_rate"] = average_service_rate + + # Average FLM request service rate + flm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.FIRSTLASTMILE.value].copy() + num_flm_parent_requests = flm_parent_requests.shape[0] + served_flm_parent_requests = flm_parent_requests[flm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() + num_served_flm_parent_requests = served_flm_parent_requests.shape[0] + average_flm_service_rate = num_served_flm_parent_requests / num_flm_parent_requests if num_flm_parent_requests > 0 else 0.0 + result_dict["average_flm_service_rate"] = average_flm_service_rate + + # Average FM request service rate + fm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.FIRSTMILE.value].copy() + num_fm_parent_requests = fm_parent_requests.shape[0] + served_fm_parent_requests = fm_parent_requests[fm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() + num_served_fm_parent_requests = served_fm_parent_requests.shape[0] + average_fm_service_rate = num_served_fm_parent_requests / num_fm_parent_requests if num_fm_parent_requests > 0 else 0.0 + result_dict["average_fm_service_rate"] = average_fm_service_rate + + # Average LM request service rate + lm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.LASTMILE.value].copy() + num_lm_parent_requests = lm_parent_requests.shape[0] + served_lm_parent_requests = lm_parent_requests[lm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() + num_served_lm_parent_requests = served_lm_parent_requests.shape[0] + average_lm_service_rate = num_served_lm_parent_requests / num_lm_parent_requests if num_lm_parent_requests > 0 else 0.0 + result_dict["average_lm_service_rate"] = average_lm_service_rate + + # Average AMoD service rate + amod_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.MONOMODAL.value].copy() + num_amod_parent_requests = amod_parent_requests.shape[0] + served_amod_parent_requests = amod_parent_requests[amod_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() + num_served_amod_parent_requests = served_amod_parent_requests.shape[0] + average_amod_service_rate = num_served_amod_parent_requests / num_amod_parent_requests if num_amod_parent_requests > 0 else 0.0 + result_dict["average_amod_service_rate"] = average_amod_service_rate + + # ---------------------------- AMoD operator -------------------------------- + amod_op_id = DEFAULT_AMOD_OP_ID + + if print_comments: + print(f"Reading AMoD operator {amod_op_id} vehicle stats ...") + try: + op_vehicle_df = read_op_output_file(output_dir, op_id=amod_op_id, evaluation_start_time=evaluation_start_time, evaluation_end_time=evaluation_end_time) + except FileNotFoundError: + op_vehicle_df = pd.DataFrame([], columns=[G_V_OP_ID, G_V_VID, G_VR_STATUS, G_VR_LOCKED, G_VR_LEG_START_TIME, + G_VR_LEG_END_TIME, G_VR_LEG_START_POS, G_VR_LEG_END_POS, + G_VR_LEG_DISTANCE, G_VR_LEG_START_SOC, G_VR_LEG_END_SOC, + G_VR_TOLL, G_VR_OB_RID, G_VR_BOARDING_RID, G_VR_ALIGHTING_RID, + G_VR_NODE_LIST, G_VR_REPLAY_ROUTE]) + + n_vehicles = veh_type_stats[veh_type_stats[G_V_OP_ID]==amod_op_id].shape[0] + sim_end_time = scenario_parameters["end_time"] + simulation_time = scenario_parameters["end_time"] - scenario_parameters["start_time"] + + op_vehicle_df["VRL_end_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_END_TIME], sim_end_time) + op_vehicle_df["VRL_start_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_START_TIME], sim_end_time) + utilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] != VRL_STATES.OUT_OF_SERVICE.display_name) & (op_vehicle_df["status"] != VRL_STATES.CHARGING.display_name)] + utilization_time = utilized_veh_df["VRL_end_sim_end_time"].sum() - utilized_veh_df["VRL_start_sim_end_time"].sum() + unutilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] == VRL_STATES.OUT_OF_SERVICE.display_name) | (op_vehicle_df["status"] == VRL_STATES.CHARGING.display_name)] + unutilized_time = unutilized_veh_df["VRL_end_sim_end_time"].sum() - unutilized_veh_df["VRL_start_sim_end_time"].sum() + + op_fleet_utilization = 100 * (utilization_time/(n_vehicles * simulation_time - unutilized_time)) + op_total_km = op_vehicle_df[G_VR_LEG_DISTANCE].sum()/1000.0 + + # by vehicle stats + # ---------------- + op_veh_types = veh_type_stats[veh_type_stats[G_V_OP_ID] == amod_op_id] + op_veh_types.set_index(G_V_VID, inplace=True) + all_vid_dict = {} + for vid, vid_vtype_row in op_veh_types.iterrows(): + vtype_data = veh_type_db[vid_vtype_row[G_V_TYPE]] + op_vid_vehicle_df = op_vehicle_df[op_vehicle_df[G_V_VID] == vid] + veh_km = op_vid_vehicle_df[G_VR_LEG_DISTANCE].sum() / 1000 + veh_kWh = veh_km * vtype_data[G_VTYPE_BATTERY_SIZE] / vtype_data[G_VTYPE_RANGE] + co2_per_kWh = scenario_parameters.get(G_ENERGY_EMISSIONS, ENERGY_EMISSIONS) + if co2_per_kWh is None: + co2_per_kWh = ENERGY_EMISSIONS + veh_co2 = co2_per_kWh * veh_kWh + veh_fix_costs = np.rint(scenario_parameters.get(G_OP_SHARE_FC, 1.0) * vtype_data[G_VTYPE_FIX_COST]) + veh_var_costs = np.rint(vtype_data[G_VTYPE_DIST_COST] * veh_km) + # TODO # after ISTTT: idle times + all_vid_dict[vid] = {"type":vtype_data[G_VTYPE_NAME], "total km":veh_km, "total kWh": veh_kWh, + "total CO2 [g]": veh_co2, "fix costs": veh_fix_costs, + "total variable costs": veh_var_costs} + all_vid_df = pd.DataFrame.from_dict(all_vid_dict, orient="index") + try: + op_co2 = all_vid_df["total CO2 [g]"].sum() + op_ext_em_costs = np.rint(EMISSION_CPG * op_co2) + op_fix_costs = all_vid_df["fix costs"].sum() + op_var_costs = all_vid_df["total variable costs"].sum() + except: + op_co2 = 0 + op_ext_em_costs = 0 + op_fix_costs = 0 + op_var_costs = 0 + + def weight_ob_rq(entries): + if pd.isnull(entries[G_VR_OB_RID]): + return 0.0 + else: + number_ob_rq = len(str(entries[G_VR_OB_RID]).split(";")) + return number_ob_rq * entries[G_VR_LEG_DISTANCE] + + def weight_ob_pax(entries): + try: + return entries[G_VR_NR_PAX] * entries[G_VR_LEG_DISTANCE] + except: + return 0.0 + + op_vehicle_df["weighted_ob_rq"] = op_vehicle_df.apply(weight_ob_rq, axis = 1) + op_vehicle_df["weighted_ob_pax"] = op_vehicle_df.apply(weight_ob_pax, axis=1) + op_distance_avg_rq = op_vehicle_df["weighted_ob_rq"].sum() / op_vehicle_df[G_VR_LEG_DISTANCE].sum() + op_distance_avg_occupancy = op_vehicle_df["weighted_ob_pax"].sum() / op_vehicle_df[G_VR_LEG_DISTANCE].sum() + + result_dict["fleet_utilization_rate"] = op_fleet_utilization + result_dict["distance_avg_occupancy"] = op_distance_avg_occupancy + result_dict["total_km_driven"] = op_total_km + result_dict["average_km_driven"] = op_total_km / n_vehicles + result_dict["total_amod_cost"] = op_fix_costs + op_var_costs + result_dict["average_amod_cost"] = (op_fix_costs + op_var_costs) / n_vehicles + result_dict['total_amod_fix_cost'] = op_fix_costs + result_dict['total_amod_variable_cost'] = op_var_costs + result_dict["total_co2_emissions_g"] = op_co2 + result_dict["total_external_emission_costs"] = op_ext_em_costs + + op_name = f"MoD_{amod_op_id}" + + result_dict_list.append(result_dict) + operator_names.append(op_name) + + result_df = pd.DataFrame(result_dict_list, index=operator_names) + result_df = result_df.transpose() + result_df.to_csv(os.path.join(output_dir, "standard_eval.csv")) + + return result_df \ No newline at end of file diff --git a/src/fleetctrl/PoolingIRSOnly.py b/src/fleetctrl/PoolingIRSOnly.py index 0527c0a1..4789d795 100644 --- a/src/fleetctrl/PoolingIRSOnly.py +++ b/src/fleetctrl/PoolingIRSOnly.py @@ -62,6 +62,8 @@ def __init__(self, op_id, operator_attributes, list_vehicles, routing_engine, zo self.tmp_assignment = {} # rid -> VehiclePlan self._init_dynamic_fleetcontrol_output_key(G_FCTRL_CT_RQU) + self.flm_excluded_vid = {} # flm rid -> [vid] + def receive_status_update(self, vid, simulation_time, list_finished_VRL, force_update=True): """This method can be used to update plans and trigger processes whenever a simulation vehicle finished some VehicleRouteLegs. @@ -107,6 +109,13 @@ def user_request(self, rq, sim_time): rid_struct = rq.get_rid_struct() self.rq_dict[rid_struct] = prq + parent_rid: int = rq.get_rid() + # get excluded vids for flm request + if rid_struct == f"{parent_rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}": + excluded_vid: list[int] = self.flm_excluded_vid.get(parent_rid, []) + else: + excluded_vid = [] + if prq.o_pos == prq.d_pos: LOG.debug(f"automatic decline for rid {rid_struct}!") self._create_rejection(prq, sim_time) @@ -115,14 +124,34 @@ def user_request(self, rq, sim_time): o_pos, t_pu_earliest, t_pu_latest = prq.get_o_stop_info() if t_pu_earliest - sim_time > self.opt_horizon: self.reservation_module.add_reservation_request(prq, sim_time) - offer = self.reservation_module.return_immediate_reservation_offer(prq.get_rid_struct(), sim_time) + offer = self.reservation_module.return_immediate_reservation_offer(prq.get_rid_struct(), sim_time, excluded_vid=excluded_vid) + + # # record excluded vids for flm request + # if rq_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + # assigned_vid: int = self.reservation_module.rid_to_assigned_vid.get(rid_struct) + # if assigned_vid is not None: + # if parent_rid in self.flm_excluded_vid: + # self.flm_excluded_vid[parent_rid].append(assigned_vid) + # else: + # self.flm_excluded_vid[parent_rid] = [assigned_vid] + # print(f"excluded vid {assigned_vid} for request {rid_struct}") + LOG.debug(f"reservation offer for rid {rid_struct} : {offer}") else: - list_tuples = insertion_with_heuristics(sim_time, prq, self, force_feasible_assignment=True) + list_tuples = insertion_with_heuristics(sim_time, prq, self, force_feasible_assignment=True, excluded_vid=excluded_vid) if len(list_tuples) > 0: (vid, vehplan, delta_cfv) = min(list_tuples, key=lambda x:x[2]) self.tmp_assignment[rid_struct] = vehplan offer = self._create_user_offer(prq, sim_time, vehplan) + + if rid_struct == f"{parent_rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}": + assigned_vid: int = vehplan.vid + if parent_rid in self.flm_excluded_vid: + self.flm_excluded_vid[parent_rid].append(assigned_vid) + else: + self.flm_excluded_vid[parent_rid] = [assigned_vid] + LOG.debug(f"FLM: assigned vid {assigned_vid} to fisrt mile amod sub-request {rid_struct}, excluding it for the last mile sub-request {parent_rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}") + LOG.debug(f"new offer for rid {rid_struct} : {offer}") else: LOG.debug(f"rejection for rid {rid_struct}") diff --git a/src/fleetctrl/planning/PlanRequest.py b/src/fleetctrl/planning/PlanRequest.py index 76a38715..2e253f0e 100644 --- a/src/fleetctrl/planning/PlanRequest.py +++ b/src/fleetctrl/planning/PlanRequest.py @@ -207,6 +207,11 @@ def set_new_pickup_time_constraint(self, new_latest_pu_time : int, new_earliest_ self.t_pu_earliest = new_earliest_pu_time # LOG.debug("after: {}".format(self)) + def set_new_dropoff_time_constraint(self, new_latest_do_time : int): + """ this function is used to update dropoff time constraints of the plan request + :param new_latest_do_time: new latest dropoff time""" + self.t_do_latest = new_latest_do_time + def set_new_max_trip_time(self, new_max_trip_time : float): """ this function updates the maximum trip time constraint :param new_max_trip_time: new maximum trip time""" diff --git a/src/fleetctrl/pooling/immediate/insertion.py b/src/fleetctrl/pooling/immediate/insertion.py index cce39fbb..fccf310f 100644 --- a/src/fleetctrl/pooling/immediate/insertion.py +++ b/src/fleetctrl/pooling/immediate/insertion.py @@ -387,7 +387,13 @@ def single_insertion(veh_obj_list : List[SimulationVehicle], current_vid_to_vehp return current_best_vid, current_best_plan, current_best_obj_delta -def insertion_with_heuristics(sim_time : int, prq : PlanRequest, fleetctrl : FleetControlBase, force_feasible_assignment : bool=True) -> List[Tuple[Any, VehiclePlan, float]]: +def insertion_with_heuristics( + sim_time : int, + prq : PlanRequest, + fleetctrl : FleetControlBase, + force_feasible_assignment : bool = True, + excluded_vid = [] +) -> List[Tuple[Any, VehiclePlan, float]]: """This function searches for suitable vehicles and return vehicle plans with insertions. Different heuristics depending on whether it is an immediate or reservation request can be triggered. See the respective functions for more details. @@ -395,13 +401,14 @@ def insertion_with_heuristics(sim_time : int, prq : PlanRequest, fleetctrl : Fle :param prq: PlanRequest to insert :param fleetctrl: FleetControl instance :param force_feasible_assignment: if True, a feasible solution is assigned even with positive control function value + :param excluded_vid: list of vehicle ids that should not be considered for assignment :return: list of (vid, vehplan, delta_cfv) tuples :rtype: list """ if prq.get_reservation_flag(): - return reservation_insertion_with_heuristics(sim_time, prq, fleetctrl, force_feasible_assignment) + return reservation_insertion_with_heuristics(sim_time, prq, fleetctrl, force_feasible_assignment, excluded_vid=excluded_vid) else: - return immediate_insertion_with_heuristics(sim_time, prq, fleetctrl, force_feasible_assignment) + return immediate_insertion_with_heuristics(sim_time, prq, fleetctrl, force_feasible_assignment, excluded_vid=excluded_vid) def immediate_insertion_with_heuristics(sim_time : int, prq : PlanRequest, fleetctrl : FleetControlBase, @@ -491,7 +498,14 @@ def immediate_insertion_with_heuristics(sim_time : int, prq : PlanRequest, fleet return return_rv_tuples -def reservation_insertion_with_heuristics(sim_time : int, prq : PlanRequest, fleetctrl : FleetControlBase, force_feasible_assignment : bool=True, veh_plans : Dict[int, VehiclePlan] = None) -> List[Tuple[Any, VehiclePlan, float]]: +def reservation_insertion_with_heuristics( + sim_time : int, + prq : PlanRequest, + fleetctrl : FleetControlBase, + force_feasible_assignment : bool = True, + veh_plans : Dict[int, VehiclePlan] = None, + excluded_vid: list[int] = [], +) -> List[Tuple[Any, VehiclePlan, float]]: """This function has access to all FleetControl attributes and therefore can trigger different heuristics and is easily extendable if new ideas for heuristics are developed. @@ -521,6 +535,7 @@ def reservation_insertion_with_heuristics(sim_time : int, prq : PlanRequest, fle :param fleetctrl: FleetControl instance :param force_feasible_assignment: if True, a feasible solution is assigned even with positive control function value :param veh_plans: dict vehicle id -> vehicle plan to insert to; if non fleetctrl.veh_plans is used + :param excluded_vid: list of vehicle ids that should not be considered for assignment :return: list of (vid, vehplan, delta_cfv) tuples :rtype: list """ @@ -533,7 +548,7 @@ def reservation_insertion_with_heuristics(sim_time : int, prq : PlanRequest, fle veh_plans_to_insert_to = fleetctrl.veh_plans # 1) pre vehicle-search processes - excluded_vid = [] + # excluded_vid = [] # 2) vehicle-search process dict_veh_to_av_infos = veh_search_for_reservation_request(sim_time, prq, fleetctrl, list_excluded_vid=excluded_vid, veh_plans=veh_plans_to_insert_to) diff --git a/src/fleetctrl/reservation/RollingHorizon.py b/src/fleetctrl/reservation/RollingHorizon.py index f2db16e7..b393f60d 100644 --- a/src/fleetctrl/reservation/RollingHorizon.py +++ b/src/fleetctrl/reservation/RollingHorizon.py @@ -65,14 +65,15 @@ def return_availability_constraints(self, sim_time): :return: list of (position, latest arrival time)""" return [] - def return_immediate_reservation_offer(self, rid, sim_time): + def return_immediate_reservation_offer(self, rid, sim_time, excluded_vid=[]): """ this function returns an offer if possible for an reservation request which has been added to the reservation module before in this implementation, an offer is always returned discribed by the earliest and latest pick up time :param rid: request id :param sim_time: current simulation time + :param excluded_vid: list of vehicle ids that should not be considered for assignment :return: offer for request """ prq = self.active_reservation_requests[rid] - tuple_list = reservation_insertion_with_heuristics(sim_time, prq, self.fleetctrl, force_feasible_assignment=True) + tuple_list = reservation_insertion_with_heuristics(sim_time, prq, self.fleetctrl, force_feasible_assignment=True, excluded_vid=excluded_vid) if len(tuple_list) > 0: best_tuple = min(tuple_list, key=lambda x:x[2]) best_vid, best_plan, _ = best_tuple @@ -101,9 +102,9 @@ def user_cancels_request(self, rid, simulation_time): :param simulation_time: current simulation time """ if self.rid_to_assigned_vid.get(rid) is not None: - vid = self.rid_to_assigned_vid.get[rid] + vid = self.rid_to_assigned_vid[rid] assigned_plan = self.fleetctrl.veh_plans[vid] - veh_obj = self.fleetctrl.veh_plans[vid] + veh_obj = self.fleetctrl.sim_vehicles[vid] new_plan = simple_remove(veh_obj, assigned_plan, rid, simulation_time, self.routing_engine, self.fleetctrl.vr_ctrl_f, self.fleetctrl.rq_dict, self.fleetctrl.const_bt, self.fleetctrl.add_bt) self.fleetctrl.assign_vehicle_plan(veh_obj, new_plan, simulation_time) diff --git a/src/misc/globals.py b/src/misc/globals.py index 4a31960d..6e3a8b14 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -73,6 +73,8 @@ # broker specific attributes G_BROKER_TYPE = "broker_type" +G_BROKER_TPCS_USE_DEFAULT = "broker_tpcs_use_default" # if True, only Phase 1 of TPCS communication strategy is used +G_BROKER_TRANSFER_SEARCH_METHOD = "broker_transfer_search_method" # method for finding transfer stations: "closest" or "best_overall" # public transport specific attributes G_PT_TYPE = "pt_type" @@ -105,6 +107,9 @@ G_PT_ROUTE_ID = "pt_route_id" G_PT_WALK_LOGIT_BETA = "pt_walk_logit_beta" G_PT_X_TOL = 0.01 +G_PT_SIM_START_DATE = "pt_simulation_start_date" # data string in format YYYYMMDD; this is a mandatory parameter for the Raptor Router +G_PT_OPERATOR_ID = "pt_operator_id" # id of the public transport operator +G_PT_OPERATOR_TYPE = "pt_operator_type" # type of the public transport operator # zonal control reward attributes G_PT_ZC_RID_SIM_TIME = 0 @@ -360,6 +365,7 @@ G_DIR_ZONES = "zones" G_DIR_FC = "forecasts" G_DIR_PT = "pubtrans" +G_DIR_GTFS = "gtfs" G_DIR_VEH = "vehicles" G_DIR_FCTRL = "fleetctrl" G_DIR_BP = "boardingpoints" @@ -544,12 +550,6 @@ class RQ_SUB_TRIP_ID(Enum): G_RQ_DEC_WT_FAC = "waiting_time_factor" G_RQ_DEC_REAC = "reaction_time" -# traveler modal state -G_RQ_STATE_MONOMODAL = 0 -G_RQ_STATE_FIRSTMILE = 1 -G_RQ_STATE_LASTMILE = 2 -G_RQ_STATE_FIRSTLASTMILE = 3 - # -------------------------------------------------------------------------------------------------------------------- # # Mode Choice Model # ----------------- @@ -612,6 +612,7 @@ class RQ_SUB_TRIP_ID(Enum): G_IM_OFFER_PT_WAIT = "im_t_wait_pt" # total pt waiting time G_IM_OFFER_PT_DRIVE = "im_t_drive_pt" # total pt driving time G_IM_OFFER_DURATION = "im_t_duration" # total duration of intermodal offer +G_IM_OFFER_TYPE = "im_offer_type" # type of intermodal offer: "TPCS Phase 2", "TPCS Phase 1", "TPCS Default" # additional parameters for pt offers # ------------------------------------------ @@ -760,6 +761,8 @@ class G_PLANSTOP_STATES(Enum): #--------------------------------------------------------------------------------------------------------------# # Evaluation specific params # #################### +# which evaluation method to use +G_EVAL_METHOD = "evaluation_method" # only evaluate data within specific interval G_EVAL_INT_START = "evaluation_int_start" @@ -816,6 +819,7 @@ def get_directory_dict(scenario_parameters, list_operator_dicts, abs_fleetpy_dir dirs[G_DIR_ZONES] = os.path.join(dirs[G_DIR_DATA], "zones", zone_name, network_name) if gtfs_name is not None: dirs[G_DIR_PT] = os.path.join(dirs[G_DIR_DATA], "pubtrans", gtfs_name) + dirs[G_DIR_GTFS] = os.path.join(dirs[G_DIR_DATA], "pubtrans", network_name, gtfs_name, "matched") if infra_name is not None: dirs[G_DIR_INFRA] = os.path.join(dirs[G_DIR_DATA], "infra", infra_name, network_name) if parcel_demand_name is not None: diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index 3827bd1c..a320fb45 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -118,6 +118,7 @@ def get_src_broker_modules(): # FleetPy broker options broker_dict = {} # str -> (module path, class name) broker_dict["BrokerBasic"] = ("src.broker.BrokerBasic", "BrokerBasic") + broker_dict["PTBrokerTPCS"] = ("src.broker.PTBrokerTPCS", "PTBrokerTPCS") # add development content if dev_content is not None: dev_broker_dict = dev_content.add_broker_modules() diff --git a/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb b/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb new file mode 100644 index 00000000..ec3ee136 --- /dev/null +++ b/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb @@ -0,0 +1,651 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4ba79989", + "metadata": {}, + "source": [ + "> ### 💡 Info: Data Preparation for FleetPy Raptor Router\n", + "> \n", + "> This notebook guides you through cleaning and formatting raw **GTFS data** into the specific file formats required by **FleetPy's Raptor Router**.\n", + ">\n", + "> #### 📄 Input Specifications:\n", + "> * **Mandatory GTFS Files:** `agency`, `calendar`, `routes`, `stop_times`, `stops`, `transfers`, and `trips`.\n", + "> * **Optional GTFS Files:** `calendar_dates`.\n", + "> * **Custom Required Files:** \n", + "> * `stations` (General requirement)\n", + "> * `street_station_transfers` (Required for the **PTBrokerTPCS** module)\n", + ">\n", + "> **Note:** Any files not mentioned above will be ignored by the FleetPy reader.\n", + ">\n", + "> #### 📝 Output Naming Convention:\n", + "> To distinguish processed files from the originals, the suffix `_fp` will be appended to each filename: \n", + "> `{original_filename}.txt` $\\rightarrow$ `{original_filename}_fp.txt`\n", + ">\n", + "> #### 📂 Output Directory Structure:\n", + "> All processed files must be placed in the following directory path:\n", + ">\n", + "> `data/pubtrans/{network_name}/{gtfs_name}/matched`\n", + ">\n", + "> * **`{network_name}`**: The name of the road network used in your FleetPy experiment.\n", + "> * **`{gtfs_name}`**: A custom identifier (string) that must be defined in your scenario configuration." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "09edb0cb", + "metadata": {}, + "outputs": [], + "source": [ + "# standard library imports\n", + "import pandas as pd\n", + "from pathlib import Path\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "6cf7b630", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "d:\\projects\\fleetpy\\ptbroker_to_be_merged\\data\\pubtrans\\example_network\\example_gtfs\\matched\n" + ] + } + ], + "source": [ + "current_dir = Path.cwd()\n", + "MAIN_DIR = current_dir.parents[2]\n", + "example_gtfs_path = os.path.join(MAIN_DIR, 'data', 'pubtrans', 'example_network', 'example_gtfs', 'matched')\n", + "print(example_gtfs_path)" + ] + }, + { + "cell_type": "markdown", + "id": "03c87c07", + "metadata": {}, + "source": [ + "# Mandatory GTFS Files" + ] + }, + { + "cell_type": "markdown", + "id": "6e4f72a8", + "metadata": {}, + "source": [ + "### agency" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "1ce0d496", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Agency file preview:\n", + " agency_id agency_name\n", + "0 pt FleetPy PT Operator\n" + ] + } + ], + "source": [ + "# read example agency file\n", + "agency_fp = pd.read_csv(os.path.join(example_gtfs_path, 'agency_fp.txt'))\n", + "print(\"\\nAgency file preview:\")\n", + "print(agency_fp.head())\n" + ] + }, + { + "cell_type": "markdown", + "id": "8101895b", + "metadata": {}, + "source": [ + "> #### 📄 Agency File Requirements\n", + "> \n", + "> **Required Columns:**\n", + "> * `agency_id`: Can be of type `int` or `string`.\n", + "> * `agency_name`: Must be of type `string`.\n", + "> \n", + "> ⚠️ **Critical Warning:** > When handling string fields (especially `agency_name`), **strictly avoid** using special characters such as commas (`,`), semicolons (`;`), or colons (`:`). \n", + "> These characters can interfere with file parsing and cause the underlying **C++ backend to crash**." + ] + }, + { + "cell_type": "markdown", + "id": "2baeb223", + "metadata": {}, + "source": [ + "### calendar" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "3f9b8f91", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Calendar file preview:\n", + " service_id monday tuesday wednesday thursday friday saturday sunday \\\n", + "0 0 1 1 1 1 1 1 1 \n", + "\n", + " start_date end_date \n", + "0 20000101 20991231 \n" + ] + } + ], + "source": [ + "# read example calendar file\n", + "calendar_fp = pd.read_csv(os.path.join(example_gtfs_path, 'calendar_fp.txt'))\n", + "print(\"\\nCalendar file preview:\")\n", + "print(calendar_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "4238ce98", + "metadata": {}, + "source": [ + "> #### 🗓️ Calendar File Specifications\n", + "> \n", + "> **Column Naming:** > Ensure strict adherence to the column naming conventions found in the provided example file.\n", + "> \n", + "> **Data Formatting & Types:**\n", + "> * `start_date` & `end_date`: Must be in **`YYYYMMDD`** format.\n", + "> * `service_id`: Can be of type `int` or `string`.\n", + "> * **All other columns:** Must be of type `int`." + ] + }, + { + "cell_type": "markdown", + "id": "18433a16", + "metadata": {}, + "source": [ + "### routes" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "314dd822", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Routes file preview:\n", + " route_id route_short_name route_desc\n", + "0 196 196 Bus\n", + "1 U5 U5 U-Bahn\n" + ] + } + ], + "source": [ + "# read example routes file\n", + "routes_fp = pd.read_csv(os.path.join(example_gtfs_path, 'routes_fp.txt'))\n", + "print(\"\\nRoutes file preview:\")\n", + "print(routes_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "9e2784e6", + "metadata": {}, + "source": [ + "> #### 🚌 Routes File Requirements\n", + "> \n", + "> **Column Specifications:**\n", + "> * **Mandatory:** `route_id`, `route_short_name`.\n", + "> * **Optional:** `route_desc`.\n", + "> * **Data Types:** All the columns above accept either `int` or `string` types.\n", + "> \n", + "> ⚠️ **Critical Warning:** > For all string fields (especially `route_desc` and `route_short_name`), **strictly avoid** using special characters such as commas (`,`), semicolons (`;`), or colons (`:`).\n", + "> Presence of these symbols can interfere with parsing and cause the **C++ backend to crash**." + ] + }, + { + "cell_type": "markdown", + "id": "7ba044a2", + "metadata": {}, + "source": [ + "### stops" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "6bd77ecf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stops file preview:\n", + " stop_id\n", + "0 1-0\n", + "1 1-1\n", + "2 1-2\n", + "3 1-3\n", + "4 2-0\n" + ] + } + ], + "source": [ + "# read example stops file\n", + "stops_fp = pd.read_csv(os.path.join(example_gtfs_path, 'stops_fp.txt'))\n", + "print(\"\\nStops file preview:\")\n", + "print(stops_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "d3deda00", + "metadata": {}, + "source": [ + "> #### 🚏 Stops File Requirements\n", + "> \n", + "> **Purpose & Optimization:**\n", + "> Since the FleetPy Raptor Router is designed solely to calculate the fastest route between two points, the `stops` file can be minimal.\n", + ">\n", + "> **Required Column:**\n", + "> * **`stop_id`**: This is the only column required to represent and index PT stops.\n", + "> * **Note:** All other columns (e.g., stop names, coordinates) are unnecessary for this specific input file and can be omitted.\n", + "> \n", + "> **Data Type:**\n", + "> * `stop_id` can be of type `int` or `string`.\n", + "> \n", + "> ⚠️ **Critical Warning:** > If `stop_id` is a string, **strictly avoid** using special characters such as commas (`,`), semicolons (`;`), or colons (`:`).\n", + "> These symbols can cause the **C++ backend to crash**." + ] + }, + { + "cell_type": "markdown", + "id": "99410a83", + "metadata": {}, + "source": [ + "### trips" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "8b1dfa77", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Trips file preview:\n", + " route_id trip_id service_id direction_id\n", + "0 196 196-0-0 0 0\n", + "1 196 196-1-0 0 0\n", + "2 196 196-2-0 0 0\n", + "3 196 196-3-0 0 0\n", + "4 196 196-4-0 0 0\n" + ] + } + ], + "source": [ + "# read example trips file\n", + "trips_fp = pd.read_csv(os.path.join(example_gtfs_path, 'trips_fp.txt'))\n", + "print(\"\\nTrips file preview:\")\n", + "print(trips_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "9d94b39b", + "metadata": {}, + "source": [ + "> #### 🔄 Trips File Requirements\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `route_id`: `int` or `string`\n", + "> * `trip_id`: `int` or `string`\n", + "> * `service_id`: `int` or `string`\n", + "> * `direction_id`: `int`\n", + "> \n", + "> ⚠️ **Critical Warning:** > For any string fields, **strictly avoid** using special characters such as commas (`,`), semicolons (`;`), or colons (`:`).\n", + "> These symbols can interfere with parsing and cause the **C++ backend to crash**." + ] + }, + { + "cell_type": "markdown", + "id": "8b369960", + "metadata": {}, + "source": [ + "### stop_times" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "9dd8a151", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stop_times file preview:\n", + " trip_id arrival_time departure_time stop_id stop_sequence\n", + "0 196-0-0 0:00:00 0:00:00 1-0 1\n", + "1 196-0-0 0:02:00 0:02:00 2-0 2\n", + "2 196-0-0 0:03:30 0:03:30 3-0 3\n", + "3 196-0-0 0:04:30 0:04:30 4-0 4\n", + "4 196-0-0 0:05:30 0:05:30 5-0 5\n" + ] + } + ], + "source": [ + "# read example stop_times file\n", + "stop_times_fp = pd.read_csv(os.path.join(example_gtfs_path, 'stop_times_fp.txt'))\n", + "print(\"\\nStop_times file preview:\")\n", + "print(stop_times_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "bd84356b", + "metadata": {}, + "source": [ + "> #### ⏱️ Stop Times File Requirements\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `trip_id`\n", + "> * `arrival_time`\n", + "> * `departure_time`\n", + "> * `stop_id`\n", + "> * `stop_sequence`\n", + "> \n", + "> **Data Formatting Rules:**\n", + "> * **Time Fields:** `arrival_time` and `departure_time` must be strictly formatted as **`HH:MM:SS`**.\n", + "> * **Sequence:** `stop_sequence` must be an **integer greater than 0**." + ] + }, + { + "cell_type": "markdown", + "id": "9a41f81f", + "metadata": {}, + "source": [ + "### transfers" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "41917216", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Transfers file preview:\n", + " from_stop_id to_stop_id min_transfer_time\n", + "0 1-0 1-1 3\n", + "1 1-0 1-2 3\n", + "2 1-0 1-3 3\n", + "3 1-1 1-0 3\n", + "4 1-1 1-2 3\n" + ] + } + ], + "source": [ + "# read example transfers file\n", + "transfers_fp = pd.read_csv(os.path.join(example_gtfs_path, 'transfers_fp.txt'))\n", + "print(\"\\nTransfers file preview:\")\n", + "print(transfers_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "59a8d1c4", + "metadata": {}, + "source": [ + "> #### ⇄ Transfers File Requirements\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `from_stop_id`\n", + "> * `to_stop_id`\n", + "> * `min_transfer_time`\n", + "> \n", + "> **Data Specifications:**\n", + "> * `min_transfer_time`: Must be of type `int`. This value represents the required transfer duration between stops **in seconds**.\n", + "> \n", + "> **Connectivity Rule:**\n", + "> * If a specific pair of stops is not listed in this file, it implies that **no transfer is possible** between them." + ] + }, + { + "cell_type": "markdown", + "id": "8bacc072", + "metadata": {}, + "source": [ + "# Optional GTFS Files" + ] + }, + { + "cell_type": "markdown", + "id": "b04bce9e", + "metadata": {}, + "source": [ + "### calendar_dates" + ] + }, + { + "cell_type": "markdown", + "id": "685b376a", + "metadata": {}, + "source": [ + "> #### 📅 Calendar Dates File Requirements\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `service_id`\n", + "> * `date`\n", + "> * `exception_type`\n", + "> \n", + "> **Data Specifications:**\n", + "> * **Date:** The `date` column must be in **`YYYYMMDD`** format.\n", + "> * **Exception Type:** The `exception_type` column accepts only values `1` or `2`:\n", + "> * **`1`**: Service has been **added** for the specified date.\n", + "> * **`2`**: Service has been **removed** for the specified date." + ] + }, + { + "cell_type": "markdown", + "id": "2a4467c4", + "metadata": {}, + "source": [ + "# Custom Required Files" + ] + }, + { + "cell_type": "markdown", + "id": "3250a8fc", + "metadata": {}, + "source": [ + "### stations" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d5030f8e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Stations file preview:\n", + " station_id station_name station_lat station_lon \\\n", + "0 s1 Neuperlach Zentrum 48.101125 11.646505 \n", + "1 s2 Jakob-Kaiser-Straße 48.104353 11.640405 \n", + "2 s3 Holzwiesenstraße 48.103075 11.636597 \n", + "3 s4 Wilhelm-Hoegner-Straße 48.098876 11.636399 \n", + "4 s5 Wolframstraße 48.094862 11.635797 \n", + "\n", + " stops_included station_stop_transfer_times \\\n", + "0 ['1-0', '1-1', '1-2', '1-3'] [1, 1, 1, 1] \n", + "1 ['2-0', '2-1'] [1, 1] \n", + "2 ['3-0', '3-1'] [1, 1] \n", + "3 ['4-0', '4-1'] [1, 1] \n", + "4 ['5-0', '5-1'] [1, 1] \n", + "\n", + " num_stops_included \n", + "0 4 \n", + "1 2 \n", + "2 2 \n", + "3 2 \n", + "4 2 \n" + ] + } + ], + "source": [ + "# read example stations file\n", + "stations_fp = pd.read_csv(os.path.join(example_gtfs_path, 'stations_fp.txt'))\n", + "print(\"\\nStations file preview:\")\n", + "print(stations_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "4d80550c", + "metadata": {}, + "source": [ + "> #### 🚉 Stations File Requirements (Custom Input)\n", + "> \n", + "> **Role in FleetPy:**\n", + "> Stations serve as the **interface points** between the Road Network and the PT Network.\n", + "> * **Passenger Flow:** Street Network Node $\\rightarrow$ Walk $\\rightarrow$ Station $\\rightarrow$ Transfer $\\rightarrow$ Specific PT Stops (within the station).\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `station_id`\n", + "> * `stops_included`\n", + "> * `station_stop_transfer_times`\n", + "> * `num_stops_included`\n", + "> \n", + "> **Optional Columns:**\n", + "> * `station_name`\n", + "> * `station_lat`, `station_lon`\n", + "> \n", + "> **Detailed Column Specifications:**\n", + "> * **`station_id`**: A unique `string` used to index the station.\n", + "> * **`stops_included`**: A **list** containing all stop IDs belonging to this station. These IDs must exist in `stops_fp.txt`.\n", + "> * **`station_stop_transfer_times`**: A **list** representing the walking time (in **seconds**) from the abstract Station Node to each corresponding Stop Node.\n", + "> * **`num_stops_included`**: An `integer` representing the total number of stops in the station (i.e., the length of `stops_included`).\n", + "> * **`station_lat` / `station_lon`**: Coordinates of the station. It is recommended that the **CRS** (Coordinate Reference System) matches the network CRS used in your FleetPy experiment.\n", + "> \n", + "> ⚠️ **Implementation Note:**\n", + "> * **Resolution:** Even if your GTFS data (stops_fp.txt) is already at the \"station level\" (rather than stop level), this file **must still be created**. In this case, `station_stop_transfer_times` can be a list containing only zeros.\n", + "> * **Backend Usage:** This file is explicitly called by the `_get_included_stops_and_transfer_times` method in **`RaptorRouterCpp`**." + ] + }, + { + "cell_type": "markdown", + "id": "8bf509e1", + "metadata": {}, + "source": [ + "### street_station_transfers" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "bb8d18d3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Street_station_transfers file preview:\n", + " node_id closest_station_id street_station_transfer_time\n", + "0 2966 s1 60\n", + "1 2967 s2 27\n", + "2 2968 s3 49\n", + "3 2969 s4 27\n", + "4 2970 s5 12\n" + ] + } + ], + "source": [ + "# read example street_station_transfers file\n", + "street_station_transfers_fp = pd.read_csv(os.path.join(example_gtfs_path, 'street_station_transfers_fp.txt'))\n", + "print(\"\\nStreet_station_transfers file preview:\")\n", + "print(street_station_transfers_fp.head())" + ] + }, + { + "cell_type": "markdown", + "id": "9a295e8b", + "metadata": {}, + "source": [ + "> #### 🛣️ Street-Station Transfers File Requirements\n", + "> *Target Module: PTBrokerTPCS*\n", + "> \n", + "> **Mandatory Columns:**\n", + "> * `node_id`\n", + "> * `closest_station_id`\n", + "> * `street_station_transfer_time`\n", + "> \n", + "> **Usage Context:**\n", + "> This file is **mandatory** for the `PTBrokerTPCS` module when the `_find_transfer_info` method is set to the `\"closest\"` query strategy (which is the default setting).\n", + "> \n", + "> **Data Logic:**\n", + "> * **`node_id`**: Represents the PUDO (Pick-up/Drop-off) nodes.\n", + "> * **`closest_station_id`**: Records the ID of the nearest station node relative to the PUDO node.\n", + "> * **`street_station_transfer_time`**: Represents the walking time from the PUDO node to the closest station **in seconds**.\n", + "> \n", + "> ℹ️ **Optimization Note:**\n", + "> If you are exclusively using `RaptorRouterCpp` to run the PT Router (without the PTBrokerTPCS module), this file is unnecessary and can be **ignored**." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "fleetpy", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/ptctrl/PTControlBase.py b/src/ptctrl/PTControlBase.py index f6715973..b1f996ce 100644 --- a/src/ptctrl/PTControlBase.py +++ b/src/ptctrl/PTControlBase.py @@ -10,6 +10,9 @@ # src imports # ----------- +if tp.TYPE_CHECKING: + from src.routing.pt.RaptorRouterCpp import RaptorRouterCpp + from src.simulation.Offers import PTOffer # -------------------------------------------------------------------------------------------------------------------- # # global variables @@ -33,7 +36,10 @@ class PTControlBase(metaclass=ABCMeta): @abstractmethod def __init__(self): - pass + self.pt_router: RaptorRouterCpp = None + self.pt_operator_id: int = None + self.pt_offer_db: tp.Dict[str, 'PTOffer'] = {} + self.gtfs_dir: str = None @abstractmethod def _load_pt_router(self): diff --git a/src/ptctrl/PTControlBasic.py b/src/ptctrl/PTControlBasic.py index 3fea2ddc..1c4f5488 100644 --- a/src/ptctrl/PTControlBasic.py +++ b/src/ptctrl/PTControlBasic.py @@ -42,25 +42,21 @@ class PTControlBasic(PTControlBase): def __init__(self, gtfs_dir: str, pt_operator_id: int = -2): super().__init__() - self.pt_router: RaptorRouterCpp = self._load_pt_router(gtfs_dir) + self.gtfs_dir: str = gtfs_dir self.pt_operator_id: int = pt_operator_id - self.pt_offer_db: tp.Dict[str, 'PTOffer'] = {} # rid_struct -> PTOffer - + self.pt_router: RaptorRouterCpp = self._load_pt_router() LOG.info("PT operator initialized successfully.") - def _load_pt_router(self, gtfs_dir: str) -> RaptorRouterCpp: + def _load_pt_router(self) -> RaptorRouterCpp: """This method will load and initialize the pt router instance. - - Args: - gtfs_dir (str): the directory path where the GTFS files are stored. """ - return RaptorRouterCpp(gtfs_dir) + return RaptorRouterCpp(self.gtfs_dir) def return_fastest_pt_journey_1to1( self, source_station_id: str, target_station_id: str, - source_station_departure_time: int, + source_station_departure_datetime: datetime, max_transfers: int = 999, detailed: bool = False, ) -> tp.Union[tp.Dict[str, tp.Any], None]: @@ -69,7 +65,7 @@ def return_fastest_pt_journey_1to1( Args: source_station_id (str): id of the source station. target_station_id (str): id of the target station. - source_station_departure_time (int): departure timestamp [s] from source station. + source_station_departure_datetime (datetime): departure datetime from source station. max_transfers (int, optional): maximum number of transfers allowed. Defaults to 999 (no limit). detailed (bool, optional): whether to return a detailed journey plan. Defaults to False. Returns: @@ -78,7 +74,7 @@ def return_fastest_pt_journey_1to1( pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_router.find_fastest_pt_journey_1to1( source_station_id = source_station_id, target_station_id = target_station_id, - source_station_departure_time = source_station_departure_time, + source_station_departure_datetime = source_station_departure_datetime, max_transfers = max_transfers, detailed = detailed, ) @@ -89,9 +85,8 @@ def create_and_record_pt_offer_db( rid_struct: str, operator_id: int, source_station_id: str, target_station_id: str, source_walking_time: int,target_walking_time: int, - source_station_departure_time: int, pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None], - previous_amod_operator_id: int = None, + firstmile_amod_operator_id: int = None, ): """This method will create a PTOffer for the pt request and record it in the pt offer database. @@ -102,19 +97,18 @@ def create_and_record_pt_offer_db( target_station_id (str): id of the target station. source_walking_time (int): walking time [s] from origin street node to source station. target_walking_time (int): walking time [s] from target station to destination street node. - source_station_departure_time (int): departure timestamp [s] from source station. pt_journey_plan_dict (tp.Union[tp.Dict[str, tp.Any], None]): The pt journey plan dictionary or None if no journey is found. - previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + firstmile_amod_operator_id (int, optional): The operator id of the firstmile amod operator. Defaults to None. """ if pt_journey_plan_dict is None: - self.pt_offer_db[(rid_struct, previous_amod_operator_id)] = Rejection(rid_struct, operator_id) + self.pt_offer_db[(rid_struct, firstmile_amod_operator_id)] = Rejection(rid_struct, operator_id) else: fare: int = self._compute_fare() # old offer will always be overwritten - self.pt_offer_db[(rid_struct, previous_amod_operator_id)] = PTOffer( + self.pt_offer_db[(rid_struct, firstmile_amod_operator_id)] = PTOffer( traveler_id = rid_struct, operator_id = operator_id, source_station_id = source_station_id, target_station_id = target_station_id, - source_walking_time = source_walking_time, source_station_departure_time = source_station_departure_time, + source_walking_time = source_walking_time, source_station_departure_time = pt_journey_plan_dict.get(G_PT_OFFER_SOURCE_STATION_DEPARTURE_TIME, None), source_transfer_time = pt_journey_plan_dict.get(G_PT_OFFER_SOURCE_TRANSFER_TIME, None), waiting_time = pt_journey_plan_dict.get(G_PT_OFFER_SOURCE_WAITING_TIME, None), trip_time = pt_journey_plan_dict.get(G_PT_OFFER_TRIP_TIME, None), @@ -137,31 +131,31 @@ def _compute_fare(self) -> int: def get_current_offer( self, rid_struct: str, - previous_amod_operator_id: int = None, + firstmile_amod_operator_id: int = None, ) -> tp.Optional[PTOffer]: """This method will return the current offer for the pt request. Args: rid_struct (str): The sub-request id struct of the journey. - previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + firstmile_amod_operator_id (int, optional): The operator id of the firstmile amod operator. Defaults to None. Returns: tp.Optional[PTOffer]: The current offer for the pt request. """ - return self.pt_offer_db.get((rid_struct, previous_amod_operator_id), None) + return self.pt_offer_db.get((rid_struct, firstmile_amod_operator_id), None) def user_confirms_booking( self, pt_sub_rq_obj: 'BasicIntermodalRequest', - previous_amod_operator_id: int = None + firstmile_amod_operator_id: int = None ): """This method is used to confirm a customer booking. This can trigger some database processes. Args: - pt_sub_rq_obj (BasicMultimodalRequest): The pt sub-request object. - previous_amod_operator_id (int, optional): The operator id of the previous amod operator. Defaults to None. + pt_sub_rq_obj (BasicIntermodalRequest): The pt sub-request object. + firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests """ pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() - pt_offer: 'PTOffer' = self.get_current_offer(pt_rid_struct, previous_amod_operator_id) + pt_offer: 'PTOffer' = self.get_current_offer(pt_rid_struct, firstmile_amod_operator_id) pt_sub_rq_obj.user_boards_vehicle( simulation_time = pt_offer.get(G_PT_OFFER_SOURCE_STATION_DEPARTURE_TIME, None), op_id = self.pt_operator_id, diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py index adc0b94b..15b8a07d 100644 --- a/src/routing/pt/RaptorRouterCpp.py +++ b/src/routing/pt/RaptorRouterCpp.py @@ -47,9 +47,6 @@ def __init__(self, gtfs_dir: str): # load the stations: used for station-stop mapping self.stations_fp_df = self._load_stations_from_gtfs(gtfs_dir) - # load the street-station transfers: used for finding closest station to a street node, or vice versa - self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(gtfs_dir) - def _initialize_pt_router(self, gtfs_dir: str): """This method initializes the PT router. @@ -97,28 +94,13 @@ def _load_stations_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: } return pd.read_csv(os.path.join(gtfs_dir, "stations_fp.txt"), dtype=dtypes) - def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: - """This method loads the FleetPy-specific street station transfers file. - - Args: - gtfs_dir (str): The directory containing the GTFS data of the operator. - Returns: - pd.DataFrame: The transfer data between the street nodes and the PT stations. - """ - dtypes = { - 'node_id': 'int', - 'closest_station_id': 'str', - 'street_transfer_time': 'int', - } - return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) - def find_fastest_pt_journey_1to1( self, source_station_id: str, target_station_id: str, source_station_departure_datetime: datetime, - max_transfers: int=999, - detailed: bool=False, + max_transfers: int = 999, + detailed: bool = False, ) -> tp.Union[tp.Dict[str, tp.Any], None]: """This method returns the fastest PT journey plan between two PT stations. A station may consist of multiple stops. @@ -183,6 +165,7 @@ def _get_included_stops_and_transfer_times(self, station_id: str) -> tp.Tuple[tp if __name__ == "__main__": # Test/run the pt router module: python -m src.routing.pt.RaptorRouterCpp + # To prepare the GTFS data, please check: src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb gtfs_dir = "data/pubtrans/example_network/example_gtfs/matched" router = RaptorRouterCpp(gtfs_dir) diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index 95d0c412..5f1a511a 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -281,15 +281,18 @@ def _merge_sub_trip_offers(self) -> tp.Dict[str, tp.Any]: for sub_trip_id, wait_key, drive_key in mapping_configs: offer = self.sub_trip_offers.get(sub_trip_id, {}) # map pt specific attributes - if sub_trip_id == RQ_SUB_TRIP_ID.FM_PT.value or sub_trip_id == RQ_SUB_TRIP_ID.PT_LM.value or sub_trip_id == RQ_SUB_TRIP_ID.FLM_PT.value: + if sub_trip_id == RQ_SUB_TRIP_ID.FM_PT.value or sub_trip_id == RQ_SUB_TRIP_ID.LM_PT.value or sub_trip_id == RQ_SUB_TRIP_ID.FLM_PT.value: for attr in pt_attributes_to_extract: self.additional_offer_parameters[attr] = offer.get(attr) self.additional_offer_parameters[wait_key] = offer.get(G_OFFER_WAIT) self.additional_offer_parameters[drive_key] = offer.get(G_OFFER_DRIVE) + duration = total_wait + total_drive + self.additional_offer_parameters[G_IM_OFFER_DURATION] = duration + return { G_IM_OFFER_OPERATOR_SUB_TRIP_TUPLE: tuple(operator_sub_trip_list), G_OFFER_FARE: total_fare, G_OFFER_WAIT: total_wait, - G_OFFER_DRIVE: total_drive + G_OFFER_DRIVE: total_drive, } \ No newline at end of file diff --git a/src/simulation/Vehicles.py b/src/simulation/Vehicles.py index c95efdf5..7e562596 100644 --- a/src/simulation/Vehicles.py +++ b/src/simulation/Vehicles.py @@ -339,8 +339,8 @@ def assign_vehicle_plan(self, list_route_legs : tp.List[VehicleRouteLeg], sim_ti # transform rq from PlanRequest to SimulationRequest (based on RequestBase) # LOG.info(f"Vehicle {self.vid} before new assignment: {[str(x) for x in self.assigned_route]} at time {sim_time}") for vrl in list_route_legs: - boarding_list = [self.rq_db[prq.get_rid()] for prq in vrl.rq_dict.get(1,[])] - alighting_list = [self.rq_db[prq.get_rid()] for prq in vrl.rq_dict.get(-1,[])] + boarding_list = [self.rq_db[prq.get_rid_struct()] for prq in vrl.rq_dict.get(1,[])] + alighting_list = [self.rq_db[prq.get_rid_struct()] for prq in vrl.rq_dict.get(-1,[])] vrl.rq_dict = {1:boarding_list, -1:alighting_list} LOG.debug(f"Vehicle {self.vid} received new VRLs {[str(x) for x in list_route_legs]} at time {sim_time}") LOG.debug(f" -> current assignment: {[str(x) for x in self.assigned_route]}") diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv new file mode 100644 index 00000000..04a716eb --- /dev/null +++ b/studies/example_study/scenarios/example_im.csv @@ -0,0 +1,3 @@ +scenario_name,op_module,rq_file,op_fleet_composition,broker_type,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,broker_tpcs_use_default,evaluation_method,sim_env,user_max_decision_time +example_im_ptbroker_tpcs,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,False,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbroker_tpcs_default,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,True,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file diff --git a/studies/module_tests/run_module_tests.py b/studies/module_tests/run_module_tests.py index 1cfb2eed..654c3f17 100644 --- a/studies/module_tests/run_module_tests.py +++ b/studies/module_tests/run_module_tests.py @@ -269,6 +269,13 @@ def run_module_test_simulations(N_PARALLEL_SIM=1): sc = os.path.join(scs_path, "sc_config_forecasting.csv") run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=N_PARALLEL_SIM) print(" => Test Forecasting Modules completed!") + + # Test Intermodal Modules + # TODO: integrate result comparison after fixing issues with intermodal evaluation + print("Test Intermodal Modules ...") + sc = os.path.join(scs_path, "sc_config_im.csv") + run_scenarios(cc, sc, log_level=log_level, n_cpu_per_sim=1, n_parallel_sim=N_PARALLEL_SIM) + print(" => Test Intermodal Modules completed!") # Test SoD Max Modules # TODO test after upgrade diff --git a/studies/module_tests/scenarios/sc_config_im.csv b/studies/module_tests/scenarios/sc_config_im.csv new file mode 100644 index 00000000..61cdc01f --- /dev/null +++ b/studies/module_tests/scenarios/sc_config_im.csv @@ -0,0 +1,3 @@ +scenario_name,op_module,rq_file,op_fleet_composition,broker_type,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,broker_tpcs_use_default,evaluation_method,sim_env,user_max_decision_time +mt_im_ptbroker_tpcs,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,False,intermodal_evaluation,ImmediateDecisionsSimulation,0 +mt_im_ptbroker_tpcs_default,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,True,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From daa5ab1b8b0ca8ba554795606ebe06ccaad464ec Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 18 Dec 2025 10:47:13 +0100 Subject: [PATCH 12/31] Standardize fixed-line transportation service naming to 'pt' and update corresponding directory names and file paths to reflect this change. --- .gitignore | 8 +++--- .../example_gtfs/matched/agency_fp.txt | 0 .../example_gtfs/matched/calendar_fp.txt | 0 .../example_gtfs/matched/routes_fp.txt | 0 .../example_gtfs/matched/stations_fp.txt | 0 .../example_gtfs/matched/stop_times_fp.txt | 0 .../example_gtfs/matched/stops_fp.txt | 0 .../matched/street_station_transfers_fp.txt | 0 .../example_gtfs/matched/transfers_fp.txt | 0 .../example_gtfs/matched/trips_fp.txt | 0 .../route_193/193_line_alignment.geojson | 0 .../route_193/193_schedules.csv | 0 data/{pubtrans => pt}/route_193/stations.csv | 0 src/FleetSimulationBase.py | 4 +-- src/misc/globals.py | 6 ++--- .../pubtrans/PTRouterGTFSPreperation.ipynb | 26 +++++++++---------- src/preprocessing/pubtrans/PTScheduleGen.py | 10 +++---- src/routing/pt/RaptorRouterCpp.py | 4 +-- 18 files changed, 29 insertions(+), 29 deletions(-) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/agency_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/calendar_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/routes_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/stations_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/stop_times_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/stops_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/street_station_transfers_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/transfers_fp.txt (100%) rename data/{pubtrans => pt}/example_network/example_gtfs/matched/trips_fp.txt (100%) rename data/{pubtrans => pt}/route_193/193_line_alignment.geojson (100%) rename data/{pubtrans => pt}/route_193/193_schedules.csv (100%) rename data/{pubtrans => pt}/route_193/stations.csv (100%) diff --git a/.gitignore b/.gitignore index 2fac21a2..bb599d12 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,9 @@ data/networks/* data/networks/example_network/ff/* data/networks/example_network/ch_graph/* data/networks/example_network/base/*.graph -data/pubtrans/* -!data/pubtrans/route_193 -!data/pubtrans/example_network +data/pt/* +!data/pt/route_193 +!data/pt/example_network data/vehicles/* !data/vehicles/default_vehtype.csv !data/vehicles/low_range_vehtype.csv @@ -196,5 +196,5 @@ dmypy.json .DS_Store # GTFS preprocessing file -!src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb +!src/preprocessing/pt/PTRouterGTFSPreperation.ipynb diff --git a/data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt b/data/pt/example_network/example_gtfs/matched/agency_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/agency_fp.txt rename to data/pt/example_network/example_gtfs/matched/agency_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt b/data/pt/example_network/example_gtfs/matched/calendar_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/calendar_fp.txt rename to data/pt/example_network/example_gtfs/matched/calendar_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt b/data/pt/example_network/example_gtfs/matched/routes_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/routes_fp.txt rename to data/pt/example_network/example_gtfs/matched/routes_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt b/data/pt/example_network/example_gtfs/matched/stations_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/stations_fp.txt rename to data/pt/example_network/example_gtfs/matched/stations_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt b/data/pt/example_network/example_gtfs/matched/stop_times_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/stop_times_fp.txt rename to data/pt/example_network/example_gtfs/matched/stop_times_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt b/data/pt/example_network/example_gtfs/matched/stops_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/stops_fp.txt rename to data/pt/example_network/example_gtfs/matched/stops_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt b/data/pt/example_network/example_gtfs/matched/street_station_transfers_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/street_station_transfers_fp.txt rename to data/pt/example_network/example_gtfs/matched/street_station_transfers_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt b/data/pt/example_network/example_gtfs/matched/transfers_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/transfers_fp.txt rename to data/pt/example_network/example_gtfs/matched/transfers_fp.txt diff --git a/data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt b/data/pt/example_network/example_gtfs/matched/trips_fp.txt similarity index 100% rename from data/pubtrans/example_network/example_gtfs/matched/trips_fp.txt rename to data/pt/example_network/example_gtfs/matched/trips_fp.txt diff --git a/data/pubtrans/route_193/193_line_alignment.geojson b/data/pt/route_193/193_line_alignment.geojson similarity index 100% rename from data/pubtrans/route_193/193_line_alignment.geojson rename to data/pt/route_193/193_line_alignment.geojson diff --git a/data/pubtrans/route_193/193_schedules.csv b/data/pt/route_193/193_schedules.csv similarity index 100% rename from data/pubtrans/route_193/193_schedules.csv rename to data/pt/route_193/193_schedules.csv diff --git a/data/pubtrans/route_193/stations.csv b/data/pt/route_193/stations.csv similarity index 100% rename from data/pubtrans/route_193/stations.csv rename to data/pt/route_193/stations.csv diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index b2835a9d..3a449b9c 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -257,12 +257,12 @@ def __init__(self, scenario_parameters: dict): # if pt_type is None or self.gtfs_data_dir is None: # self.pt = None # elif pt_type == "PTMatrixCrowding": - # pt_module = importlib.import_module("src.pubtrans.PtTTMatrixCrowding") + # pt_module = importlib.import_module("src.pt.PtTTMatrixCrowding") # self.pt = pt_module.PublicTransportTravelTimeMatrixWithCrowding(self.gtfs_data_dir, self.pt_stat_f, # self.scenario_parameters, # self.routing_engine, self.zones) # elif pt_type == "PtCrowding": - # pt_module = importlib.import_module("src.pubtrans.PtCrowding") + # pt_module = importlib.import_module("src.pt.PtCrowding") # self.pt = pt_module.PublicTransportWithCrowding(self.gtfs_data_dir, self.pt_stat_f, self.scenario_parameters, # self.routing_engine, self.zones) # else: diff --git a/src/misc/globals.py b/src/misc/globals.py index 6e3a8b14..714f55d6 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -364,7 +364,7 @@ G_DIR_DEMAND = "demand" G_DIR_ZONES = "zones" G_DIR_FC = "forecasts" -G_DIR_PT = "pubtrans" +G_DIR_PT = "pt" G_DIR_GTFS = "gtfs" G_DIR_VEH = "vehicles" G_DIR_FCTRL = "fleetctrl" @@ -818,8 +818,8 @@ def get_directory_dict(scenario_parameters, list_operator_dicts, abs_fleetpy_dir if zone_name is not None: dirs[G_DIR_ZONES] = os.path.join(dirs[G_DIR_DATA], "zones", zone_name, network_name) if gtfs_name is not None: - dirs[G_DIR_PT] = os.path.join(dirs[G_DIR_DATA], "pubtrans", gtfs_name) - dirs[G_DIR_GTFS] = os.path.join(dirs[G_DIR_DATA], "pubtrans", network_name, gtfs_name, "matched") + dirs[G_DIR_PT] = os.path.join(dirs[G_DIR_DATA], "pt", gtfs_name) + dirs[G_DIR_GTFS] = os.path.join(dirs[G_DIR_DATA], "pt", network_name, gtfs_name, "matched") if infra_name is not None: dirs[G_DIR_INFRA] = os.path.join(dirs[G_DIR_DATA], "infra", infra_name, network_name) if parcel_demand_name is not None: diff --git a/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb b/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb index ec3ee136..721b79a6 100644 --- a/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb +++ b/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb @@ -25,7 +25,7 @@ "> #### 📂 Output Directory Structure:\n", "> All processed files must be placed in the following directory path:\n", ">\n", - "> `data/pubtrans/{network_name}/{gtfs_name}/matched`\n", + "> `data/pt/{network_name}/{gtfs_name}/matched`\n", ">\n", "> * **`{network_name}`**: The name of the road network used in your FleetPy experiment.\n", "> * **`{gtfs_name}`**: A custom identifier (string) that must be defined in your scenario configuration." @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "id": "6cf7b630", "metadata": {}, "outputs": [ @@ -54,14 +54,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "d:\\projects\\fleetpy\\ptbroker_to_be_merged\\data\\pubtrans\\example_network\\example_gtfs\\matched\n" + "/Users/dch/Projects/FleetPy/ptbroker_to_be_merged/data/pt/example_network/example_gtfs/matched\n" ] } ], "source": [ "current_dir = Path.cwd()\n", "MAIN_DIR = current_dir.parents[2]\n", - "example_gtfs_path = os.path.join(MAIN_DIR, 'data', 'pubtrans', 'example_network', 'example_gtfs', 'matched')\n", + "example_gtfs_path = os.path.join(MAIN_DIR, 'data', 'pt', 'example_network', 'example_gtfs', 'matched')\n", "print(example_gtfs_path)" ] }, @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "id": "1ce0d496", "metadata": {}, "outputs": [ @@ -130,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "id": "3f9b8f91", "metadata": {}, "outputs": [ @@ -180,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "id": "314dd822", "metadata": {}, "outputs": [ @@ -229,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 6, "id": "6bd77ecf", "metadata": {}, "outputs": [ @@ -286,7 +286,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 7, "id": "8b1dfa77", "metadata": {}, "outputs": [ @@ -339,7 +339,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 8, "id": "9dd8a151", "metadata": {}, "outputs": [ @@ -394,7 +394,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 9, "id": "41917216", "metadata": {}, "outputs": [ @@ -492,7 +492,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 10, "id": "d5030f8e", "metadata": {}, "outputs": [ @@ -575,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 11, "id": "bb8d18d3", "metadata": {}, "outputs": [ diff --git a/src/preprocessing/pubtrans/PTScheduleGen.py b/src/preprocessing/pubtrans/PTScheduleGen.py index dced21fb..5d9ea316 100755 --- a/src/preprocessing/pubtrans/PTScheduleGen.py +++ b/src/preprocessing/pubtrans/PTScheduleGen.py @@ -782,7 +782,7 @@ def plot_route_with_demand(self, terminus_stop: str, time_range=None, data_p = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), "data") demand_csv = os.path.join(data_p, "demand", "SoD_demand", "sample.csv") #'data/demand/SoD_demand/sample.csv' - GTFS_folder = os.path.join(data_p, "pubtrans", "MVG_GTFS_2025-03-04") # "data/pubtrans/MVG_GTFS" + GTFS_folder = os.path.join(data_p, "pt", "MVG_GTFS_2025-03-04") # "data/pt/MVG_GTFS" network_path = os.path.join(data_p, "networks", "osm_route_MVG_road") # "data/networks/osm_route_MVG_road" route_no = 193 @@ -824,7 +824,7 @@ def plot_route_with_demand(self, terminus_stop: str, time_range=None, veh_size = 20 # veh size (passenger) pt_gen.load_demand(demand_csv) - pt_gen.save_alignment_geojson(os.path.join(data_p, "pubtrans", f"route_{route_no}")) + pt_gen.save_alignment_geojson(os.path.join(data_p, "pt", f"route_{route_no}")) hourly_demand = pt_gen.return_hourly_demand(time_range=(start_time, end_time)) print(f"Route {route_no} hourly demand: {hourly_demand}") @@ -835,12 +835,12 @@ def plot_route_with_demand(self, terminus_stop: str, time_range=None, route_len = pt_gen.return_route_length() print(f"Route {route_no} length: {route_len}") - pt_gen.output_station(os.path.join(data_p, "pubtrans", f"route_{route_no}")) + pt_gen.output_station(os.path.join(data_p, "pt", f"route_{route_no}")) # schedule is now standard instead of dependent on headway and n_veh schedule_file_name = f"{route_no}_schedules.csv" veh_type = f"veh_{veh_size}" - pt_gen.output_schedule(os.path.join(data_p, "pubtrans", f"route_{route_no}"), + pt_gen.output_schedule(os.path.join(data_p, "pt", f"route_{route_no}"), schedules_file=schedule_file_name, veh_type=veh_type) gtfs_name = f"route_{route_no}" demand_name = f"route_{route_no}_demand" @@ -848,7 +848,7 @@ def plot_route_with_demand(self, terminus_stop: str, time_range=None, pt_gen.plot_route_with_demand( terminus_stop, time_range=(start_time, end_time), - html_name=os.path.join(data_p, "pubtrans", f"route_{route_no}", f"route_{route_no}_demand_sample.html") + html_name=os.path.join(data_p, "pt", f"route_{route_no}", f"route_{route_no}_demand_sample.html") ) terminus_id = pt_gen.return_terminus_id() diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py index 15b8a07d..35b399ed 100644 --- a/src/routing/pt/RaptorRouterCpp.py +++ b/src/routing/pt/RaptorRouterCpp.py @@ -165,9 +165,9 @@ def _get_included_stops_and_transfer_times(self, station_id: str) -> tp.Tuple[tp if __name__ == "__main__": # Test/run the pt router module: python -m src.routing.pt.RaptorRouterCpp - # To prepare the GTFS data, please check: src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb + # To prepare the GTFS data, please check: src/preprocessing/pt/PTRouterGTFSPreperation.ipynb - gtfs_dir = "data/pubtrans/example_network/example_gtfs/matched" + gtfs_dir = "data/pt/example_network/example_gtfs/matched" router = RaptorRouterCpp(gtfs_dir) source_station_departure_datetime = datetime(2024, 1, 1, 0, 4, 0) From 71d7c4cc41932a678b99cd9b252dd57799a06678 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 5 Jan 2026 14:50:19 +0100 Subject: [PATCH 13/31] Remove a duplicated global value and add a new self attribute to BasicIntermodalRequest --- src/demand/TravelerModels.py | 4 ++++ src/misc/globals.py | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 344f2339..51014037 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -771,6 +771,7 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE(self.modal_state_int) self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit + self.chosen_tpcs_phase = None def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: raw_transfer_station_ids = rq_row.get(G_RQ_TRANSFER_STATION_IDS, None) @@ -834,6 +835,7 @@ def record_data(self): record_dict[G_RQ_FARE] = self.fare record_dict[G_RQ_MODAL_STATE] = self.modal_state record_dict[G_RQ_MODAL_STATE_VALUE] = self.modal_state_int + record_dict[G_IM_OFFER_TYPE] = self.chosen_tpcs_phase return self._add_record(record_dict) def choose_offer(self, scenario_parameters, simulation_time): @@ -859,6 +861,7 @@ def choose_offer(self, scenario_parameters, simulation_time): return None elif len(opts) == 1: # only one offer: pure pt or amod+pt self.fare = self.offer[opts[0]].get(G_OFFER_FARE, 0) + self.chosen_tpcs_phase = self.offer[opts[0]].get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = opts[0] return opts[0] elif len(opts) == 2: # two offers: pure pt and amod+pt @@ -867,6 +870,7 @@ def choose_offer(self, scenario_parameters, simulation_time): op_id = operator_offer.operator_id if op_id != -2: self.fare = operator_offer.get(G_OFFER_FARE, 0) + self.chosen_tpcs_phase = operator_offer.get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = op_id return offer_id else: diff --git a/src/misc/globals.py b/src/misc/globals.py index 714f55d6..f8c33a22 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -600,7 +600,6 @@ class RQ_SUB_TRIP_ID(Enum): G_IM_OFFER_MOD_SUB = "im_mod_subsidy" G_IM_OFFER_OPERATOR_SUB_TRIP_TUPLE = "im_operator_sub_trip_tuple" # tuple of operator ids for each sub-trip: ((operator_id, sub_trip_id),) -G_IM_OFFER_TYPE = "im_offer_type" # type of multi offer: "default firstlastmile", "3phase firstlastmile" G_IM_OFFER_FLM_WAIT_0 = "im_t_wait_flm_0" # Only used for FM AMoD segment in FLM G_IM_OFFER_FLM_WAIT_1 = "im_t_wait_flm_1" # Only used for LM AMoD segment in FLM G_IM_OFFER_FLM_DRIVE_0 = "im_t_drive_flm_0" # Only used for FM AMoD segment in FLM From 2b3bed0e5382db7daf22e9e3c9361d6e5831c694 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 15 Jan 2026 18:12:43 +0100 Subject: [PATCH 14/31] Bug fix --- src/routing/pt/RaptorRouterCpp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routing/pt/RaptorRouterCpp.py b/src/routing/pt/RaptorRouterCpp.py index 35b399ed..a5beee40 100644 --- a/src/routing/pt/RaptorRouterCpp.py +++ b/src/routing/pt/RaptorRouterCpp.py @@ -173,8 +173,8 @@ def _get_included_stops_and_transfer_times(self, station_id: str) -> tp.Tuple[tp source_station_departure_datetime = datetime(2024, 1, 1, 0, 4, 0) import time start_time = time.time() - print(router.return_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=False)) + print(router.find_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=False)) print(f"Time taken: {time.time() - start_time} seconds") start_time = time.time() - print(router.return_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=True)) + print(router.find_fastest_pt_journey_1to1("s1", "s14", source_station_departure_datetime, 3, detailed=True)) print(f"Time taken: {time.time() - start_time} seconds") \ No newline at end of file From 1d17444ecfa857b8a5c15885ea219996257ba428 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 26 Jan 2026 17:04:25 +0100 Subject: [PATCH 15/31] feat: new PTBroker step 1 --- .../networks/osm_route_MVG_road/base/crs.info | 0 src/broker/PTBroker.py | 950 ++++++++++++++++++ src/misc/globals.py | 9 +- .../scenarios/constant_config_sod.csv | 0 4 files changed, 958 insertions(+), 1 deletion(-) mode change 100755 => 100644 data/networks/osm_route_MVG_road/base/crs.info create mode 100644 src/broker/PTBroker.py mode change 100755 => 100644 studies/example_study/scenarios/constant_config_sod.csv diff --git a/data/networks/osm_route_MVG_road/base/crs.info b/data/networks/osm_route_MVG_road/base/crs.info old mode 100755 new mode 100644 diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py new file mode 100644 index 00000000..984a235e --- /dev/null +++ b/src/broker/PTBroker.py @@ -0,0 +1,950 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import logging +from datetime import datetime, timedelta +import typing as tp +import pandas as pd +# additional module imports (> requirements) +# ------------------------------------------ + + +# src imports +# ----------- +from src.broker.BrokerBasic import BrokerBasic +from src.simulation.Offers import IntermodalOffer +if tp.TYPE_CHECKING: + from src.fleetctrl.FleetControlBase import FleetControlBase + from src.fleetctrl.planning.PlanRequest import PlanRequest + from src.ptctrl.PTControlBase import PTControlBase + from src.demand.demand import Demand + from src.routing.road.NetworkBase import NetworkBase + from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest + from src.simulation.Offers import TravellerOffer, PTOffer + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) +LARGE_INT = 100000000 +BUFFER_SIZE = 100 + +INPUT_PARAMETERS_PTBroker = { + "doc" : "this class represents a broker platform which handles intermodal requests", + "inherit" : BrokerBasic, + "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTBroker(BrokerBasic): + def __init__( + self, + n_amod_op: int, + amod_operators: tp.List['FleetControlBase'], + pt_operator: 'PTControlBase', + demand: 'Demand', + routing_engine: 'NetworkBase', + scenario_parameters: dict, + always_query_pt: bool = False, # TODO: make it a scenario parameter + ): + """ + The general attributes for the broker are initialized. + + Args: + n_amod_op (int): number of AMoD operators + amod_operators (tp.List['FleetControlBase']): list of AMoD operators + pt_operator (PTControlBase): PT operator + demand (Demand): demand object + routing_engine (NetworkBase): routing engine + scenario_parameters (dict): scenario parameters + always_query_pt (bool): if True, the pure PT offers are always requested + """ + super().__init__(n_amod_op, amod_operators) + + self.demand: Demand = demand + self.routing_engine: NetworkBase = routing_engine + self.pt_operator: PTControlBase = pt_operator + + self.pt_operator_id: int = self.pt_operator.pt_operator_id + self.scenario_parameters: dict = scenario_parameters + self.always_query_pt: bool = always_query_pt + + # set simulation start date for Raptor routing + self.sim_start_datetime: datetime = None + self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) + + # method for communication between AMoD and PT operators + comm_method_str: str = self.scenario_parameters.get(G_BROKER_COMM_METHOD, BROKER_COMM_METHOD.DUP.value) + try: + self.comm_method: BROKER_COMM_METHOD = BROKER_COMM_METHOD(comm_method_str) + except ValueError: + LOG.error(f"Invalid broker communication method: {comm_method_str}") + raise ValueError(f"Invalid broker communication method: {comm_method_str}") + + # method for finding transfer stations + self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") + # read necessary files based on the transfer search method + if self.transfer_search_method == "closest": + # load the street-station transfers: used for finding closest station to a street node, or vice versa + try: + self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) + except FileNotFoundError: + LOG.error("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + raise FileNotFoundError("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + + + def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): + """This method informs the broker that a new request has been made. + Based on the request modal state, the broker will create the appropriate sub-requests + and inform the operators. + + Args: + rid (int): parent request id + rq_obj (RequestBase): request object + sim_time (int): simulation time + """ + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") + + if self.always_query_pt: + # 1. query the PT operator for the pure PT travel costs + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) + + # 2.1 pure AMoD request or PT request + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.2 AMoD as firstmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.3 AMoD as lastmile request + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.4 AMoD as firstlastmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: + """This method collects the offers from the operators. + + Args: + rid (int): parent request id + sim_time (int): simulation time + Returns: + tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators + """ + # get parent request modal state + parent_rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + offers: tp.Dict[int, TravellerOffer] = {} + LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") + + # 1. collect PT offers for multimodal requests + if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) + LOG.debug(f"pt offer {pt_offer}") + + if pt_offer is not None and not pt_offer.service_declined(): + offers[self.pt_operator_id] = pt_offer + # register the pt offer in the sub-request + self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) + + # 2.1 collect AMoD offers for MONOMODAL and PT requests + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) + + # 2.2 collect AMoD offers for FIRSTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + # 2.3 collect AMoD offers for LASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) + + # 2.4 collect AMoD offers for FIRSTLASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + return offers + + def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: + """This method informs the broker that the user has booked a trip. + """ + amod_confirmed_rids = [] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + # 1. Pure PT offer has been selected + if chosen_operator == self.pt_operator_id: + amod_confirmed_rids.append((rid, rq_obj)) + + # inform all AMoD operators that the request is cancelled + self.inform_user_leaving_system(rid, sim_time) + + # inform PT operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) + # 2. AMoD involved offer has been selected + else: + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int + operator.user_cancels_request(rid, sim_time) + else: + operator.user_confirms_booking(rid, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + # inform the pt operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{sub_trip_id}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + + if parent_modal_state == RQ_MODAL_STATE.LASTMILE: + previous_amod_operator_id = None # no previous amod operator + else: # firstmile or firstlastmile + previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) + else: + # inform the amod operator that the request is confirmed + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + for i, operator in enumerate(self.amod_operators): + if i != operator_id: + operator.user_cancels_request(amod_rid_struct, sim_time) + else: + operator.user_confirms_booking(amod_rid_struct, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + return amod_confirmed_rids + + def inform_user_leaving_system(self, rid: int, sim_time: int): + """This method informs the broker that the user is leaving the system. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(rid, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(fm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(lm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) + operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): + """This method informs the operators that the waiting requests have been cancelled. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if chosen_operator == self.pt_operator_id: + return + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) + + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + continue + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + operator_id = int(operator_id) + self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): + """This method processes the new monomodal request. + + Args: + rid (int): the request id + rq_obj ('RequestBase'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + for op_id in range(self.n_amod_op): + LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(rq_obj, sim_time) + + def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): + """This method processes the new firstmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] + # create sub-request for PT + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") + # estimate the earliest start time of the pt sub-request + fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, rq_obj.get_destination_node(), fm_est_pt_mod, parent_modal_state, op_id) + + def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): + """This method processes the new lastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # create sub-request for PT + lm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_PT.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state) + + if lm_pt_arrival is not None: + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_AMOD.value, transfer_street_node, rq_obj.get_destination_node(), lm_pt_arrival, parent_modal_state, op_id, sim_time) + else: + LOG.info(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.LM_PT.value}, so the lastmile AMoD sub-request will not be created.") + + def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): + """This method processes the new firstlastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + # firstmile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] + # create sub-request for PT + # estimate the dropoff time of the amod sub-request + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") + # estimate the earliest start time of the pt sub-request + flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0,transfer_street_node_1, flm_est_pt_mod,parent_modal_state,op_id) + + # create sub-request for the same AMoD operator + if flm_pt_arrival is None: + raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") + else: + # last mile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) + + def _inform_amod_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int + ): + """ + This method informs the AMoD operators that a new sub-request has been made. + + Args: + rq_obj ('RequestBase'): the parent request object + sub_trip_id (int): the sub-trip id + leg_o_node (int): the origin node of the sub-request + leg_d_node (int): the destination node of the sub-request + leg_start_time (int): the start time of the sub-request + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) + + def _inform_pt_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None + ) -> tp.Optional[int]: + """ + This method informs the PT operator that a new sub-request has been made. + + Args: + rq_obj (RequestBase): the parent request object + sub_trip_id (int): the sub_trip id + leg_o_node (int): the origin street node of the sub-request + leg_d_node (int): the destination street node of the sub-request + leg_start_time (int): the start time [s] of the sub-request at the origin street node + parent_modal_state (RQ_MODAL_STATE): the parent modal state + firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests + Returns: + t_d_node_arrival (tp.Optional[int]): + the pt arrival time of the sub-request at the destination street node + or None if the pt travel costs are not available + """ + pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") + + costs_info = self._query_street_node_pt_travel_costs_1to1( + pt_sub_rq_obj.get_origin_node(), + pt_sub_rq_obj.get_destination_node(), + pt_sub_rq_obj.earliest_start_time, + pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest + ) + + if costs_info is not None: + source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") + else: + source_pt_station_id = None + t_source_walk = None + target_pt_station_id = None + t_target_walk = None + pt_journey_plan_dict = None + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") + + pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() + + self.pt_operator.create_and_record_pt_offer_db( + rid_struct = pt_rid_struct, + operator_id = self.pt_operator_id, + source_station_id = source_pt_station_id, + target_station_id = target_pt_station_id, + source_walking_time = t_source_walk, + target_walking_time = t_target_walk, + pt_journey_plan_dict = pt_journey_plan_dict, + firstmile_amod_operator_id = firstmile_amod_operator_id, + ) + if pt_journey_plan_dict is not None: + t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer + return t_d_node_arrival + else: + return None + + def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of monomodal offers. + + Args: + rid (int): the request id + parent_modal_state (RQ_MODAL_STATE): the parent modal state + offers (tp.Dict[int, TravellerOffer]): the current offers dictionary + Returns: + tp.Dict[int, TravellerOffer]: the updated offers dictionary + """ + for amod_op_id in range(self.n_amod_op): + amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) + LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") + if amod_offer is not None and not amod_offer.service_declined(): + offers[amod_op_id] = amod_offer + return offers + + def _process_collect_firstmile_offers_tpcs_phase1( + self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. + """ + # collect all offers + fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) + LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") + + fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) + LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") + + if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") + return None, None + + if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): + LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") + return None, fm_amod_offer_p1 + + if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + return intermodal_offer_p1, fm_amod_offer_p1 + + def _process_collect_firstmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstmile offers using TPCS approach. + """ + # get rid struct for all sections + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" + + for amod_op_id in range(self.n_amod_op): + # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! + # 1. Phase 1 + intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + # No amod offer in phase 1, skip to next amod operator + if fm_amod_offer_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.1 re-query the pt offer + # 2.1.1 get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # 2.1.2 determine the earliest start time of the pt sub-request + fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) + # 2.1.3 create the pt sub-request and get the pt arrival time + fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FM_PT.value, + transfer_street_node, + parent_rq_obj.get_destination_node(), + fm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) + if fm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.2 create intermodal offer + sub_trip_offers: tp.Dict[int, TravellerOffer] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of lastmile offers. + """ + # get lastmile pt offer + lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" + lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) + LOG.debug(f"Collecting lm_pt offer for request {lm_pt_rid_struct} from PT operator {self.pt_operator_id}: {lm_pt_offer}") + + if lm_pt_offer is not None and not lm_pt_offer.service_declined(): + # register the pt offer in the sub-request + self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for amod_op_id in range(self.n_amod_op): + # get lastmile amod offer + lm_amod_offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) + LOG.debug(f"Collecting lm_amod offer for request {lm_amod_rid_struct} from operator {amod_op_id}: {lm_amod_offer}") + + if lm_amod_offer is not None and not lm_amod_offer.service_declined(): + # register the amod offer in the sub-request + self.demand[lm_amod_rid_struct].receive_offer(amod_op_id, lm_amod_offer, None) + + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.LM_PT.value] = lm_pt_offer + sub_trip_offers[RQ_SUB_TRIP_ID.LM_AMOD.value] = lm_amod_offer + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + offers[intermodal_offer.operator_id] = intermodal_offer + else: + LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}") + else: + LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") + return offers + + def _process_collect_firstlastmile_offers_tpcs_phase1( + self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. + """ + flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) + LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") + + flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) + LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") + + flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) + LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") + + if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") + return None, None + + if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + else: + LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") + intermodal_offer_p1 = None + return intermodal_offer_p1, flm_amod_offer_0_p1 + + def _process_collect_firstlastmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstlastmile offers using 3-phases approach. + """ + # get rid struct for all sections + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + + for amod_op_id in range(self.n_amod_op): + # 1. Phase 1 + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + # No firstmile amod offer in phase 1, skip to next amod operator + if flm_amod_offer_0_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.0 cancel lastmile amod sub-request + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + + # 2.2 re-query the pt offer + # 2.2.1 get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # 2.2.2 determine the earliest start time of the pt sub-request + flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) + + # 2.2.3 create the pt sub-request and get the pt arrival time + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_PT.value, + transfer_street_node_0, + transfer_street_node_1, + flm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) + if flm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.3 re-query the lastmile amod offer + self._inform_amod_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_AMOD_1.value, + transfer_street_node_1, + parent_rq_obj.get_destination_node(), + flm_pt_arrival, + parent_modal_state, + amod_op_id, + sim_time, + ) + flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) + if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.4 create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _set_sim_start_datetime(self, sim_start_date: str): + """This method sets the simulation start date. + Converts the date string (format YYYYMMDD) to a datetime object. + + Args: + sim_start_date (str): the simulation start date in format YYYYMMDD + """ + if sim_start_date is None: + LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + + if type(sim_start_date) is not str: + sim_start_date = str(int(sim_start_date)) + self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") + + def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: + """This method returns the current datetime based on the simulation time in seconds. + """ + return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) + + def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific street station transfers file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The transfer data between the street nodes and the PT stations. + """ + dtypes = { + 'node_id': 'int', + 'closest_station_id': 'str', + 'street_station_transfer_time': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) + + def _query_street_node_pt_travel_costs_1to1( + self, o_node: int, d_node: int, est: int, + max_transfers: int = 999, detailed: bool = False + ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + """This method queries the pt travel costs between two street nodes at a given datetime. + The pt station ids will be the closest pt station ids to the street nodes. + + Args: + o_node (int): The origin street node id. + d_node (int): The destination street node id. + est (int): The earliest start time of the request at the origin street node in seconds. + max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. + detailed (bool): Whether to return detailed journey information. Defaults to False. + Returns: + tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + Returns a tuple containing: + (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) + if a public transport journey plan is found. + Returns None if no public transport journey plan is available. + """ + # find pt transfer stations + source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") + target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") + + source_station_departure_seconds: int = est + t_source_walk + source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) + LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( + source_pt_station_id, target_pt_station_id, + source_station_departure_datetime, + max_transfers, detailed, + ) + if pt_journey_plan_dict is None: + return None + else: + return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict + + def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: + """This method finds the transfer possibility between pt station and street node. + + Args: + node_id (tp.Union[int, str]): The street node id. + direction (str): "pt2street" or "street2pt" + Returns: + tp.Tuple[str, int]: The transfer node id and the walking time. + """ + if self.transfer_search_method == "closest": # closest station or street node + if direction == "street2pt": # find closest pt station from street node + street_node_id: int = int(node_id) + # TODO: allow multiple closest stations? + street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] + if street_station_transfer.empty: + raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") + closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] + walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] + return closest_station_id, walking_time + elif direction == "pt2street": # find closest street node from pt station + pt_station_id: str = str(node_id) + street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] + if street_station_transfers.empty: + raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") + # find the record with the minimum street_station_transfer_time + # TODO: if multiple exist, return all? + min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] + closest_street_node_id: int = min_transfer["node_id"] + walking_time: int = min_transfer["street_station_transfer_time"] + return closest_street_node_id, walking_time + else: + raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") + else: + LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") + raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") + + def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest', estimation_type: str = "latest") -> tp.Optional[int]: + """This method estimates the dropoff time of an amod sub-request. + + Args: + amod_op_id (int): the id of the amod operator + sub_rq_obj (BasicIntermodalRequest): the sub-request object + estimation_type (str): the type of the estimation + Returns: + int: the dropoff time of the sub-request + """ + # get amod dropoff time range + # TODO: add estimation type key in global variables + if estimation_type == "latest": + sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) + return sub_prq_obj.t_do_latest + else: + raise NotImplementedError(f"PTBrokerTPCS: AMod dropoff estimation type not implemented: {estimation_type}") + + def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: + """This method determines the earliest start time for the pt sub-request. + """ + t_est_pt_mod: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + self.amod_operators[amod_op_id].const_bt + return t_est_pt_mod + + def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: 'TravellerOffer', pt_waiting_time: int, old_t_do_latest: int) -> tp.Optional[int]: + """This method determines the latest dropoff time for the amod sub-request. + """ + t_do_latest: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + pt_waiting_time + # add latest dropoff time constraint check + if t_do_latest > old_t_do_latest: + t_do_latest = old_t_do_latest + return t_do_latest + + def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': + """This method merges the amod and pt offers into an intermodal offer. + """ + return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) + + def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: + """This method compares two intermodal offers based on availability and arrival time at destination node. + If offer_1 and offer_2 are both None, it returns 0. + If offer_1 is None and offer_2 is not None, it returns 2. + If offer_1 is not None and offer_2 is None, it returns 1. + If offer_1 is better than offer_2, it returns 1. + If offer_1 is worse than offer_2, it returns 2. + If offer_1 and offer_2 are equally good, it returns 2. + """ + if offer_1 is None and offer_2 is None: + return 0 + elif offer_1 is None and offer_2 is not None: + return 2 + elif offer_1 is not None and offer_2 is None: + return 1 + else: + duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) + duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) + if duration_p1 <= duration_p2: + return 1 + elif duration_p1 > duration_p2: + return 2 + else: + raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file diff --git a/src/misc/globals.py b/src/misc/globals.py index 714f55d6..052935c9 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -73,9 +73,16 @@ # broker specific attributes G_BROKER_TYPE = "broker_type" -G_BROKER_TPCS_USE_DEFAULT = "broker_tpcs_use_default" # if True, only Phase 1 of TPCS communication strategy is used +G_BROKER_COMM_METHOD = "broker_communication_method" # method for communication between AMoD and PT operators: "default", "tpcs" G_BROKER_TRANSFER_SEARCH_METHOD = "broker_transfer_search_method" # method for finding transfer stations: "closest" or "best_overall" +class BROKER_COMM_METHOD(Enum): + """ This enum is used to identify different communication methods between AMoD and PT operators. + """ + DUP: str = "Decoupled User-led Planning" + EI: str = "Estimation-based Integration" + DCC: str = "Dynamic Collaborative Coordination" + # public transport specific attributes G_PT_TYPE = "pt_type" G_GTFS_NAME = "gtfs_name" diff --git a/studies/example_study/scenarios/constant_config_sod.csv b/studies/example_study/scenarios/constant_config_sod.csv old mode 100755 new mode 100644 From 05e40e712d562656aec059924f06d3275486070a Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Wed, 28 Jan 2026 14:47:38 +0100 Subject: [PATCH 16/31] 1. update pt preprocessing directory path; 2. fix a bug that last mile leg can be a walking leg in PTRouter --- .../PTRouterGTFSPreperation.ipynb | 0 .../{pubtrans => pt}/PTScheduleGen.py | 0 .../route_193/193_line_alignment.geojson | 0 .../data/pubtrans/route_193/stations.csv | 0 src/routing/pt/cpp_raptor_router/Raptor.cpp | 35 +++++++++++-------- 5 files changed, 20 insertions(+), 15 deletions(-) rename src/preprocessing/{pubtrans => pt}/PTRouterGTFSPreperation.ipynb (100%) rename src/preprocessing/{pubtrans => pt}/PTScheduleGen.py (100%) rename src/preprocessing/{pubtrans => pt}/data/pubtrans/route_193/193_line_alignment.geojson (100%) rename src/preprocessing/{pubtrans => pt}/data/pubtrans/route_193/stations.csv (100%) diff --git a/src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb b/src/preprocessing/pt/PTRouterGTFSPreperation.ipynb similarity index 100% rename from src/preprocessing/pubtrans/PTRouterGTFSPreperation.ipynb rename to src/preprocessing/pt/PTRouterGTFSPreperation.ipynb diff --git a/src/preprocessing/pubtrans/PTScheduleGen.py b/src/preprocessing/pt/PTScheduleGen.py similarity index 100% rename from src/preprocessing/pubtrans/PTScheduleGen.py rename to src/preprocessing/pt/PTScheduleGen.py diff --git a/src/preprocessing/pubtrans/data/pubtrans/route_193/193_line_alignment.geojson b/src/preprocessing/pt/data/pubtrans/route_193/193_line_alignment.geojson similarity index 100% rename from src/preprocessing/pubtrans/data/pubtrans/route_193/193_line_alignment.geojson rename to src/preprocessing/pt/data/pubtrans/route_193/193_line_alignment.geojson diff --git a/src/preprocessing/pubtrans/data/pubtrans/route_193/stations.csv b/src/preprocessing/pt/data/pubtrans/route_193/stations.csv similarity index 100% rename from src/preprocessing/pubtrans/data/pubtrans/route_193/stations.csv rename to src/preprocessing/pt/data/pubtrans/route_193/stations.csv diff --git a/src/routing/pt/cpp_raptor_router/Raptor.cpp b/src/routing/pt/cpp_raptor_router/Raptor.cpp index 83dd7e08..c9ff4963 100644 --- a/src/routing/pt/cpp_raptor_router/Raptor.cpp +++ b/src/routing/pt/cpp_raptor_router/Raptor.cpp @@ -22,15 +22,6 @@ Raptor::Raptor(const std::unordered_map &agencies, const std::unordered_map &trips) : agencies_(agencies), services_(services), stops_(stops), routes_(routes), trips_(trips) { k = 1; - - // TODO: Remove this part - std::cout << "Raptor Router (C++): " - << "initialized with " - << agencies_.size() << " agencies, " - << services_.size() << " services, " - << stops_.size() << " stops, " - << routes_.size() << " routes, and " - << trips_.size() << " trips." << std::endl; } void Raptor::setQuery(const Query &query) { @@ -413,7 +404,13 @@ void Raptor::handleFootpaths() { int p_arrival = arrivals_[stop_id][k].arrival_seconds.value(); // For each footpath (p, p') - for (const auto &[dest_id, duration]: stops_[stop_id].getFootpaths()) { + for (const auto &[dest_id, duration]: stops_[stop_id].getFootpaths()) { + // DRT Constraint: Skip if destination is a target stop (prevents walking last leg) + if (included_target_ids_.find(dest_id) != included_target_ids_.end()) continue; + + // DRT Constraint: Skip if destination is a source stop (prevents walking first leg) + if (included_source_ids_.find(dest_id) != included_source_ids_.end()) continue; + int new_arrival = p_arrival + duration; if (improvesArrivalTime(new_arrival, dest_id)) { markStop(dest_id, new_arrival, std::nullopt, stop_id); @@ -548,18 +545,26 @@ Journey Raptor::reconstructJourney( } bool Raptor::isValidJourney(Journey journey) const { - // TODO: add more checks? - - if (journey.steps.empty()) + if (journey.steps.empty()) return false; - + // Get the starting stop ID of the journey std::string start_stop_id = journey.steps.front().src_stop->getField("stop_id"); - + // Check if the starting stop is one of the included source IDs if (included_source_ids_.find(start_stop_id) == included_source_ids_.end()) { return false; } + // DRT Constraint: First leg must be a vehicle trip (not walking) + if (!journey.steps.front().trip_id.has_value()) { + return false; + } + + // DRT Constraint: Last leg must be a vehicle trip (not walking) + if (!journey.steps.back().trip_id.has_value()) { + return false; + } + return true; } \ No newline at end of file From 58f88b8158ad314454f8d9cbe878fb9ffaa9ceca Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 29 Jan 2026 10:44:04 +0100 Subject: [PATCH 17/31] update the readme file, add compile instruction for the PT router --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bfc16301..aefe2e98 100644 --- a/README.md +++ b/README.md @@ -66,13 +66,20 @@ conda activate fleetpy ### 2️⃣ Install C++ Router (Recommended) -For improved routing efficiency, compile the C++ router: +For improved road network routing efficiency, compile the C++ road router: ```bash cd FleetPy/src/routing/road/cpp_router python setup.py build_ext --inplace ``` +To enable public transport routing, compile the C++ RAPTOR router: + +```bash +cd FleetPy/src/routing/pt/cpp_raptor_router +python setup.py build_ext --inplace +``` + **Ensure a C++ compiler and Cython are installed.** ### 3️⃣ Install Optimizer (Optional) From d06909ea46fec112b96d367a13057695fc98e838 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 30 Jan 2026 08:12:21 +0100 Subject: [PATCH 18/31] Move to win --- src/broker/PTBroker.py | 445 ++++++++++------------------------- src/demand/TravelerModels.py | 2 +- 2 files changed, 130 insertions(+), 317 deletions(-) diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index 984a235e..13674b8a 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -1,3 +1,7 @@ +# TODO: +# - Support dynamic adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. +# - Support multiple AMoD operators in the firstlastmile requests. + # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports # ----------------------------- @@ -80,17 +84,10 @@ def __init__( self.sim_start_datetime: datetime = None self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) - # method for communication between AMoD and PT operators - comm_method_str: str = self.scenario_parameters.get(G_BROKER_COMM_METHOD, BROKER_COMM_METHOD.DUP.value) - try: - self.comm_method: BROKER_COMM_METHOD = BROKER_COMM_METHOD(comm_method_str) - except ValueError: - LOG.error(f"Invalid broker communication method: {comm_method_str}") - raise ValueError(f"Invalid broker communication method: {comm_method_str}") - # method for finding transfer stations self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") # read necessary files based on the transfer search method + # default method: closest transfer station search. if self.transfer_search_method == "closest": # load the street-station transfers: used for finding closest station to a street node, or vice versa try: @@ -168,7 +165,7 @@ def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffe # 2.2 collect AMoD offers for FIRSTMILE requests elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + offers = self._process_collect_firstmile_offers(rid, parent_rq_obj, parent_modal_state, offers) # 2.3 collect AMoD offers for LASTMILE requests elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: @@ -176,7 +173,7 @@ def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffe # 2.4 collect AMoD offers for FIRSTLASTMILE requests elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + offers = self._process_collect_firstlastmile_offers(rid, parent_rq_obj, parent_modal_state, offers, sim_time) else: raise ValueError(f"Invalid modal state: {parent_modal_state}") @@ -301,7 +298,8 @@ def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim self.amod_operators[op_id].user_request(rq_obj, sim_time) def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): - """This method processes the new firstmile request. + """This method processes the new firstmile request. + In this stage, only the first-mile AMoD sub-request is created first; the PT sub-request will be created after receiving the AMoD offer. Args: rid (int): the request id @@ -316,17 +314,10 @@ def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRe # create sub-request for AMoD for op_id in range(self.n_amod_op): self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] - # create sub-request for PT - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") - # estimate the earliest start time of the pt sub-request - fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt - # create the pt sub-request - _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, rq_obj.get_destination_node(), fm_est_pt_mod, parent_modal_state, op_id) def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): """This method processes the new lastmile request. + First, the PT sub-request is created. If the PT offer is available, then the last-mile AMoD sub-request is created. Args: rid (int): the request id @@ -349,6 +340,7 @@ def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalReq def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): """This method processes the new firstlastmile request. + In this stage, only the first-mile AMoD sub-request is created first; the PT and last-mile AMoD sub-requests will be created after receiving the first-mile AMoD offer. Args: rid (int): the request id @@ -359,28 +351,11 @@ def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermod # get the transfer station ids and their closest pt stations transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") - # create sub-request for AMoD + # create FM sub-request for AMoD for op_id in range(self.n_amod_op): # firstmile AMoD sub-request - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] - # create sub-request for PT - # estimate the dropoff time of the amod sub-request - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") - # estimate the earliest start time of the pt sub-request - flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt - # create the pt sub-request - flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0,transfer_street_node_1, flm_est_pt_mod,parent_modal_state,op_id) - - # create sub-request for the same AMoD operator - if flm_pt_arrival is None: - raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") - else: - # last mile AMoD sub-request - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) def _inform_amod_sub_request( self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, @@ -477,74 +452,35 @@ def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MOD offers[amod_op_id] = amod_offer return offers - def _process_collect_firstmile_offers_tpcs_phase1( - self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. - """ - # collect all offers - fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) - self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) - LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") - - fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) - LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") - - if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): - LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") - return None, None - - if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): - LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") - return None, fm_amod_offer_p1 - - if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - return intermodal_offer_p1, fm_amod_offer_p1 - - def _process_collect_firstmile_offers_tpcs( + def _process_collect_firstmile_offers( self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, - offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + offers: tp.Dict[int, 'TravellerOffer'] ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstmile offers using TPCS approach. + """This method processes the collection of firstmile offers and try to optimize the waiting time of the PT leg. """ # get rid struct for all sections fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" fm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" for amod_op_id in range(self.n_amod_op): - # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! - # 1. Phase 1 - intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - # No amod offer in phase 1, skip to next amod operator - if fm_amod_offer_p1 is None: - continue + # collect FM offers + fm_amod_offer: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer}.") - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: + # check if FM AMoD offer is available + if fm_amod_offer is None or fm_amod_offer.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct}, skipping to next AMoD operator.") continue - else: - # 2. Phase 2 - # 2.1 re-query the pt offer - # 2.1.1 get the transfer station id and its closest pt station - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - - # 2.1.2 determine the earliest start time of the pt sub-request - fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) - # 2.1.3 create the pt sub-request and get the pt arrival time - fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + # register the FM AMoD offer in the sub-request + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer, None) + + # create PT sub-request and inform PT operator + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # determine the earliest start time of the PT sub-request based on the FM AMoD offer + fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer) + # inform PT operator + fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( parent_rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, @@ -553,67 +489,52 @@ def _process_collect_firstmile_offers_tpcs( parent_modal_state, amod_op_id, ) - fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) - if fm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.2 create intermodal offer - sub_trip_offers: tp.Dict[int, TravellerOffer] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") - - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 - - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") + fm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + # check if PT offer is available + if fm_pt_arrival is None or fm_pt_offer is None or fm_pt_offer.service_declined(): + LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct}, skipping to next AMoD operator.") + continue + # register the PT offer in the sub-request + self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer, None) + + # create intermodal offer + sub_trip_offers: tp.Dict[int, TravellerOffer] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer for request {rid}: {intermodal_offer}") + + # update FM latest dropoff time based on the PT offer + sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer, fm_pt_offer.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + # add intermodal offer to offers dictionary + offers[intermodal_offer.operator_id] = intermodal_offer + return offers def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of lastmile offers. + """This method processes the collection of LM offers. """ - # get lastmile pt offer + # get LM PT offer lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) LOG.debug(f"Collecting lm_pt offer for request {lm_pt_rid_struct} from PT operator {self.pt_operator_id}: {lm_pt_offer}") if lm_pt_offer is not None and not lm_pt_offer.service_declined(): - # register the pt offer in the sub-request + # register the PT offer in the sub-request self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) + + # get LM AMoD offers lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" for amod_op_id in range(self.n_amod_op): - # get lastmile amod offer lm_amod_offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) LOG.debug(f"Collecting lm_amod offer for request {lm_amod_rid_struct} from operator {amod_op_id}: {lm_amod_offer}") if lm_amod_offer is not None and not lm_amod_offer.service_declined(): - # register the amod offer in the sub-request + # register the LM AMoD offer in the sub-request self.demand[lm_amod_rid_struct].receive_offer(amod_op_id, lm_amod_offer, None) # create intermodal offer @@ -623,51 +544,16 @@ def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODA intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) offers[intermodal_offer.operator_id] = intermodal_offer else: - LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}") + LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}, skipping to next AMoD operator.") else: LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") return offers - def _process_collect_firstlastmile_offers_tpcs_phase1( - self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. - """ - flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) - self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) - LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") - - flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) - LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") - - flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) - LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") - - if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") - return None, None - - if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - else: - LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") - intermodal_offer_p1 = None - return intermodal_offer_p1, flm_amod_offer_0_p1 - - def _process_collect_firstlastmile_offers_tpcs( + def _process_collect_firstlastmile_offers( self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer'], sim_time: int ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstlastmile offers using 3-phases approach. + """This method processes the collection of firstlastmile offers. """ # get rid struct for all sections flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" @@ -675,106 +561,77 @@ def _process_collect_firstlastmile_offers_tpcs( flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" for amod_op_id in range(self.n_amod_op): - # 1. Phase 1 - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - # No firstmile amod offer in phase 1, skip to next amod operator - if flm_amod_offer_0_p1 is None: - continue + # collect FM AMoD offer + flm_amod_offer_0: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0}.") - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: + if flm_amod_offer_0 is None or flm_amod_offer_0.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {flm_amod_rid_struct_0}, skipping to next AMoD operator.") continue - else: - # 2. Phase 2 - # 2.0 cancel lastmile amod sub-request - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - - # 2.2 re-query the pt offer - # 2.2.1 get the transfer station ids and their closest pt stations - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") - - # 2.2.2 determine the earliest start time of the pt sub-request - flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) - - # 2.2.3 create the pt sub-request and get the pt arrival time - flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + # register the FM AMoD offer in the sub-request + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0, None) + + # create PT sub-request and inform PT operator + # get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + # determine the earliest start time of the PT sub-request based on the FM AMoD offer + flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0) + # inform PT operator + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_PT.value, + RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0, - transfer_street_node_1, + transfer_street_node_1, flm_est_pt_mod, parent_modal_state, amod_op_id, ) - flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) - if flm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.3 re-query the lastmile amod offer - self._inform_amod_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_AMOD_1.value, - transfer_street_node_1, - parent_rq_obj.get_destination_node(), - flm_pt_arrival, - parent_modal_state, - amod_op_id, - sim_time, - ) - flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) - if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.4 create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") - - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 - - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") + flm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + # check if PT offer is available + if flm_pt_arrival is None or flm_pt_offer is None or flm_pt_offer.service_declined(): + LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct}, skipping to next AMoD operator.") + continue + # register the PT offer in the sub-request + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer, None) + + # create LM AMoD sub-request and inform AMoD operator + self._inform_amod_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_AMOD_1.value, + transfer_street_node_1, + parent_rq_obj.get_destination_node(), + flm_pt_arrival, + parent_modal_state, + amod_op_id, + sim_time, + ) + flm_amod_offer_1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + # check if LM AMoD offer is available + if flm_amod_offer_1 is None or flm_amod_offer_1.service_declined(): + LOG.info(f"LM AMoD offer is not available for sub_request {flm_amod_rid_struct_1}, skipping to next AMoD operator.") + continue + # register the LM AMoD offer in the sub-request + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1, None) + + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1 + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer for request {rid}: {intermodal_offer}") + + # update FM latest dropoff time based on the PT offer + sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0, flm_pt_offer.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + # add intermodal offer to offers dictionary + offers[intermodal_offer.operator_id] = intermodal_offer + return offers def _set_sim_start_datetime(self, sim_start_date: str): @@ -885,25 +742,6 @@ def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") - def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest', estimation_type: str = "latest") -> tp.Optional[int]: - """This method estimates the dropoff time of an amod sub-request. - - Args: - amod_op_id (int): the id of the amod operator - sub_rq_obj (BasicIntermodalRequest): the sub-request object - estimation_type (str): the type of the estimation - Returns: - int: the dropoff time of the sub-request - """ - # get amod dropoff time range - # TODO: add estimation type key in global variables - if estimation_type == "latest": - sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() - sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) - return sub_prq_obj.t_do_latest - else: - raise NotImplementedError(f"PTBrokerTPCS: AMod dropoff estimation type not implemented: {estimation_type}") - def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: """This method determines the earliest start time for the pt sub-request. """ @@ -922,29 +760,4 @@ def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': """This method merges the amod and pt offers into an intermodal offer. """ - return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) - - def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: - """This method compares two intermodal offers based on availability and arrival time at destination node. - If offer_1 and offer_2 are both None, it returns 0. - If offer_1 is None and offer_2 is not None, it returns 2. - If offer_1 is not None and offer_2 is None, it returns 1. - If offer_1 is better than offer_2, it returns 1. - If offer_1 is worse than offer_2, it returns 2. - If offer_1 and offer_2 are equally good, it returns 2. - """ - if offer_1 is None and offer_2 is None: - return 0 - elif offer_1 is None and offer_2 is not None: - return 2 - elif offer_1 is not None and offer_2 is None: - return 1 - else: - duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) - duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) - if duration_p1 <= duration_p2: - return 1 - elif duration_p1 > duration_p2: - return 2 - else: - raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file + return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) \ No newline at end of file diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 51014037..2d10c41d 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -859,7 +859,7 @@ def choose_offer(self, scenario_parameters, simulation_time): operator_offer is not None and not operator_offer.service_declined()] if len(opts) == 0: return None - elif len(opts) == 1: # only one offer: pure pt or amod+pt + elif len(opts) == 1: # only one offer: pure amod, pt or amod+pt self.fare = self.offer[opts[0]].get(G_OFFER_FARE, 0) self.chosen_tpcs_phase = self.offer[opts[0]].get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = opts[0] From fc0a9ee78382285d5cc09cd1a8f182d897817fc9 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 30 Jan 2026 13:33:21 +0100 Subject: [PATCH 19/31] Basic Collaborative Coordination --- src/broker/PTBroker.py | 5 ++++- src/demand/TravelerModels.py | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index 13674b8a..95eae307 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -199,14 +199,17 @@ def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, ch self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) # 2. AMoD involved offer has been selected else: + # non-intermodal offer has been selected if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: for i, operator in enumerate(self.amod_operators): - if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int + if i != chosen_operator: # Non-intermodal requests: the chosen operator has the data type int operator.user_cancels_request(rid, sim_time) else: operator.user_confirms_booking(rid, sim_time) amod_confirmed_rids.append((rid, rq_obj)) + # intermodal offer has been selected elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + # chosen_operator has the data type tuple: ((operator_id, sub_trip_id), ...) for operator_id, sub_trip_id in chosen_operator: if operator_id == self.pt_operator_id: # inform the pt operator that the request is confirmed diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 2d10c41d..9cdca669 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -863,6 +863,7 @@ def choose_offer(self, scenario_parameters, simulation_time): self.fare = self.offer[opts[0]].get(G_OFFER_FARE, 0) self.chosen_tpcs_phase = self.offer[opts[0]].get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = opts[0] + # offer_id is a tuple: ((operator_id, sub_trip_id), ...) return opts[0] elif len(opts) == 2: # two offers: pure pt and amod+pt # always choose amod+pt @@ -872,6 +873,7 @@ def choose_offer(self, scenario_parameters, simulation_time): self.fare = operator_offer.get(G_OFFER_FARE, 0) self.chosen_tpcs_phase = operator_offer.get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = op_id + # offer_id is a tuple: ((operator_id, sub_trip_id), ...) return offer_id else: LOG.error(f"not implemented {offer_str(self.offer)}") From 27b8673ccd05d04fd39a3fa8f378d055bf2a0fdb Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 30 Jan 2026 14:39:19 +0100 Subject: [PATCH 20/31] Enable customizable wait time for last mile AMoD pickups --- src/broker/PTBroker.py | 10 +++++++++- src/demand/TravelerModels.py | 4 ++++ src/fleetctrl/PoolingIRSOnly.py | 8 ++++++-- src/misc/globals.py | 9 +-------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index 95eae307..d017dd90 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -377,7 +377,15 @@ def _inform_amod_sub_request( """ amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) + + # get customizable wait time for last mile AMoD pickups + if parent_modal_state == RQ_MODAL_STATE.LASTMILE or (parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE and sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value): + # in this case, the parent request type must be BasicIntermodalRequest + max_wait_time: tp.Optional[int] = rq_obj.get_lastmile_max_wait_time() + else: + max_wait_time: tp.Optional[int] = None + + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time, max_wait_time=max_wait_time) def _inform_pt_sub_request( self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 9cdca669..ed9cdb9c 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -772,6 +772,7 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit self.chosen_tpcs_phase = None + self.lastmile_max_wait_time: tp.Optional[int] = rq_row.get(G_IM_LM_WAIT_TIME, None) # the customizable max waiting time for lastmile amod service def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: raw_transfer_station_ids = rq_row.get(G_RQ_TRANSFER_STATION_IDS, None) @@ -786,6 +787,9 @@ def get_transfer_station_ids(self) -> tp.Optional[tp.List[str]]: def get_max_transfers(self) -> int: return self.max_transfers + def get_lastmile_max_wait_time(self) -> tp.Optional[int]: + return self.lastmile_max_wait_time + def record_data(self): record_dict = {} # input diff --git a/src/fleetctrl/PoolingIRSOnly.py b/src/fleetctrl/PoolingIRSOnly.py index 4789d795..bbc383bb 100644 --- a/src/fleetctrl/PoolingIRSOnly.py +++ b/src/fleetctrl/PoolingIRSOnly.py @@ -85,7 +85,7 @@ def receive_status_update(self, vid, simulation_time, list_finished_VRL, force_u self.pos_veh_dict[veh_obj.pos] = [veh_obj] LOG.debug(f"veh {veh_obj} | after status update: {self.veh_plans[vid]}") - def user_request(self, rq, sim_time): + def user_request(self, rq, sim_time, max_wait_time=None): """This method is triggered for a new incoming request. It generally adds the rq to the database. It has to return an offer to the user. This operator class only works with immediate responses and therefore either sends an offer or a rejection. @@ -94,14 +94,18 @@ def user_request(self, rq, sim_time): :type rq: RequestDesign :param sim_time: current simulation time :type sim_time: float + :param max_wait_time: maximum wait time (for LM leg of intermodal requests); None if not specified + :type max_wait_time: float or None :return: offer :rtype: TravellerOffer """ t0 = time.perf_counter() LOG.debug(f"Incoming request {rq.__dict__} at time {sim_time}") self.sim_time = sim_time + if max_wait_time is None: # if not specified, use operator default settings + max_wait_time = self.max_wait_time prq = PlanRequest(rq, self.routing_engine, min_wait_time=self.min_wait_time, - max_wait_time=self.max_wait_time, + max_wait_time=max_wait_time, max_detour_time_factor=self.max_dtf, max_constant_detour_time=self.max_cdt, add_constant_detour_time=self.add_cdt, min_detour_time_window=self.min_dtw, boarding_time=self.const_bt) diff --git a/src/misc/globals.py b/src/misc/globals.py index 067c8077..fe50ad1b 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -73,16 +73,8 @@ # broker specific attributes G_BROKER_TYPE = "broker_type" -G_BROKER_COMM_METHOD = "broker_communication_method" # method for communication between AMoD and PT operators: "default", "tpcs" G_BROKER_TRANSFER_SEARCH_METHOD = "broker_transfer_search_method" # method for finding transfer stations: "closest" or "best_overall" -class BROKER_COMM_METHOD(Enum): - """ This enum is used to identify different communication methods between AMoD and PT operators. - """ - DUP: str = "Decoupled User-led Planning" - EI: str = "Estimation-based Integration" - DCC: str = "Dynamic Collaborative Coordination" - # public transport specific attributes G_PT_TYPE = "pt_type" G_GTFS_NAME = "gtfs_name" @@ -159,6 +151,7 @@ class BROKER_COMM_METHOD(Enum): G_IM_MIN_MOD_DISTANCE = "min_IM_MOD_distance" G_IM_PER_KM_SUBSIDY = "subsidy_IM_MOD_per_km" G_IM_TRANSFER_TIME = "im_transfer_time" +G_IM_LM_WAIT_TIME = "im_lastmile_wait_time" # customizable wait time for last mile AMoD pickup # operator general attributes From 9fc7680a08e7abe6b3aec13fd33a46397120d347 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 30 Jan 2026 14:42:19 +0100 Subject: [PATCH 21/31] Update initialization mehtod of PTBroker --- src/FleetSimulationBase.py | 6 +++--- src/misc/init_modules.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index 3a449b9c..f2f570c4 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -466,12 +466,12 @@ def _load_broker_module(self): LOG.info(prt_msg) BrokerClass = load_broker_module("BrokerBasic") self.broker = BrokerClass(self.n_op, self.operators) - elif broker_type == "PTBrokerTPCS": - prt_msg: str = "PTBroker specified, using PTBrokerTPCS" + elif broker_type == "PTBroker": + prt_msg: str = "PTBroker specified, using PTBroker" LOG.info(prt_msg) if self.pt_operator is None: raise ValueError("PT operator should be loaded before loading PTBroker.") - BrokerClass = load_broker_module("PTBrokerTPCS") + BrokerClass = load_broker_module("PTBroker") self.broker = BrokerClass(self.n_op, self.operators, self.pt_operator, self.demand, self.routing_engine, self.scenario_parameters) else: raise ValueError(f"Unknown broker type: {broker_type}!") diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index a320fb45..5c80bd88 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -118,7 +118,7 @@ def get_src_broker_modules(): # FleetPy broker options broker_dict = {} # str -> (module path, class name) broker_dict["BrokerBasic"] = ("src.broker.BrokerBasic", "BrokerBasic") - broker_dict["PTBrokerTPCS"] = ("src.broker.PTBrokerTPCS", "PTBrokerTPCS") + broker_dict["PTBroker"] = ("src.broker.PTBroker", "PTBroker") # add development content if dev_content is not None: dev_broker_dict = dev_content.add_broker_modules() From 31b3e52f14497010113ef856ec993081d8b1369e Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 2 Feb 2026 09:47:51 +0100 Subject: [PATCH 22/31] - Bugfix: PTBroker - Feat: Intermodal evaluation --- .../example_100_intermodal_lmwt30.csv | 101 ++ src/broker/PTBroker.py | 6 +- src/broker/PTBrokerTPCS.py | 945 ------------------ src/demand/TravelerModels.py | 5 - src/evaluation/intermodal.py | 670 ++++++++++--- src/misc/globals.py | 1 - .../example_study/scenarios/example_im.csv | 6 +- 7 files changed, 613 insertions(+), 1121 deletions(-) create mode 100644 data/demand/example_demand/matched/example_network/example_100_intermodal_lmwt30.csv delete mode 100644 src/broker/PTBrokerTPCS.py diff --git a/data/demand/example_demand/matched/example_network/example_100_intermodal_lmwt30.csv b/data/demand/example_demand/matched/example_network/example_100_intermodal_lmwt30.csv new file mode 100644 index 00000000..91f60a81 --- /dev/null +++ b/data/demand/example_demand/matched/example_network/example_100_intermodal_lmwt30.csv @@ -0,0 +1,101 @@ +rq_time,start,end,request_id,is_multimodal,modal_state_value,transfer_station_ids,max_transfers,im_lastmile_wait_time +194,2966,2977,0,1,2,s15,1,30.0 +217,2966,2973,1,0,0,-1,1, +301,2976,2966,2,1,1,s15,1, +388,2982,2980,3,0,0,-1,1, +397,2977,2968,4,1,3,s15;s1,1,30.0 +679,2966,2985,5,1,2,s15,1,30.0 +890,2993,2988,6,0,0,-1,1, +896,2966,2973,7,1,2,s15,1,30.0 +933,2977,2986,8,1,3,s15;s1,1,30.0 +959,2976,2982,9,0,0,-1,1, +983,2977,2966,10,1,1,s15,1, +1085,2966,2981,11,1,2,s15,1,30.0 +1092,2992,2980,12,0,0,-1,1, +1185,2987,2984,13,0,0,-1,1, +1204,2966,2981,14,1,2,s15,1,30.0 +1320,2993,2980,15,1,1,s1,1, +1449,2977,2967,16,1,3,s15;s1,1,30.0 +1511,2984,2966,17,1,1,s15,1, +1514,2989,2977,18,1,3,s1;s15,1,30.0 +1558,2989,2975,19,1,3,s1;s15,1,30.0 +1587,2981,2979,20,0,0,-1,1, +1659,2978,2966,21,1,1,s15,1, +1668,2966,2982,22,1,2,s15,1,30.0 +1681,2967,2980,23,1,1,s1,1, +1725,2966,2977,24,1,2,s15,1,30.0 +1735,2990,2982,25,1,3,s1;s15,1,30.0 +2045,2980,2993,26,1,2,s1,1,30.0 +2045,2969,2993,27,0,0,-1,1, +2127,2973,2966,28,1,1,s15,1, +2198,2966,2976,29,1,2,s15,1,30.0 +2309,2986,2966,30,1,1,s15,1, +2383,2989,2978,31,1,3,s1;s15,1,30.0 +2416,2981,2969,32,1,3,s15;s1,1,30.0 +2494,2992,2980,33,1,1,s1,1, +2540,2980,2970,34,1,2,s1,1,30.0 +2626,2990,2988,35,1,3,s1;s15,1,30.0 +2727,2972,2985,36,0,0,-1,1, +2803,2970,2972,37,0,0,-1,1, +2881,2993,2980,38,1,1,s1,1, +2912,2992,2982,39,1,3,s1;s15,1,30.0 +2947,2990,2981,40,0,0,-1,1, +3008,2966,2982,41,1,2,s15,1,30.0 +3064,2986,2970,42,0,0,-1,1, +3088,2973,2966,43,1,1,s15,1, +3109,2967,2981,44,1,3,s1;s15,1,30.0 +3303,2980,2971,45,1,2,s1,1,30.0 +3373,2976,2987,46,0,0,-1,1, +3437,2971,2966,47,1,1,s15,1, +3616,2966,2982,48,1,2,s15,1,30.0 +3637,2983,2966,49,1,1,s15,1, +3725,2974,2966,50,1,1,s15,1, +3846,2966,2988,51,1,2,s15,1,30.0 +3855,2969,2979,52,1,3,s1;s15,1,30.0 +3881,2980,2990,53,1,2,s1,1,30.0 +4260,2980,2992,54,1,2,s1,1,30.0 +4325,2972,2991,55,0,0,-1,1, +4341,2979,2969,56,1,3,s15;s1,1,30.0 +4394,2983,2967,57,1,3,s15;s1,1,30.0 +4464,2981,2971,58,0,0,-1,1, +4476,2966,2981,59,1,2,s15,1,30.0 +4564,2980,2969,60,1,2,s1,1,30.0 +4621,2979,2968,61,1,3,s15;s1,1,30.0 +4642,2991,2980,62,1,1,s1,1, +4722,2989,2967,63,0,0,-1,1, +4877,2978,2992,64,1,3,s15;s1,1,30.0 +4944,2980,2972,65,1,2,s1,1,30.0 +4960,2979,2966,66,1,1,s15,1, +4984,2987,2966,67,1,1,s15,1, +4997,2980,2992,68,1,2,s1,1,30.0 +5118,2968,2980,69,1,1,s1,1, +5177,2993,2977,70,1,3,s1;s15,1,30.0 +5237,2985,2967,71,1,3,s15;s1,1,30.0 +5401,2967,2981,72,0,0,-1,1, +5459,2980,2969,73,1,2,s1,1,30.0 +5470,2969,2979,74,0,0,-1,1, +5486,2984,2993,75,1,3,s15;s1,1,30.0 +5505,2984,2992,76,1,3,s15;s1,1,30.0 +5531,2986,2966,77,1,1,s15,1, +5541,2970,2981,78,1,3,s1;s15,1,30.0 +5563,2978,2975,79,0,0,-1,1, +5571,2980,2993,80,1,2,s1,1,30.0 +5580,2984,2969,81,0,0,-1,1, +5622,2970,2980,82,1,1,s1,1, +5637,2975,2976,83,0,0,-1,1, +5701,2966,2987,84,1,2,s15,1,30.0 +5726,2971,2978,85,0,0,-1,1, +5788,2969,2982,86,1,3,s1;s15,1,30.0 +6062,2978,2993,87,1,3,s15;s1,1,30.0 +6252,2966,2982,88,1,2,s15,1,30.0 +6437,2992,2980,89,0,0,-1,1, +6580,2982,2966,90,1,1,s15,1, +6617,2973,2982,91,0,0,-1,1, +6648,2973,2966,92,1,1,s15,1, +6685,2967,2974,93,1,3,s1;s15,1,30.0 +6707,2968,2991,94,0,0,-1,1, +6850,2966,2987,95,1,2,s15,1,30.0 +6886,2991,2980,96,1,1,s1,1, +6910,2983,2993,97,1,3,s15;s1,1,30.0 +6944,2976,2966,98,1,1,s15,1, +7152,2988,2980,99,1,1,s1,1, diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index d017dd90..e81782c7 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -259,7 +259,11 @@ def inform_user_leaving_system(self, rid: int, sim_time: int): flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" for _, operator in enumerate(self.amod_operators): operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) - operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + try: + operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + except KeyError: + # LM AMoD sub-request may not be created if no PT offer is available + LOG.info(f"LM AMoD sub-request {flm_amod_rid_struct_1} not found when user leaves system, possibly no FM or PT offer available so the LM sub-request was not created.") else: raise ValueError(f"Invalid modal state: {parent_modal_state}") diff --git a/src/broker/PTBrokerTPCS.py b/src/broker/PTBrokerTPCS.py deleted file mode 100644 index a2ebeca5..00000000 --- a/src/broker/PTBrokerTPCS.py +++ /dev/null @@ -1,945 +0,0 @@ -# -------------------------------------------------------------------------------------------------------------------- # -# standard distribution imports -# ----------------------------- -import logging -from datetime import datetime, timedelta -import typing as tp -import pandas as pd -# additional module imports (> requirements) -# ------------------------------------------ - - -# src imports -# ----------- -from src.broker.BrokerBasic import BrokerBasic -from src.simulation.Offers import IntermodalOffer -if tp.TYPE_CHECKING: - from src.fleetctrl.FleetControlBase import FleetControlBase - from src.fleetctrl.planning.PlanRequest import PlanRequest - from src.ptctrl.PTControlBase import PTControlBase - from src.demand.demand import Demand - from src.routing.road.NetworkBase import NetworkBase - from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest - from src.simulation.Offers import TravellerOffer, PTOffer - -# -------------------------------------------------------------------------------------------------------------------- # -# global variables -# ---------------- -from src.misc.globals import * - -LOG = logging.getLogger(__name__) -LARGE_INT = 100000000 -BUFFER_SIZE = 100 - -INPUT_PARAMETERS_PTBroker = { - "doc" : "this class represents a broker platform which handles intermodal requests", - "inherit" : BrokerBasic, - "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], - "input_parameters_optional": [], - "mandatory_modules": [], - "optional_modules": [] -} - -# -------------------------------------------------------------------------------------------------------------------- # -# main -# ---- -class PTBrokerTPCS(BrokerBasic): - def __init__( - self, - n_amod_op: int, - amod_operators: tp.List['FleetControlBase'], - pt_operator: 'PTControlBase', - demand: 'Demand', - routing_engine: 'NetworkBase', - scenario_parameters: dict, - always_query_pt: bool = False, # TODO: make it a scenario parameter - ): - """ - The general attributes for the broker are initialized. - - Args: - n_amod_op (int): number of AMoD operators - amod_operators (tp.List['FleetControlBase']): list of AMoD operators - pt_operator (PTControlBase): PT operator - demand (Demand): demand object - routing_engine (NetworkBase): routing engine - scenario_parameters (dict): scenario parameters - always_query_pt (bool): if True, the pure PT offers are always requested - """ - super().__init__(n_amod_op, amod_operators) - - self.demand: Demand = demand - self.routing_engine: NetworkBase = routing_engine - self.pt_operator: PTControlBase = pt_operator - - self.pt_operator_id: int = self.pt_operator.pt_operator_id - self.scenario_parameters: dict = scenario_parameters - self.always_query_pt: bool = always_query_pt - - # set simulation start date for Raptor routing - self.sim_start_datetime: datetime = None - self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) - - # check whether only Phase 1 is used - self.use_phase_1_only: bool = self.scenario_parameters.get(G_BROKER_TPCS_USE_DEFAULT, False) - - # method for finding transfer stations - self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") - # read necessary files based on the transfer search method - if self.transfer_search_method == "closest": - # load the street-station transfers: used for finding closest station to a street node, or vice versa - try: - self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) - except FileNotFoundError: - LOG.error("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - raise FileNotFoundError("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - - - def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): - """This method informs the broker that a new request has been made. - Based on the request modal state, the broker will create the appropriate sub-requests - and inform the operators. - - Args: - rid (int): parent request id - rq_obj (RequestBase): request object - sim_time (int): simulation time - """ - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") - - if self.always_query_pt: - # 1. query the PT operator for the pure PT travel costs - _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) - - # 2.1 pure AMoD request or PT request - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.2 AMoD as firstmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.3 AMoD as lastmile request - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.4 AMoD as firstlastmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: - """This method collects the offers from the operators. - - Args: - rid (int): parent request id - sim_time (int): simulation time - Returns: - tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators - """ - # get parent request modal state - parent_rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() - offers: tp.Dict[int, TravellerOffer] = {} - LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") - - # 1. collect PT offers for multimodal requests - if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) - LOG.debug(f"pt offer {pt_offer}") - - if pt_offer is not None and not pt_offer.service_declined(): - offers[self.pt_operator_id] = pt_offer - # register the pt offer in the sub-request - self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) - - # 2.1 collect AMoD offers for MONOMODAL and PT requests - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) - - # 2.2 collect AMoD offers for FIRSTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) - - # 2.3 collect AMoD offers for LASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) - - # 2.4 collect AMoD offers for FIRSTLASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - return offers - - def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: - """This method informs the broker that the user has booked a trip. - """ - amod_confirmed_rids = [] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - # 1. Pure PT offer has been selected - if chosen_operator == self.pt_operator_id: - amod_confirmed_rids.append((rid, rq_obj)) - - # inform all AMoD operators that the request is cancelled - self.inform_user_leaving_system(rid, sim_time) - - # inform PT operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) - # 2. AMoD involved offer has been selected - else: - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for i, operator in enumerate(self.amod_operators): - if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int - operator.user_cancels_request(rid, sim_time) - else: - operator.user_confirms_booking(rid, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - # inform the pt operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{sub_trip_id}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - - if parent_modal_state == RQ_MODAL_STATE.LASTMILE: - previous_amod_operator_id = None # no previous amod operator - else: # firstmile or firstlastmile - previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) - else: - # inform the amod operator that the request is confirmed - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - for i, operator in enumerate(self.amod_operators): - if i != operator_id: - operator.user_cancels_request(amod_rid_struct, sim_time) - else: - operator.user_confirms_booking(amod_rid_struct, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - return amod_confirmed_rids - - def inform_user_leaving_system(self, rid: int, sim_time: int): - """This method informs the broker that the user is leaving the system. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(rid, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(fm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(lm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) - operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): - """This method informs the operators that the waiting requests have been cancelled. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if chosen_operator == self.pt_operator_id: - return - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) - - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - continue - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - operator_id = int(operator_id) - self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): - """This method processes the new monomodal request. - - Args: - rid (int): the request id - rq_obj ('RequestBase'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - for op_id in range(self.n_amod_op): - LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(rq_obj, sim_time) - - def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): - """This method processes the new firstmile request. - - Args: - rid (int): the request id - rq_obj ('BasicIntermodalRequest'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - # get the transfer station id and its closest pt station - transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() - transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - - # create sub-request for AMoD - for op_id in range(self.n_amod_op): - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] - # create sub-request for PT - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") - # estimate the earliest start time of the pt sub-request - fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt - # create the pt sub-request - _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, rq_obj.get_destination_node(), fm_est_pt_mod, parent_modal_state, op_id) - - def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): - """This method processes the new lastmile request. - - Args: - rid (int): the request id - rq_obj ('BasicIntermodalRequest'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - # get the transfer station id and its closest pt station - transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() - transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - # create sub-request for PT - lm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_PT.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state) - - if lm_pt_arrival is not None: - # create sub-request for AMoD - for op_id in range(self.n_amod_op): - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_AMOD.value, transfer_street_node, rq_obj.get_destination_node(), lm_pt_arrival, parent_modal_state, op_id, sim_time) - else: - LOG.info(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.LM_PT.value}, so the lastmile AMoD sub-request will not be created.") - - def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): - """This method processes the new firstlastmile request. - - Args: - rid (int): the request id - rq_obj ('BasicIntermodalRequest'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - # get the transfer station ids and their closest pt stations - transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() - transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") - - # create sub-request for AMoD - for op_id in range(self.n_amod_op): - # firstmile AMoD sub-request - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] - # create sub-request for PT - # estimate the dropoff time of the amod sub-request - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") - # estimate the earliest start time of the pt sub-request - flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt - # create the pt sub-request - flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0,transfer_street_node_1, flm_est_pt_mod,parent_modal_state,op_id) - - # create sub-request for the same AMoD operator - if flm_pt_arrival is None: - raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") - else: - # last mile AMoD sub-request - self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) - - def _inform_amod_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int - ): - """ - This method informs the AMoD operators that a new sub-request has been made. - - Args: - rq_obj ('RequestBase'): the parent request object - sub_trip_id (int): the sub-trip id - leg_o_node (int): the origin node of the sub-request - leg_d_node (int): the destination node of the sub-request - leg_start_time (int): the start time of the sub-request - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) - - def _inform_pt_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None - ) -> tp.Optional[int]: - """ - This method informs the PT operator that a new sub-request has been made. - - Args: - rq_obj (RequestBase): the parent request object - sub_trip_id (int): the sub_trip id - leg_o_node (int): the origin street node of the sub-request - leg_d_node (int): the destination street node of the sub-request - leg_start_time (int): the start time [s] of the sub-request at the origin street node - parent_modal_state (RQ_MODAL_STATE): the parent modal state - firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests - Returns: - t_d_node_arrival (tp.Optional[int]): - the pt arrival time of the sub-request at the destination street node - or None if the pt travel costs are not available - """ - pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") - - costs_info = self._query_street_node_pt_travel_costs_1to1( - pt_sub_rq_obj.get_origin_node(), - pt_sub_rq_obj.get_destination_node(), - pt_sub_rq_obj.earliest_start_time, - pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest - ) - - if costs_info is not None: - source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") - else: - source_pt_station_id = None - t_source_walk = None - target_pt_station_id = None - t_target_walk = None - pt_journey_plan_dict = None - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") - - pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() - - self.pt_operator.create_and_record_pt_offer_db( - rid_struct = pt_rid_struct, - operator_id = self.pt_operator_id, - source_station_id = source_pt_station_id, - target_station_id = target_pt_station_id, - source_walking_time = t_source_walk, - target_walking_time = t_target_walk, - pt_journey_plan_dict = pt_journey_plan_dict, - firstmile_amod_operator_id = firstmile_amod_operator_id, - ) - if pt_journey_plan_dict is not None: - t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer - return t_d_node_arrival - else: - return None - - def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of monomodal offers. - - Args: - rid (int): the request id - parent_modal_state (RQ_MODAL_STATE): the parent modal state - offers (tp.Dict[int, TravellerOffer]): the current offers dictionary - Returns: - tp.Dict[int, TravellerOffer]: the updated offers dictionary - """ - for amod_op_id in range(self.n_amod_op): - amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) - LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") - if amod_offer is not None and not amod_offer.service_declined(): - offers[amod_op_id] = amod_offer - return offers - - def _process_collect_firstmile_offers_tpcs_phase1( - self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. - """ - # collect all offers - fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) - self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) - LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") - - fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) - LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") - - if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): - LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") - return None, None - - if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): - LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") - return None, fm_amod_offer_p1 - - if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - return intermodal_offer_p1, fm_amod_offer_p1 - - def _process_collect_firstmile_offers_tpcs( - self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, - offers: tp.Dict[int, 'TravellerOffer'], sim_time: int - ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstmile offers using TPCS approach. - """ - # get rid struct for all sections - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - fm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" - - for amod_op_id in range(self.n_amod_op): - # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! - # 1. Phase 1 - intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - # No amod offer in phase 1, skip to next amod operator - if fm_amod_offer_p1 is None: - continue - - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: - continue - else: - # 2. Phase 2 - # 2.1 re-query the pt offer - # 2.1.1 get the transfer station id and its closest pt station - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - - # 2.1.2 determine the earliest start time of the pt sub-request - fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) - # 2.1.3 create the pt sub-request and get the pt arrival time - fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FM_PT.value, - transfer_street_node, - parent_rq_obj.get_destination_node(), - fm_est_pt_mod, - parent_modal_state, - amod_op_id, - ) - fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) - if fm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.2 create intermodal offer - sub_trip_offers: tp.Dict[int, TravellerOffer] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") - - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 - - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") - return offers - - def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of lastmile offers. - """ - # get lastmile pt offer - lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" - lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) - LOG.debug(f"Collecting lm_pt offer for request {lm_pt_rid_struct} from PT operator {self.pt_operator_id}: {lm_pt_offer}") - - if lm_pt_offer is not None and not lm_pt_offer.service_declined(): - # register the pt offer in the sub-request - self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) - lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" - for amod_op_id in range(self.n_amod_op): - # get lastmile amod offer - lm_amod_offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) - LOG.debug(f"Collecting lm_amod offer for request {lm_amod_rid_struct} from operator {amod_op_id}: {lm_amod_offer}") - - if lm_amod_offer is not None and not lm_amod_offer.service_declined(): - # register the amod offer in the sub-request - self.demand[lm_amod_rid_struct].receive_offer(amod_op_id, lm_amod_offer, None) - - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.LM_PT.value] = lm_pt_offer - sub_trip_offers[RQ_SUB_TRIP_ID.LM_AMOD.value] = lm_amod_offer - intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - offers[intermodal_offer.operator_id] = intermodal_offer - else: - LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}") - else: - LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") - return offers - - def _process_collect_firstlastmile_offers_tpcs_phase1( - self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. - """ - flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) - self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) - LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") - - flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) - LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") - - flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) - LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") - - if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") - return None, None - - if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - else: - LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") - intermodal_offer_p1 = None - return intermodal_offer_p1, flm_amod_offer_0_p1 - - def _process_collect_firstlastmile_offers_tpcs( - self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, - offers: tp.Dict[int, 'TravellerOffer'], sim_time: int - ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstlastmile offers using 3-phases approach. - """ - # get rid struct for all sections - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" - flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" - - for amod_op_id in range(self.n_amod_op): - # 1. Phase 1 - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - # No firstmile amod offer in phase 1, skip to next amod operator - if flm_amod_offer_0_p1 is None: - continue - - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: - continue - else: - # 2. Phase 2 - # 2.0 cancel lastmile amod sub-request - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - - # 2.2 re-query the pt offer - # 2.2.1 get the transfer station ids and their closest pt stations - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") - - # 2.2.2 determine the earliest start time of the pt sub-request - flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) - - # 2.2.3 create the pt sub-request and get the pt arrival time - flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_PT.value, - transfer_street_node_0, - transfer_street_node_1, - flm_est_pt_mod, - parent_modal_state, - amod_op_id, - ) - flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) - if flm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.3 re-query the lastmile amod offer - self._inform_amod_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_AMOD_1.value, - transfer_street_node_1, - parent_rq_obj.get_destination_node(), - flm_pt_arrival, - parent_modal_state, - amod_op_id, - sim_time, - ) - flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) - if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.4 create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") - - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 - - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") - return offers - - def _set_sim_start_datetime(self, sim_start_date: str): - """This method sets the simulation start date. - Converts the date string (format YYYYMMDD) to a datetime object. - - Args: - sim_start_date (str): the simulation start date in format YYYYMMDD - """ - if sim_start_date is None: - LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - - if type(sim_start_date) is not str: - sim_start_date = str(int(sim_start_date)) - self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") - - def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: - """This method returns the current datetime based on the simulation time in seconds. - """ - return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) - - def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: - """This method loads the FleetPy-specific street station transfers file. - - Args: - gtfs_dir (str): The directory containing the GTFS data of the operator. - Returns: - pd.DataFrame: The transfer data between the street nodes and the PT stations. - """ - dtypes = { - 'node_id': 'int', - 'closest_station_id': 'str', - 'street_station_transfer_time': 'int', - } - return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) - - def _query_street_node_pt_travel_costs_1to1( - self, o_node: int, d_node: int, est: int, - max_transfers: int = 999, detailed: bool = False - ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - """This method queries the pt travel costs between two street nodes at a given datetime. - The pt station ids will be the closest pt station ids to the street nodes. - - Args: - o_node (int): The origin street node id. - d_node (int): The destination street node id. - est (int): The earliest start time of the request at the origin street node in seconds. - max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. - detailed (bool): Whether to return detailed journey information. Defaults to False. - Returns: - tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - Returns a tuple containing: - (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) - if a public transport journey plan is found. - Returns None if no public transport journey plan is available. - """ - # find pt transfer stations - source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") - target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") - - source_station_departure_seconds: int = est + t_source_walk - source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) - LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") - pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( - source_pt_station_id, target_pt_station_id, - source_station_departure_datetime, - max_transfers, detailed, - ) - if pt_journey_plan_dict is None: - return None - else: - return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict - - def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: - """This method finds the transfer possibility between pt station and street node. - - Args: - node_id (tp.Union[int, str]): The street node id. - direction (str): "pt2street" or "street2pt" - Returns: - tp.Tuple[str, int]: The transfer node id and the walking time. - """ - if self.transfer_search_method == "closest": # closest station or street node - if direction == "street2pt": # find closest pt station from street node - street_node_id: int = int(node_id) - # TODO: allow multiple closest stations? - street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] - if street_station_transfer.empty: - raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") - closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] - walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] - return closest_station_id, walking_time - elif direction == "pt2street": # find closest street node from pt station - pt_station_id: str = str(node_id) - street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] - if street_station_transfers.empty: - raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") - # find the record with the minimum street_station_transfer_time - # TODO: if multiple exist, return all? - min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] - closest_street_node_id: int = min_transfer["node_id"] - walking_time: int = min_transfer["street_station_transfer_time"] - return closest_street_node_id, walking_time - else: - raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") - else: - LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") - raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") - - def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest', estimation_type: str = "latest") -> tp.Optional[int]: - """This method estimates the dropoff time of an amod sub-request. - - Args: - amod_op_id (int): the id of the amod operator - sub_rq_obj (BasicIntermodalRequest): the sub-request object - estimation_type (str): the type of the estimation - Returns: - int: the dropoff time of the sub-request - """ - # get amod dropoff time range - # TODO: add estimation type key in global variables - if estimation_type == "latest": - sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() - sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) - return sub_prq_obj.t_do_latest - else: - raise NotImplementedError(f"PTBrokerTPCS: AMod dropoff estimation type not implemented: {estimation_type}") - - def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: - """This method determines the earliest start time for the pt sub-request. - """ - t_est_pt_mod: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + self.amod_operators[amod_op_id].const_bt - return t_est_pt_mod - - def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: 'TravellerOffer', pt_waiting_time: int, old_t_do_latest: int) -> tp.Optional[int]: - """This method determines the latest dropoff time for the amod sub-request. - """ - t_do_latest: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + pt_waiting_time - # add latest dropoff time constraint check - if t_do_latest > old_t_do_latest: - t_do_latest = old_t_do_latest - return t_do_latest - - def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': - """This method merges the amod and pt offers into an intermodal offer. - """ - return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) - - def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: - """This method compares two intermodal offers based on availability and arrival time at destination node. - If offer_1 and offer_2 are both None, it returns 0. - If offer_1 is None and offer_2 is not None, it returns 2. - If offer_1 is not None and offer_2 is None, it returns 1. - If offer_1 is better than offer_2, it returns 1. - If offer_1 is worse than offer_2, it returns 2. - If offer_1 and offer_2 are equally good, it returns 2. - """ - if offer_1 is None and offer_2 is None: - return 0 - elif offer_1 is None and offer_2 is not None: - return 2 - elif offer_1 is not None and offer_2 is None: - return 1 - else: - duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) - duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) - if duration_p1 <= duration_p2: - return 1 - elif duration_p1 > duration_p2: - return 2 - else: - raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index ed9cdb9c..445c80df 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -771,7 +771,6 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE(self.modal_state_int) self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit - self.chosen_tpcs_phase = None self.lastmile_max_wait_time: tp.Optional[int] = rq_row.get(G_IM_LM_WAIT_TIME, None) # the customizable max waiting time for lastmile amod service def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: @@ -837,9 +836,7 @@ def record_data(self): record_dict[G_RQ_PU] = self.pu_time record_dict[G_RQ_DO] = self.do_time record_dict[G_RQ_FARE] = self.fare - record_dict[G_RQ_MODAL_STATE] = self.modal_state record_dict[G_RQ_MODAL_STATE_VALUE] = self.modal_state_int - record_dict[G_IM_OFFER_TYPE] = self.chosen_tpcs_phase return self._add_record(record_dict) def choose_offer(self, scenario_parameters, simulation_time): @@ -865,7 +862,6 @@ def choose_offer(self, scenario_parameters, simulation_time): return None elif len(opts) == 1: # only one offer: pure amod, pt or amod+pt self.fare = self.offer[opts[0]].get(G_OFFER_FARE, 0) - self.chosen_tpcs_phase = self.offer[opts[0]].get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = opts[0] # offer_id is a tuple: ((operator_id, sub_trip_id), ...) return opts[0] @@ -875,7 +871,6 @@ def choose_offer(self, scenario_parameters, simulation_time): op_id = operator_offer.operator_id if op_id != -2: self.fare = operator_offer.get(G_OFFER_FARE, 0) - self.chosen_tpcs_phase = operator_offer.get(G_IM_OFFER_TYPE, None) self.chosen_operator_id = op_id # offer_id is a tuple: ((operator_id, sub_trip_id), ...) return offer_id diff --git a/src/evaluation/intermodal.py b/src/evaluation/intermodal.py index 791a96bd..fc41f511 100644 --- a/src/evaluation/intermodal.py +++ b/src/evaluation/intermodal.py @@ -1,204 +1,542 @@ -import pandas as pd -import numpy as np import os -import re import sys import glob +import numpy as np +import pandas as pd +import re MAIN_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(MAIN_DIR) -from src.evaluation.standard import read_op_output_file, read_user_output_file, create_vehicle_type_db from src.misc.globals import * -DEFAULT_AMOD_OP_ID = 0 - +# Import constants from standard evaluation EURO_PER_TON_OF_CO2 = 145 # from BVWP2030 Modulhandbuch (page 113) EMISSION_CPG = 145 * 100 / 1000**2 ENERGY_EMISSIONS = 112 # g/kWh from https://www.swm.de/dam/swm/dokumente/geschaeftskunden/broschuere-strom-erdgas-gk.pdf PV_G_CO2_KM = 130 # g/km from https://www.ris-muenchen.de/RII/RII/DOK/ANTRAG/2337762.pdf with 60:38 benzin vs diesel +def calculate_pt_wait_time(fm_amod_row, pt_row): + """Calculate PT wait time for a given request based on its sub-trips. + Defines wait time as: (PT Pick-up - AMoD Drop-off) - Required Transfer Time + Station Waiting Time. (Note: PT Pick-up refers to the source station departure time). + """ + amod_dropoff_time = fm_amod_row.get(G_RQ_DO, np.nan) + pt_pickup_time = pt_row.get(G_RQ_PU, np.nan) + + pt_offer_str = pt_row.get(G_RQ_OFFERS, None) + if pt_offer_str is not None and not pd.isna(pt_offer_str): + pt_station_wait_time = int(re.search(r't_wait:(\d+)', pt_offer_str).group(1)) + source_walking_time = int(re.search(r'source_walking_time:(\d+)', pt_offer_str).group(1)) + pt_wait_time = (pt_pickup_time - amod_dropoff_time) - source_walking_time + pt_station_wait_time + return max(pt_wait_time, 0) + return np.nan + +def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_end_time=None, print_comments=False): + """ + Pre-processing step: Aggregate sub-trips into parent requests. -# TODO: extend evaluation with more KPIs -def intermodal_evaluation(output_dir, evaluation_start_time = None, evaluation_end_time = None, print_comments=False, dir_names_in = {}): - """This function runs a standard evaluation over a scenario output directory for intermodal scenarios. - Currently, only few KPIs are implemented and only for scenarios with one AMoD operator. + Logic: + - Group by request_id + - A parent request is "served" ONLY if all its mandatory legs are served + - Sum/aggregate metrics from sub-trips to parent level + - Save detailed leg information for analysis :param output_dir: scenario output directory - :param start_time: start time of evaluation interval in s (if None, then evaluation of all data from sim start) - :param end_time: end time of evaluation interval in s (if None, then evaluation of all data until sim end) - :param print_comments: print some comments about status in between + :param evaluation_start_time: start time filter + :param evaluation_end_time: end time filter + :param print_comments: print status messages + :return: parent_df - DataFrame with aggregated parent request data + """ + if print_comments: + print("Creating parent user stats from sub-trips...") + + # Read original user stats + user_stats_file = os.path.join(output_dir, "1_user-stats.csv") + df = pd.read_csv(user_stats_file) + + # Apply time filters + if evaluation_start_time is not None: + df = df[df[G_RQ_TIME] >= evaluation_start_time] + if evaluation_end_time is not None: + df = df[df[G_RQ_TIME] < evaluation_end_time] + + # Separate parent requests and sub-trips + parent_df = df[df[G_RQ_IS_PARENT_REQUEST] == True].copy() + subtrip_df = df[df[G_RQ_IS_PARENT_REQUEST] == False].copy() + + if print_comments: + print(f" Found {len(parent_df)} parent requests and {len(subtrip_df)} sub-trips") + + # For each parent request, aggregate sub-trip information + parent_rows = [] + + for parent_idx, parent_row in parent_df.iterrows(): + request_id = parent_row[G_RQ_ID] + modal_state = parent_row.get(G_RQ_MODAL_STATE_VALUE, np.nan) + + # Get all sub-trips for this request + sub_trips = subtrip_df[subtrip_df[G_RQ_ID] == request_id] + + # Create aggregated parent row + parent_agg = parent_row.to_dict() + + # Determine if request is served + # For MONOMODAL (0), parent itself determines if served + # For intermodal (FM=1, LM=2, FLM=3), check if all mandatory sub-trips are served + is_served = False + total_fare = 0 + total_wait_time = 0 + total_travel_time = 0 + + # Store leg-specific information + leg_info = {} + + if modal_state == RQ_MODAL_STATE.MONOMODAL.value: + # MONOMODAL: parent row has all information + is_served = not pd.isna(parent_row.get(G_RQ_PU)) + if is_served: + total_fare = parent_row.get(G_RQ_FARE, 0) + total_wait_time = parent_row.get(G_RQ_PU, 0) - parent_row.get(G_RQ_TIME, 0) + total_travel_time = parent_row.get(G_RQ_DO, 0) - parent_row.get(G_RQ_PU, 0) + + elif modal_state == RQ_MODAL_STATE.FIRSTMILE.value: + # FM: Need FM_AMOD (1) and FM_PT (2) + fm_amod = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.FM_AMOD.value] + fm_pt = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.FM_PT.value] + + if len(fm_amod) > 0 and len(fm_pt) > 0: + fm_amod_row = fm_amod.iloc[0] + fm_pt_row = fm_pt.iloc[0] + + # Both legs must be served + fm_amod_served = not pd.isna(fm_amod_row.get(G_RQ_PU)) + fm_pt_served = not pd.isna(fm_pt_row.get(G_RQ_PU)) + is_served = fm_amod_served and fm_pt_served + + if is_served: + # Aggregate metrics + total_fare = fm_amod_row.get(G_RQ_FARE, 0) + fm_pt_row.get(G_RQ_FARE, 0) + + # Wait time for FM_AMOD leg + fm_amod_wait = fm_amod_row.get(G_RQ_PU, 0) - fm_amod_row.get(G_RQ_TIME, 0) + + # Wait time for PT leg (waiting for PT after AMoD dropoff) + fm_pt_wait = calculate_pt_wait_time(fm_amod_row, fm_pt_row) + + total_wait_time = fm_amod_wait + fm_pt_wait + + # Total travel time from AMoD pickup to PT drop-off + total_travel_time = fm_pt_row.get(G_RQ_DO, 0) - fm_amod_row.get(G_RQ_PU, 0) + + # Store leg info + leg_info['fm_amod_pu'] = fm_amod_row.get(G_RQ_PU) + leg_info['fm_amod_do'] = fm_amod_row.get(G_RQ_DO) + leg_info['fm_amod_wait'] = fm_amod_wait + leg_info['fm_amod_fare'] = fm_amod_row.get(G_RQ_FARE, 0) + leg_info['fm_pt_pu'] = fm_pt_row.get(G_RQ_PU) + leg_info['fm_pt_do'] = fm_pt_row.get(G_RQ_DO) + leg_info['fm_pt_wait'] = fm_pt_wait + leg_info['fm_pt_fare'] = fm_pt_row.get(G_RQ_FARE, 0) + + elif modal_state == RQ_MODAL_STATE.LASTMILE.value: + # LM: Need LM_PT (3) and LM_AMOD (4) + lm_pt = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.LM_PT.value] + lm_amod = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.LM_AMOD.value] + + if len(lm_pt) > 0 and len(lm_amod) > 0: + lm_pt_row = lm_pt.iloc[0] + lm_amod_row = lm_amod.iloc[0] + + lm_pt_served = not pd.isna(lm_pt_row.get(G_RQ_PU)) + lm_amod_served = not pd.isna(lm_amod_row.get(G_RQ_PU)) + is_served = lm_pt_served and lm_amod_served + + if is_served: + total_fare = lm_pt_row.get(G_RQ_FARE, 0) + lm_amod_row.get(G_RQ_FARE, 0) + + # Wait time for PT leg + pt_offer_str = lm_pt_row.get(G_RQ_OFFERS, None) + lm_pt_wait = int(re.search(r't_wait:(\d+)', pt_offer_str).group(1)) + + # Wait time for LM AMoD (waiting for AMoD) + lm_pt_target_walking_time = int(re.search(r'target_walking_time:(\d+)', pt_offer_str).group(1)) + lm_amod_wait = lm_amod_row.get(G_RQ_PU, 0) - lm_pt_row.get(G_RQ_DO, 0) - lm_pt_target_walking_time + + total_wait_time = lm_pt_wait + lm_amod_wait + # Total travel time from PT pickup to AMoD drop-off + total_travel_time = lm_amod_row.get(G_RQ_DO, 0) - lm_pt_row.get(G_RQ_PU, 0) + + # Store leg info + leg_info['lm_pt_pu'] = lm_pt_row.get(G_RQ_PU) + leg_info['lm_pt_do'] = lm_pt_row.get(G_RQ_DO) + leg_info['lm_pt_wait'] = lm_pt_wait + leg_info['lm_pt_fare'] = lm_pt_row.get(G_RQ_FARE, 0) + leg_info['lm_amod_pu'] = lm_amod_row.get(G_RQ_PU) + leg_info['lm_amod_do'] = lm_amod_row.get(G_RQ_DO) + leg_info['lm_amod_wait'] = lm_amod_wait + leg_info['lm_amod_fare'] = lm_amod_row.get(G_RQ_FARE, 0) + + elif modal_state == RQ_MODAL_STATE.FIRSTLASTMILE.value: + # FLM: Need FLM_AMOD_0 (5), FLM_PT (6), FLM_AMOD_1 (7) + flm_amod_0 = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.FLM_AMOD_0.value] + flm_pt = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.FLM_PT.value] + flm_amod_1 = sub_trips[sub_trips[G_RQ_SUB_TRIP_ID] == RQ_SUB_TRIP_ID.FLM_AMOD_1.value] + + if len(flm_amod_0) > 0 and len(flm_pt) > 0 and len(flm_amod_1) > 0: + flm_amod_0_row = flm_amod_0.iloc[0] + flm_pt_row = flm_pt.iloc[0] + flm_amod_1_row = flm_amod_1.iloc[0] + + flm_amod_0_served = not pd.isna(flm_amod_0_row.get(G_RQ_PU)) + flm_pt_served = not pd.isna(flm_pt_row.get(G_RQ_PU)) + flm_amod_1_served = not pd.isna(flm_amod_1_row.get(G_RQ_PU)) + is_served = flm_amod_0_served and flm_pt_served and flm_amod_1_served + + if is_served: + total_fare = (flm_amod_0_row.get(G_RQ_FARE, 0) + + flm_pt_row.get(G_RQ_FARE, 0) + + flm_amod_1_row.get(G_RQ_FARE, 0)) + + # Wait times + flm_amod_0_wait = flm_amod_0_row.get(G_RQ_PU, 0) - flm_amod_0_row.get(G_RQ_TIME, 0) + flm_pt_wait = calculate_pt_wait_time(flm_amod_0_row, flm_pt_row) + flm_pt_offer_str = flm_pt_row.get(G_RQ_OFFERS, None) + flm_pt_target_walking_time = int(re.search(r'target_walking_time:(\d+)', flm_pt_offer_str).group(1)) + # Wait time for FLM_AMOD_1 (waiting for AMoD): LM AMoD pickup - PT drop-off - target walking time + flm_amod_1_wait = flm_amod_1_row.get(G_RQ_PU, 0) - flm_pt_row.get(G_RQ_DO, 0) - flm_pt_target_walking_time + + total_wait_time = flm_amod_0_wait + flm_pt_wait + flm_amod_1_wait + # Total travel time from first AMoD pickup to last AMoD drop-off + total_travel_time = flm_amod_1_row.get(G_RQ_DO, 0) - flm_amod_0_row.get(G_RQ_PU, 0) + + # Store leg info + leg_info['flm_amod_0_pu'] = flm_amod_0_row.get(G_RQ_PU) + leg_info['flm_amod_0_do'] = flm_amod_0_row.get(G_RQ_DO) + leg_info['flm_amod_0_wait'] = flm_amod_0_wait + leg_info['flm_amod_0_fare'] = flm_amod_0_row.get(G_RQ_FARE, 0) + leg_info['flm_pt_pu'] = flm_pt_row.get(G_RQ_PU) + leg_info['flm_pt_do'] = flm_pt_row.get(G_RQ_DO) + leg_info['flm_pt_wait'] = flm_pt_wait + leg_info['flm_pt_fare'] = flm_pt_row.get(G_RQ_FARE, 0) + leg_info['flm_amod_1_pu'] = flm_amod_1_row.get(G_RQ_PU) + leg_info['flm_amod_1_do'] = flm_amod_1_row.get(G_RQ_DO) + leg_info['flm_amod_1_wait'] = flm_amod_1_wait + leg_info['flm_amod_1_fare'] = flm_amod_1_row.get(G_RQ_FARE, 0) + + # Update parent aggregation with computed values + parent_agg['is_served'] = is_served + parent_agg['total_fare'] = total_fare if is_served else np.nan + parent_agg['total_wait_time'] = total_wait_time if is_served else np.nan + parent_agg['total_travel_time'] = total_travel_time if is_served else np.nan + + # Add leg info as columns + for key, val in leg_info.items(): + parent_agg[key] = val + + parent_rows.append(parent_agg) + + # Create parent DataFrame + parent_result_df = pd.DataFrame(parent_rows) + + # Save to file + parent_output_file = os.path.join(output_dir, "1_user-stats_parent.csv") + parent_result_df.to_csv(parent_output_file, index=False) + + if print_comments: + print(f" Saved parent user stats to: {parent_output_file}") + print(f" Served requests: {parent_result_df['is_served'].sum()} / {len(parent_result_df)}") + + return parent_result_df + + +def categorize_modal_state(modal_state_value): + """Categorize request based on modal state value.""" + if pd.isna(modal_state_value): + return 'Unknown' + modal_state_value = int(modal_state_value) + if modal_state_value == RQ_MODAL_STATE.MONOMODAL.value: + return 'DRT_only' + elif modal_state_value == RQ_MODAL_STATE.FIRSTMILE.value: + return 'FM' + elif modal_state_value == RQ_MODAL_STATE.LASTMILE.value: + return 'LM' + elif modal_state_value == RQ_MODAL_STATE.FIRSTLASTMILE.value: + return 'FLM' + elif modal_state_value == RQ_MODAL_STATE.PT.value: + return 'PT_only' + else: + return 'Unknown' + + +def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end_time=None, print_comments=False, dir_names_in={}): + """ + Main intermodal evaluation function. + + Follows the same pattern as standard_evaluation but: + 1. Pre-processes user stats to create parent request aggregations + 2. Calculates standard metrics on parent requests + 3. Adds intermodal-specific metrics + + :param output_dir: scenario output directory + :param evaluation_start_time: start time filter + :param evaluation_end_time: end time filter + :param print_comments: print status messages + :param dir_names_in: directory dictionary (optional) + :return: result DataFrame """ if not os.path.isdir(output_dir): raise IOError(f"Could not find result directory {output_dir}!") - + + # Load scenario configuration scenario_parameters, list_operator_attributes, _ = load_scenario_inputs(output_dir) dir_names = get_directory_dict(scenario_parameters, list_operator_attributes, abs_fleetpy_dir=MAIN_DIR) if dir_names_in: dir_names = dir_names_in - # evaluation interval + # Evaluation interval if evaluation_start_time is None and scenario_parameters.get(G_EVAL_INT_START) is not None: evaluation_start_time = int(scenario_parameters[G_EVAL_INT_START]) if evaluation_end_time is None and scenario_parameters.get(G_EVAL_INT_END) is not None: evaluation_end_time = int(scenario_parameters[G_EVAL_INT_END]) - # vehicle type data + # Vehicle type data + from src.evaluation.standard import create_vehicle_type_db, read_op_output_file, avg_in_vehicle_distance, shared_rides veh_type_db = create_vehicle_type_db(dir_names[G_DIR_VEH]) veh_type_stats = pd.read_csv(os.path.join(output_dir, "2_vehicle_types.csv")) - # user stats if print_comments: - print(f"Evaluating {scenario_parameters[G_SCENARIO_NAME]}\nReading user stats ...") - - user_stats = read_user_output_file(output_dir, evaluation_start_time=evaluation_start_time, evaluation_end_time=evaluation_end_time) - parent_user_stats = user_stats[user_stats[G_RQ_IS_PARENT_REQUEST] == True].copy() + print(f"Evaluating {scenario_parameters[G_SCENARIO_NAME]}") + print("="*80) + + # Step 1: Create parent user stats + parent_user_stats = create_parent_user_stats(output_dir, evaluation_start_time, evaluation_end_time, print_comments) + + # Add passenger column if needed + if G_RQ_PAX not in parent_user_stats.columns: + parent_user_stats[G_RQ_PAX] = 1 + + # Filter to only served requests for metrics + served_requests = parent_user_stats[parent_user_stats['is_served'] == True].copy() if print_comments: - print(f"\t shape of user stats: {user_stats.shape}") - print(f"\t shape of parent user stats: {parent_user_stats.shape}") - - result_dict_list = [] - operator_names = [] - - result_dict = {} - - # ---------------------------- User stats -------------------------------- - num_parent_requests = parent_user_stats.shape[0] - served_parent_requests = parent_user_stats[parent_user_stats[G_RQ_CHOSEN_OP_ID].notna()].copy() - num_served_parent_requests = served_parent_requests.shape[0] - - # Average service rate - average_service_rate = num_served_parent_requests / num_parent_requests if num_parent_requests > 0 else 0.0 - result_dict["average_service_rate"] = average_service_rate - - # Average FLM request service rate - flm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.FIRSTLASTMILE.value].copy() - num_flm_parent_requests = flm_parent_requests.shape[0] - served_flm_parent_requests = flm_parent_requests[flm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() - num_served_flm_parent_requests = served_flm_parent_requests.shape[0] - average_flm_service_rate = num_served_flm_parent_requests / num_flm_parent_requests if num_flm_parent_requests > 0 else 0.0 - result_dict["average_flm_service_rate"] = average_flm_service_rate - - # Average FM request service rate - fm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.FIRSTMILE.value].copy() - num_fm_parent_requests = fm_parent_requests.shape[0] - served_fm_parent_requests = fm_parent_requests[fm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() - num_served_fm_parent_requests = served_fm_parent_requests.shape[0] - average_fm_service_rate = num_served_fm_parent_requests / num_fm_parent_requests if num_fm_parent_requests > 0 else 0.0 - result_dict["average_fm_service_rate"] = average_fm_service_rate - - # Average LM request service rate - lm_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.LASTMILE.value].copy() - num_lm_parent_requests = lm_parent_requests.shape[0] - served_lm_parent_requests = lm_parent_requests[lm_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() - num_served_lm_parent_requests = served_lm_parent_requests.shape[0] - average_lm_service_rate = num_served_lm_parent_requests / num_lm_parent_requests if num_lm_parent_requests > 0 else 0.0 - result_dict["average_lm_service_rate"] = average_lm_service_rate - - # Average AMoD service rate - amod_parent_requests = parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE] == RQ_MODAL_STATE.MONOMODAL.value].copy() - num_amod_parent_requests = amod_parent_requests.shape[0] - served_amod_parent_requests = amod_parent_requests[amod_parent_requests[G_RQ_CHOSEN_OP_ID].notna()].copy() - num_served_amod_parent_requests = served_amod_parent_requests.shape[0] - average_amod_service_rate = num_served_amod_parent_requests / num_amod_parent_requests if num_amod_parent_requests > 0 else 0.0 - result_dict["average_amod_service_rate"] = average_amod_service_rate - - # ---------------------------- AMoD operator -------------------------------- - amod_op_id = DEFAULT_AMOD_OP_ID + print(f"\nCalculating metrics for {len(served_requests)} served requests...") + + # Categorize requests by modal state + served_requests['modal_category'] = served_requests[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) + + # Total counts + total_requests = len(parent_user_stats) + total_served = len(served_requests) + total_pax = parent_user_stats[G_RQ_PAX].sum() + total_served_pax = served_requests[G_RQ_PAX].sum() + + # Category breakdown + category_counts = served_requests.groupby('modal_category').size() + category_pax = served_requests.groupby('modal_category')[G_RQ_PAX].sum() + + # Calculate service rates + service_rate_overall = total_served / total_requests * 100 if total_requests > 0 else 0 + service_rate_pax = total_served_pax / total_pax * 100 if total_pax > 0 else 0 + + # Service rates by category + service_rates = {} + for category in ['DRT_only', 'FM', 'LM', 'FLM', 'PT_only']: + cat_total = len(parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) == category]) + cat_served = category_counts.get(category, 0) + service_rates[f'{category}_service_rate'] = cat_served / cat_total * 100 if cat_total > 0 else np.nan + service_rates[f'{category}_count'] = cat_served + + # Calculate PT wait times for FM and FLM + fm_requests = served_requests[served_requests['modal_category'] == 'FM'] + flm_requests = served_requests[served_requests['modal_category'] == 'FLM'] + + pt_wait_time_fm = fm_requests['fm_pt_wait'].mean() if len(fm_requests) > 0 and 'fm_pt_wait' in fm_requests.columns else np.nan + pt_wait_time_flm = flm_requests['flm_pt_wait'].mean() if len(flm_requests) > 0 and 'flm_pt_wait' in flm_requests.columns else np.nan + + # Combined PT wait time + pt_waits = [] + if 'fm_pt_wait' in fm_requests.columns: + pt_waits.extend(fm_requests['fm_pt_wait'].dropna().tolist()) + if 'flm_pt_wait' in flm_requests.columns: + pt_waits.extend(flm_requests['flm_pt_wait'].dropna().tolist()) + pt_wait_time_combined = np.mean(pt_waits) if len(pt_waits) > 0 else np.nan + + # Calculate LM wait times for LM and FLM + lm_requests = served_requests[served_requests['modal_category'] == 'LM'] + + lm_wait_time_lm = lm_requests['lm_amod_wait'].mean() if len(lm_requests) > 0 and 'lm_amod_wait' in lm_requests.columns else np.nan + lm_wait_time_flm = flm_requests['flm_amod_1_wait'].mean() if len(flm_requests) > 0 and 'flm_amod_1_wait' in flm_requests.columns else np.nan + + # Combined LM wait time + lm_waits = [] + if 'lm_amod_wait' in lm_requests.columns: + lm_waits.extend(lm_requests['lm_amod_wait'].dropna().tolist()) + if 'flm_amod_1_wait' in flm_requests.columns: + lm_waits.extend(flm_requests['flm_amod_1_wait'].dropna().tolist()) + lm_wait_time_combined = np.mean(lm_waits) if len(lm_waits) > 0 else np.nan + + # Overall metrics + avg_wait_time = served_requests['total_wait_time'].mean() + med_wait_time = served_requests['total_wait_time'].median() + avg_travel_time = served_requests['total_travel_time'].mean() + total_revenue = served_requests['total_fare'].sum() + + # Standard metrics (matching standard_eval.csv format) + result_dict = { + 'operator_id': -3, # Intermodal operator + 'number users': total_served, + 'number travelers': total_served_pax, + 'modal split': service_rate_pax / 100, + 'modal split rq': service_rate_overall / 100, + 'Service_Rate [%]': service_rate_overall, + 'Service_Rate_Pax [%]': service_rate_pax, + + # Category breakdown + 'DRT_only_count': service_rates.get('DRT_only_count', 0), + 'FM_count': service_rates.get('FM_count', 0), + 'LM_count': service_rates.get('LM_count', 0), + 'FLM_count': service_rates.get('FLM_count', 0), + 'PT_only_count': service_rates.get('PT_only_count', 0), + 'DRT_only_service_rate [%]': service_rates.get('DRT_only_service_rate', np.nan), + 'FM_service_rate [%]': service_rates.get('FM_service_rate', np.nan), + 'LM_service_rate [%]': service_rates.get('LM_service_rate', np.nan), + 'FLM_service_rate [%]': service_rates.get('FLM_service_rate', np.nan), + 'PT_only_service_rate [%]': service_rates.get('PT_only_service_rate', np.nan), + + # Wait times + 'waiting time': avg_wait_time, + 'waiting time (median)': med_wait_time, + 'PT_Wait_Time_FM [s]': pt_wait_time_fm, + 'PT_Wait_Time_FLM [s]': pt_wait_time_flm, + 'PT_Wait_Time_Combined [s]': pt_wait_time_combined, + 'LM_Wait_Time_LM [s]': lm_wait_time_lm, + 'LM_Wait_Time_FLM [s]': lm_wait_time_flm, + 'LM_Wait_Time_Combined [s]': lm_wait_time_combined, + + # Travel metrics + 'travel time': avg_travel_time, + 'mod revenue': total_revenue, + } + + # Vehicle-level analysis for AMoD operators if print_comments: - print(f"Reading AMoD operator {amod_op_id} vehicle stats ...") - try: - op_vehicle_df = read_op_output_file(output_dir, op_id=amod_op_id, evaluation_start_time=evaluation_start_time, evaluation_end_time=evaluation_end_time) - except FileNotFoundError: - op_vehicle_df = pd.DataFrame([], columns=[G_V_OP_ID, G_V_VID, G_VR_STATUS, G_VR_LOCKED, G_VR_LEG_START_TIME, - G_VR_LEG_END_TIME, G_VR_LEG_START_POS, G_VR_LEG_END_POS, - G_VR_LEG_DISTANCE, G_VR_LEG_START_SOC, G_VR_LEG_END_SOC, - G_VR_TOLL, G_VR_OB_RID, G_VR_BOARDING_RID, G_VR_ALIGHTING_RID, - G_VR_NODE_LIST, G_VR_REPLAY_ROUTE]) - - n_vehicles = veh_type_stats[veh_type_stats[G_V_OP_ID]==amod_op_id].shape[0] - sim_end_time = scenario_parameters["end_time"] - simulation_time = scenario_parameters["end_time"] - scenario_parameters["start_time"] - - op_vehicle_df["VRL_end_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_END_TIME], sim_end_time) - op_vehicle_df["VRL_start_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_START_TIME], sim_end_time) - utilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] != VRL_STATES.OUT_OF_SERVICE.display_name) & (op_vehicle_df["status"] != VRL_STATES.CHARGING.display_name)] - utilization_time = utilized_veh_df["VRL_end_sim_end_time"].sum() - utilized_veh_df["VRL_start_sim_end_time"].sum() - unutilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] == VRL_STATES.OUT_OF_SERVICE.display_name) | (op_vehicle_df["status"] == VRL_STATES.CHARGING.display_name)] - unutilized_time = unutilized_veh_df["VRL_end_sim_end_time"].sum() - unutilized_veh_df["VRL_start_sim_end_time"].sum() - - op_fleet_utilization = 100 * (utilization_time/(n_vehicles * simulation_time - unutilized_time)) - op_total_km = op_vehicle_df[G_VR_LEG_DISTANCE].sum()/1000.0 - - # by vehicle stats - # ---------------- - op_veh_types = veh_type_stats[veh_type_stats[G_V_OP_ID] == amod_op_id] - op_veh_types.set_index(G_V_VID, inplace=True) - all_vid_dict = {} - for vid, vid_vtype_row in op_veh_types.iterrows(): - vtype_data = veh_type_db[vid_vtype_row[G_V_TYPE]] - op_vid_vehicle_df = op_vehicle_df[op_vehicle_df[G_V_VID] == vid] - veh_km = op_vid_vehicle_df[G_VR_LEG_DISTANCE].sum() / 1000 - veh_kWh = veh_km * vtype_data[G_VTYPE_BATTERY_SIZE] / vtype_data[G_VTYPE_RANGE] - co2_per_kWh = scenario_parameters.get(G_ENERGY_EMISSIONS, ENERGY_EMISSIONS) - if co2_per_kWh is None: - co2_per_kWh = ENERGY_EMISSIONS - veh_co2 = co2_per_kWh * veh_kWh - veh_fix_costs = np.rint(scenario_parameters.get(G_OP_SHARE_FC, 1.0) * vtype_data[G_VTYPE_FIX_COST]) - veh_var_costs = np.rint(vtype_data[G_VTYPE_DIST_COST] * veh_km) - # TODO # after ISTTT: idle times - all_vid_dict[vid] = {"type":vtype_data[G_VTYPE_NAME], "total km":veh_km, "total kWh": veh_kWh, - "total CO2 [g]": veh_co2, "fix costs": veh_fix_costs, - "total variable costs": veh_var_costs} - all_vid_df = pd.DataFrame.from_dict(all_vid_dict, orient="index") - try: - op_co2 = all_vid_df["total CO2 [g]"].sum() - op_ext_em_costs = np.rint(EMISSION_CPG * op_co2) - op_fix_costs = all_vid_df["fix costs"].sum() - op_var_costs = all_vid_df["total variable costs"].sum() - except: - op_co2 = 0 - op_ext_em_costs = 0 - op_fix_costs = 0 - op_var_costs = 0 - - def weight_ob_rq(entries): - if pd.isnull(entries[G_VR_OB_RID]): - return 0.0 - else: - number_ob_rq = len(str(entries[G_VR_OB_RID]).split(";")) - return number_ob_rq * entries[G_VR_LEG_DISTANCE] - - def weight_ob_pax(entries): + print("\nAnalyzing vehicle operations...") + + # Process each AMoD operator + for op_id in range(scenario_parameters.get(G_NR_OPERATORS, 0)): try: - return entries[G_VR_NR_PAX] * entries[G_VR_LEG_DISTANCE] - except: - return 0.0 - - op_vehicle_df["weighted_ob_rq"] = op_vehicle_df.apply(weight_ob_rq, axis = 1) - op_vehicle_df["weighted_ob_pax"] = op_vehicle_df.apply(weight_ob_pax, axis=1) - op_distance_avg_rq = op_vehicle_df["weighted_ob_rq"].sum() / op_vehicle_df[G_VR_LEG_DISTANCE].sum() - op_distance_avg_occupancy = op_vehicle_df["weighted_ob_pax"].sum() / op_vehicle_df[G_VR_LEG_DISTANCE].sum() - - result_dict["fleet_utilization_rate"] = op_fleet_utilization - result_dict["distance_avg_occupancy"] = op_distance_avg_occupancy - result_dict["total_km_driven"] = op_total_km - result_dict["average_km_driven"] = op_total_km / n_vehicles - result_dict["total_amod_cost"] = op_fix_costs + op_var_costs - result_dict["average_amod_cost"] = (op_fix_costs + op_var_costs) / n_vehicles - result_dict['total_amod_fix_cost'] = op_fix_costs - result_dict['total_amod_variable_cost'] = op_var_costs - result_dict["total_co2_emissions_g"] = op_co2 - result_dict["total_external_emission_costs"] = op_ext_em_costs - - op_name = f"MoD_{amod_op_id}" - - result_dict_list.append(result_dict) - operator_names.append(op_name) - - result_df = pd.DataFrame(result_dict_list, index=operator_names) - result_df = result_df.transpose() - result_df.to_csv(os.path.join(output_dir, "standard_eval.csv")) - - return result_df \ No newline at end of file + op_vehicle_df = read_op_output_file(output_dir, op_id, evaluation_start_time, evaluation_end_time) + operator_attributes = list_operator_attributes[int(op_id)] + + if print_comments: + print(f" Processing operator {op_id}: {op_vehicle_df.shape[0]} vehicle route legs") + + # Fleet metrics + n_vehicles = veh_type_stats[veh_type_stats[G_V_OP_ID] == op_id].shape[0] + sim_end_time = scenario_parameters["end_time"] + simulation_time = scenario_parameters["end_time"] - scenario_parameters["start_time"] + + # Utilization + op_vehicle_df["VRL_end_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_END_TIME], sim_end_time) + op_vehicle_df["VRL_start_sim_end_time"] = np.minimum(op_vehicle_df[G_VR_LEG_START_TIME], sim_end_time) + utilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] != VRL_STATES.OUT_OF_SERVICE.display_name) & + (op_vehicle_df["status"] != VRL_STATES.CHARGING.display_name)] + utilization_time = utilized_veh_df["VRL_end_sim_end_time"].sum() - utilized_veh_df["VRL_start_sim_end_time"].sum() + unutilized_veh_df = op_vehicle_df[(op_vehicle_df["status"] == VRL_STATES.OUT_OF_SERVICE.display_name) | + (op_vehicle_df["status"] == VRL_STATES.CHARGING.display_name)] + unutilized_time = unutilized_veh_df["VRL_end_sim_end_time"].sum() - unutilized_veh_df["VRL_start_sim_end_time"].sum() + + fleet_utilization = 100 * (utilization_time / (n_vehicles * simulation_time - unutilized_time)) if (n_vehicles * simulation_time - unutilized_time) > 0 else 0 + + # Distance metrics + total_km = op_vehicle_df[G_VR_LEG_DISTANCE].sum() / 1000.0 + + def weight_ob_pax(entries): + try: + return entries[G_VR_NR_PAX] * entries[G_VR_LEG_DISTANCE] + except: + return 0.0 + + op_vehicle_df["weighted_ob_pax"] = op_vehicle_df.apply(weight_ob_pax, axis=1) + distance_avg_occupancy = op_vehicle_df["weighted_ob_pax"].sum() / op_vehicle_df[G_VR_LEG_DISTANCE].sum() if op_vehicle_df[G_VR_LEG_DISTANCE].sum() > 0 else 0 + + empty_df = op_vehicle_df[op_vehicle_df[G_VR_OB_RID].isnull()] + empty_vkm = empty_df[G_VR_LEG_DISTANCE].sum() / 1000.0 / total_km * 100.0 if total_km > 0 else 0 + + # Revenue metrics + rev_df = op_vehicle_df[op_vehicle_df["status"].isin([x.display_name for x in G_REVENUE_STATUS])] + vehicle_revenue_hours = (rev_df["VRL_end_sim_end_time"].sum() - rev_df["VRL_start_sim_end_time"].sum()) / 3600.0 + + # By-vehicle stats + op_veh_types = veh_type_stats[veh_type_stats[G_V_OP_ID] == op_id] + op_veh_types.set_index(G_V_VID, inplace=True) + all_vid_dict = {} + + for vid, vid_vtype_row in op_veh_types.iterrows(): + vtype_data = veh_type_db[vid_vtype_row[G_V_TYPE]] + op_vid_vehicle_df = op_vehicle_df[op_vehicle_df[G_V_VID] == vid] + veh_km = op_vid_vehicle_df[G_VR_LEG_DISTANCE].sum() / 1000 + veh_kWh = veh_km * vtype_data[G_VTYPE_BATTERY_SIZE] / vtype_data[G_VTYPE_RANGE] + co2_per_kWh = scenario_parameters.get(G_ENERGY_EMISSIONS, ENERGY_EMISSIONS) + if co2_per_kWh is None: + co2_per_kWh = ENERGY_EMISSIONS + veh_co2 = co2_per_kWh * veh_kWh + veh_fix_costs = np.rint(scenario_parameters.get(G_OP_SHARE_FC, 1.0) * vtype_data[G_VTYPE_FIX_COST]) + veh_var_costs = np.rint(vtype_data[G_VTYPE_DIST_COST] * veh_km) + + all_vid_dict[vid] = { + "type": vtype_data[G_VTYPE_NAME], + "total km": veh_km, + "total kWh": veh_kWh, + "total CO2 [g]": veh_co2, + "fix costs": veh_fix_costs, + "total variable costs": veh_var_costs + } + + # Save vehicle-level stats + all_vid_df = pd.DataFrame.from_dict(all_vid_dict, orient="index") + all_vid_df.to_csv(os.path.join(output_dir, f"standard_mod-{op_id}_veh_eval.csv")) + + # Aggregate vehicle metrics + total_co2 = all_vid_df["total CO2 [g]"].sum() if len(all_vid_df) > 0 else 0 + fix_costs = all_vid_df["fix costs"].sum() if len(all_vid_df) > 0 else 0 + var_costs = all_vid_df["total variable costs"].sum() if len(all_vid_df) > 0 else 0 + + # Add to result dict with operator prefix + result_dict[f'op{op_id}_fleet_utilization [%]'] = fleet_utilization + result_dict[f'op{op_id}_total_vkm'] = total_km + result_dict[f'op{op_id}_occupancy'] = distance_avg_occupancy + result_dict[f'op{op_id}_empty_vkm [%]'] = empty_vkm + result_dict[f'op{op_id}_vehicle_revenue_hours'] = vehicle_revenue_hours + result_dict[f'op{op_id}_total_CO2_emissions [t]'] = total_co2 / 10**6 + result_dict[f'op{op_id}_fix_costs'] = fix_costs + result_dict[f'op{op_id}_var_costs'] = var_costs + + except FileNotFoundError: + if print_comments: + print(f" No vehicle data found for operator {op_id}") + continue + + # Create result DataFrame + result_df = pd.DataFrame([result_dict], index=['Intermodal']).T + result_df.columns = ['Intermodal'] + + # Save to standard_eval.csv for consistency + output_file = os.path.join(output_dir, "standard_eval.csv") + result_df.to_csv(output_file) + + if print_comments: + print(f"\nEvaluation complete! Results saved to: {output_file}") + print("="*80) + + return result_df + + +if __name__ == "__main__": + import sys + if len(sys.argv) > 1: + sc = sys.argv[1] + intermodal_evaluation(sc, print_comments=True) + else: + print("Usage: python intermodal.py ") + print("Example: python src/evaluation/intermodal.py studies/example_study/results/example_im_ptbroker") diff --git a/src/misc/globals.py b/src/misc/globals.py index fe50ad1b..ed38af01 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -611,7 +611,6 @@ class RQ_SUB_TRIP_ID(Enum): G_IM_OFFER_PT_WAIT = "im_t_wait_pt" # total pt waiting time G_IM_OFFER_PT_DRIVE = "im_t_drive_pt" # total pt driving time G_IM_OFFER_DURATION = "im_t_duration" # total duration of intermodal offer -G_IM_OFFER_TYPE = "im_offer_type" # type of intermodal offer: "TPCS Phase 2", "TPCS Phase 1", "TPCS Default" # additional parameters for pt offers # ------------------------------------------ diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv index 04a716eb..8b1b006d 100644 --- a/studies/example_study/scenarios/example_im.csv +++ b/studies/example_study/scenarios/example_im.csv @@ -1,3 +1,3 @@ -scenario_name,op_module,rq_file,op_fleet_composition,broker_type,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,broker_tpcs_use_default,evaluation_method,sim_env,user_max_decision_time -example_im_ptbroker_tpcs,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,False,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbroker_tpcs_default,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerTPCS,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,True,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file +scenario_name,op_module,rq_file,op_fleet_composition,broker_type,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,evaluation_method,sim_env,user_max_decision_time +example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBroker,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From 546e60a42bed52bb8a90803b80c61a871b2478ec Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Tue, 3 Feb 2026 08:28:41 +0100 Subject: [PATCH 23/31] Estimation-based Integration --- src/broker/PTBroker.py | 4 +- src/broker/PTBrokerEI.py | 944 +++++++++++++++++++++++++++++++++++++++ src/misc/globals.py | 1 + 3 files changed, 947 insertions(+), 2 deletions(-) create mode 100644 src/broker/PTBrokerEI.py diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index e81782c7..5e0f4fc4 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -1,6 +1,6 @@ # TODO: -# - Support dynamic adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. -# - Support multiple AMoD operators in the firstlastmile requests. +# - Adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. +# - Support multiple AMoD operators for firstlastmile requests. # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports diff --git a/src/broker/PTBrokerEI.py b/src/broker/PTBrokerEI.py new file mode 100644 index 00000000..9d667e13 --- /dev/null +++ b/src/broker/PTBrokerEI.py @@ -0,0 +1,944 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import logging +from datetime import datetime, timedelta +import typing as tp +import pandas as pd +# additional module imports (> requirements) +# ------------------------------------------ + + +# src imports +# ----------- +from src.broker.BrokerBasic import BrokerBasic +from src.simulation.Offers import IntermodalOffer +if tp.TYPE_CHECKING: + from src.fleetctrl.FleetControlBase import FleetControlBase + from src.fleetctrl.planning.PlanRequest import PlanRequest + from src.ptctrl.PTControlBase import PTControlBase + from src.demand.demand import Demand + from src.routing.road.NetworkBase import NetworkBase + from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest + from src.simulation.Offers import TravellerOffer, PTOffer + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) +LARGE_INT = 100000000 +BUFFER_SIZE = 100 + +INPUT_PARAMETERS_PTBroker = { + "doc" : "this class represents a broker platform which handles intermodal requests", + "inherit" : BrokerBasic, + "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTBrokerEI(BrokerBasic): + def __init__( + self, + n_amod_op: int, + amod_operators: tp.List['FleetControlBase'], + pt_operator: 'PTControlBase', + demand: 'Demand', + routing_engine: 'NetworkBase', + scenario_parameters: dict, + always_query_pt: bool = False, # TODO: make it a scenario parameter + ): + """ + The general attributes for the broker are initialized. + + Args: + n_amod_op (int): number of AMoD operators + amod_operators (tp.List['FleetControlBase']): list of AMoD operators + pt_operator (PTControlBase): PT operator + demand (Demand): demand object + routing_engine (NetworkBase): routing engine + scenario_parameters (dict): scenario parameters + always_query_pt (bool): if True, the pure PT offers are always requested + """ + super().__init__(n_amod_op, amod_operators) + + self.demand: Demand = demand + self.routing_engine: NetworkBase = routing_engine + self.pt_operator: PTControlBase = pt_operator + + self.pt_operator_id: int = self.pt_operator.pt_operator_id + self.scenario_parameters: dict = scenario_parameters + self.always_query_pt: bool = always_query_pt + + # set simulation start date for Raptor routing + self.sim_start_datetime: datetime = None + self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) + + # set MaaS detour time estimation parameter + self.maas_detour_time_factor: float = self.scenario_parameters.get(G_BROKER_MAAS_DETOUR_TIME_FACTOR , 100) + + # method for finding transfer stations + self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") + # read necessary files based on the transfer search method + if self.transfer_search_method == "closest": + # load the street-station transfers: used for finding closest station to a street node, or vice versa + try: + self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) + except FileNotFoundError: + LOG.error("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + raise FileNotFoundError("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + + + def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): + """This method informs the broker that a new request has been made. + Based on the request modal state, the broker will create the appropriate sub-requests + and inform the operators. + + Args: + rid (int): parent request id + rq_obj (RequestBase): request object + sim_time (int): simulation time + """ + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") + + if self.always_query_pt: + # 1. query the PT operator for the pure PT travel costs + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) + + # 2.1 pure AMoD request or PT request + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.2 AMoD as firstmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.3 AMoD as lastmile request + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.4 AMoD as firstlastmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: + """This method collects the offers from the operators. + + Args: + rid (int): parent request id + sim_time (int): simulation time + Returns: + tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators + """ + # get parent request modal state + parent_rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + offers: tp.Dict[int, TravellerOffer] = {} + LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") + + # 1. collect PT offers for multimodal requests + if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) + LOG.debug(f"pt offer {pt_offer}") + + if pt_offer is not None and not pt_offer.service_declined(): + offers[self.pt_operator_id] = pt_offer + # register the pt offer in the sub-request + self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) + + # 2.1 collect AMoD offers for MONOMODAL and PT requests + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) + + # 2.2 collect AMoD offers for FIRSTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + # 2.3 collect AMoD offers for LASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) + + # 2.4 collect AMoD offers for FIRSTLASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + return offers + + def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: + """This method informs the broker that the user has booked a trip. + """ + amod_confirmed_rids = [] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + # 1. Pure PT offer has been selected + if chosen_operator == self.pt_operator_id: + amod_confirmed_rids.append((rid, rq_obj)) + + # inform all AMoD operators that the request is cancelled + self.inform_user_leaving_system(rid, sim_time) + + # inform PT operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) + # 2. AMoD involved offer has been selected + else: + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int + operator.user_cancels_request(rid, sim_time) + else: + operator.user_confirms_booking(rid, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + # inform the pt operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{sub_trip_id}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + + if parent_modal_state == RQ_MODAL_STATE.LASTMILE: + previous_amod_operator_id = None # no previous amod operator + else: # firstmile or firstlastmile + previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) + else: + # inform the amod operator that the request is confirmed + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + for i, operator in enumerate(self.amod_operators): + if i != operator_id: + operator.user_cancels_request(amod_rid_struct, sim_time) + else: + operator.user_confirms_booking(amod_rid_struct, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + return amod_confirmed_rids + + def inform_user_leaving_system(self, rid: int, sim_time: int): + """This method informs the broker that the user is leaving the system. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(rid, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(fm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(lm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) + operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): + """This method informs the operators that the waiting requests have been cancelled. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if chosen_operator == self.pt_operator_id: + return + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) + + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + continue + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + operator_id = int(operator_id) + self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): + """This method processes the new monomodal request. + + Args: + rid (int): the request id + rq_obj ('RequestBase'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + for op_id in range(self.n_amod_op): + LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(rq_obj, sim_time) + + def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): + """This method processes the new firstmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # Make the estimation first, then based on the estimation, create sub-requests + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] + # create sub-request for PT + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") + # estimate the earliest start time of the pt sub-request + fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, transfer_street_node, rq_obj.get_destination_node(), fm_est_pt_mod, parent_modal_state, op_id) + + def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): + """This method processes the new lastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # create sub-request for PT + lm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_PT.value, rq_obj.get_origin_node(), transfer_street_node, rq_obj.earliest_start_time, parent_modal_state) + + if lm_pt_arrival is not None: + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.LM_AMOD.value, transfer_street_node, rq_obj.get_destination_node(), lm_pt_arrival, parent_modal_state, op_id, sim_time) + else: + LOG.info(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.LM_PT.value}, so the lastmile AMoD sub-request will not be created.") + + def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): + """This method processes the new firstlastmile request. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + # get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # create sub-request for AMoD + for op_id in range(self.n_amod_op): + # firstmile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] + # create sub-request for PT + # estimate the dropoff time of the amod sub-request + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") + # estimate the earliest start time of the pt sub-request + flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt + # create the pt sub-request + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, transfer_street_node_0,transfer_street_node_1, flm_est_pt_mod,parent_modal_state,op_id) + + # create sub-request for the same AMoD operator + if flm_pt_arrival is None: + raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") + else: + # last mile AMoD sub-request + self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) + + def _inform_amod_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int + ): + """ + This method informs the AMoD operators that a new sub-request has been made. + + Args: + rq_obj ('RequestBase'): the parent request object + sub_trip_id (int): the sub-trip id + leg_o_node (int): the origin node of the sub-request + leg_d_node (int): the destination node of the sub-request + leg_start_time (int): the start time of the sub-request + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) + + def _inform_pt_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None + ) -> tp.Optional[int]: + """ + This method informs the PT operator that a new sub-request has been made. + + Args: + rq_obj (RequestBase): the parent request object + sub_trip_id (int): the sub_trip id + leg_o_node (int): the origin street node of the sub-request + leg_d_node (int): the destination street node of the sub-request + leg_start_time (int): the start time [s] of the sub-request at the origin street node + parent_modal_state (RQ_MODAL_STATE): the parent modal state + firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests + Returns: + t_d_node_arrival (tp.Optional[int]): + the pt arrival time of the sub-request at the destination street node + or None if the pt travel costs are not available + """ + pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") + + costs_info = self._query_street_node_pt_travel_costs_1to1( + pt_sub_rq_obj.get_origin_node(), + pt_sub_rq_obj.get_destination_node(), + pt_sub_rq_obj.earliest_start_time, + pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest + ) + + if costs_info is not None: + source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") + else: + source_pt_station_id = None + t_source_walk = None + target_pt_station_id = None + t_target_walk = None + pt_journey_plan_dict = None + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") + + pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() + + self.pt_operator.create_and_record_pt_offer_db( + rid_struct = pt_rid_struct, + operator_id = self.pt_operator_id, + source_station_id = source_pt_station_id, + target_station_id = target_pt_station_id, + source_walking_time = t_source_walk, + target_walking_time = t_target_walk, + pt_journey_plan_dict = pt_journey_plan_dict, + firstmile_amod_operator_id = firstmile_amod_operator_id, + ) + if pt_journey_plan_dict is not None: + t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer + return t_d_node_arrival + else: + return None + + def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of monomodal offers. + + Args: + rid (int): the request id + parent_modal_state (RQ_MODAL_STATE): the parent modal state + offers (tp.Dict[int, TravellerOffer]): the current offers dictionary + Returns: + tp.Dict[int, TravellerOffer]: the updated offers dictionary + """ + for amod_op_id in range(self.n_amod_op): + amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) + LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") + if amod_offer is not None and not amod_offer.service_declined(): + offers[amod_op_id] = amod_offer + return offers + + def _process_collect_firstmile_offers_tpcs_phase1( + self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. + """ + # collect all offers + fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) + LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") + + fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) + LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") + + if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") + return None, None + + if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): + LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") + return None, fm_amod_offer_p1 + + if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + return intermodal_offer_p1, fm_amod_offer_p1 + + def _process_collect_firstmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstmile offers using TPCS approach. + """ + # get rid struct for all sections + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + fm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" + + for amod_op_id in range(self.n_amod_op): + # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! + # 1. Phase 1 + intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + # No amod offer in phase 1, skip to next amod operator + if fm_amod_offer_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.1 re-query the pt offer + # 2.1.1 get the transfer station id and its closest pt station + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # 2.1.2 determine the earliest start time of the pt sub-request + fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) + # 2.1.3 create the pt sub-request and get the pt arrival time + fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FM_PT.value, + transfer_street_node, + parent_rq_obj.get_destination_node(), + fm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) + if fm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.2 create intermodal offer + sub_trip_offers: tp.Dict[int, TravellerOffer] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of lastmile offers. + """ + # get lastmile pt offer + lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" + lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) + LOG.debug(f"Collecting lm_pt offer for request {lm_pt_rid_struct} from PT operator {self.pt_operator_id}: {lm_pt_offer}") + + if lm_pt_offer is not None and not lm_pt_offer.service_declined(): + # register the pt offer in the sub-request + self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for amod_op_id in range(self.n_amod_op): + # get lastmile amod offer + lm_amod_offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) + LOG.debug(f"Collecting lm_amod offer for request {lm_amod_rid_struct} from operator {amod_op_id}: {lm_amod_offer}") + + if lm_amod_offer is not None and not lm_amod_offer.service_declined(): + # register the amod offer in the sub-request + self.demand[lm_amod_rid_struct].receive_offer(amod_op_id, lm_amod_offer, None) + + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.LM_PT.value] = lm_pt_offer + sub_trip_offers[RQ_SUB_TRIP_ID.LM_AMOD.value] = lm_amod_offer + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + offers[intermodal_offer.operator_id] = intermodal_offer + else: + LOG.info(f"AMoD offer is not available for sub_request {lm_amod_rid_struct}") + else: + LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") + return offers + + def _process_collect_firstlastmile_offers_tpcs_phase1( + self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, + parent_modal_state: RQ_MODAL_STATE, amod_op_id: int + ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: + """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. + """ + flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) + LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") + + flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) + LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") + + flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) + LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") + + if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") + return None, None + + if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): + LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") + # create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 + intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + else: + LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") + intermodal_offer_p1 = None + return intermodal_offer_p1, flm_amod_offer_0_p1 + + def _process_collect_firstlastmile_offers_tpcs( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstlastmile offers using 3-phases approach. + """ + # get rid struct for all sections + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + + for amod_op_id in range(self.n_amod_op): + # 1. Phase 1 + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + # No firstmile amod offer in phase 1, skip to next amod operator + if flm_amod_offer_0_p1 is None: + continue + + # check if only phase 1 is used and process accordingly + if self.use_phase_1_only and intermodal_offer_p1 is not None: + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + continue + elif self.use_phase_1_only and intermodal_offer_p1 is None: + continue + else: + # 2. Phase 2 + # 2.0 cancel lastmile amod sub-request + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + + # 2.2 re-query the pt offer + # 2.2.1 get the transfer station ids and their closest pt stations + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # 2.2.2 determine the earliest start time of the pt sub-request + flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) + + # 2.2.3 create the pt sub-request and get the pt arrival time + flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_PT.value, + transfer_street_node_0, + transfer_street_node_1, + flm_est_pt_mod, + parent_modal_state, + amod_op_id, + ) + flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) + if flm_pt_arrival is None: + LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.3 re-query the lastmile amod offer + self._inform_amod_sub_request( + parent_rq_obj, + RQ_SUB_TRIP_ID.FLM_AMOD_1.value, + transfer_street_node_1, + parent_rq_obj.get_destination_node(), + flm_pt_arrival, + parent_modal_state, + amod_op_id, + sim_time, + ) + flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) + if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") + intermodal_offer_p2 = None + else: + # 2.4 create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 + intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + + # 3. Phase 3 + # 3.1 check if the offer from phase 2 is better than the offer from phase 1 + comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) + if comparison_results == 2: + LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") + intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) + offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + + # 3.2 update the first amod offer with the latest dropoff time + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] + old_t_do_latest: int = sub_prq_obj.t_do_latest + new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) + sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) + + elif comparison_results == 1: + LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") + # 3.2 rollback all changes in phase 2 + self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) + self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) + intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( + rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id + ) + intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) + offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + + elif comparison_results == 0: + LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") + continue + else: + raise ValueError(f"Invalid comparison results: {comparison_results}") + return offers + + def _set_sim_start_datetime(self, sim_start_date: str): + """This method sets the simulation start date. + Converts the date string (format YYYYMMDD) to a datetime object. + + Args: + sim_start_date (str): the simulation start date in format YYYYMMDD + """ + if sim_start_date is None: + LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + + if type(sim_start_date) is not str: + sim_start_date = str(int(sim_start_date)) + self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") + + def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: + """This method returns the current datetime based on the simulation time in seconds. + """ + return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) + + def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific street station transfers file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The transfer data between the street nodes and the PT stations. + """ + dtypes = { + 'node_id': 'int', + 'closest_station_id': 'str', + 'street_station_transfer_time': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) + + def _query_street_node_pt_travel_costs_1to1( + self, o_node: int, d_node: int, est: int, + max_transfers: int = 999, detailed: bool = False + ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + """This method queries the pt travel costs between two street nodes at a given datetime. + The pt station ids will be the closest pt station ids to the street nodes. + + Args: + o_node (int): The origin street node id. + d_node (int): The destination street node id. + est (int): The earliest start time of the request at the origin street node in seconds. + max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. + detailed (bool): Whether to return detailed journey information. Defaults to False. + Returns: + tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + Returns a tuple containing: + (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) + if a public transport journey plan is found. + Returns None if no public transport journey plan is available. + """ + # find pt transfer stations + source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") + target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") + + source_station_departure_seconds: int = est + t_source_walk + source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) + LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( + source_pt_station_id, target_pt_station_id, + source_station_departure_datetime, + max_transfers, detailed, + ) + if pt_journey_plan_dict is None: + return None + else: + return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict + + def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: + """This method finds the transfer possibility between pt station and street node. + + Args: + node_id (tp.Union[int, str]): The street node id. + direction (str): "pt2street" or "street2pt" + Returns: + tp.Tuple[str, int]: The transfer node id and the walking time. + """ + if self.transfer_search_method == "closest": # closest station or street node + if direction == "street2pt": # find closest pt station from street node + street_node_id: int = int(node_id) + # TODO: allow multiple closest stations? + street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] + if street_station_transfer.empty: + raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") + closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] + walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] + return closest_station_id, walking_time + elif direction == "pt2street": # find closest street node from pt station + pt_station_id: str = str(node_id) + street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] + if street_station_transfers.empty: + raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") + # find the record with the minimum street_station_transfer_time + # TODO: if multiple exist, return all? + min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] + closest_street_node_id: int = min_transfer["node_id"] + walking_time: int = min_transfer["street_station_transfer_time"] + return closest_street_node_id, walking_time + else: + raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") + else: + LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") + raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") + + def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest') -> tp.Optional[int]: + """This method estimates the dropoff time of an amod sub-request. + + Args: + amod_op_id (int): the id of the amod operator + sub_rq_obj (BasicIntermodalRequest): the sub-request object + Returns: + int: the dropoff time of the sub-request + """ + # get amod dropoff time range + sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() + sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) + amod_service_latest_dropoff_time: int = sub_prq_obj.t_do_latest + self.amod_operators[amod_op_id].const_bt # TODO: check if const_bt should be added here + maas_estimated_latest_dropoff_time: int = sub_rq_obj.earliest_start_time * self.maas_detour_time_factor + return sub_prq_obj.t_do_latest + + def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: + """This method determines the earliest start time for the pt sub-request. + """ + t_est_pt_mod: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + self.amod_operators[amod_op_id].const_bt + return t_est_pt_mod + + def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: 'TravellerOffer', pt_waiting_time: int, old_t_do_latest: int) -> tp.Optional[int]: + """This method determines the latest dropoff time for the amod sub-request. + """ + t_do_latest: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + pt_waiting_time + # add latest dropoff time constraint check + if t_do_latest > old_t_do_latest: + t_do_latest = old_t_do_latest + return t_do_latest + + def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': + """This method merges the amod and pt offers into an intermodal offer. + """ + return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) + + def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: + """This method compares two intermodal offers based on availability and arrival time at destination node. + If offer_1 and offer_2 are both None, it returns 0. + If offer_1 is None and offer_2 is not None, it returns 2. + If offer_1 is not None and offer_2 is None, it returns 1. + If offer_1 is better than offer_2, it returns 1. + If offer_1 is worse than offer_2, it returns 2. + If offer_1 and offer_2 are equally good, it returns 2. + """ + if offer_1 is None and offer_2 is None: + return 0 + elif offer_1 is None and offer_2 is not None: + return 2 + elif offer_1 is not None and offer_2 is None: + return 1 + else: + duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) + duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) + if duration_p1 <= duration_p2: + return 1 + elif duration_p1 > duration_p2: + return 2 + else: + raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file diff --git a/src/misc/globals.py b/src/misc/globals.py index ed38af01..3be8a265 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -74,6 +74,7 @@ # broker specific attributes G_BROKER_TYPE = "broker_type" G_BROKER_TRANSFER_SEARCH_METHOD = "broker_transfer_search_method" # method for finding transfer stations: "closest" or "best_overall" +G_BROKER_MAAS_DETOUR_TIME_FACTOR = "broker_maas_detour_time_factor" # factor to estimate detour time for MaaS intermodal trips (default: 1.0) # public transport specific attributes G_PT_TYPE = "pt_type" From 2b38409049b5f77719844e21629c399cdd77beee Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Tue, 3 Feb 2026 20:33:43 +0100 Subject: [PATCH 24/31] PTBrokerEI --- src/FleetSimulationBase.py | 6 +- src/broker/PTBroker.py | 460 +--------- src/broker/PTBrokerBasic.py | 584 +++++++++++++ src/broker/PTBrokerEI.py | 806 ++---------------- src/misc/globals.py | 1 + src/misc/init_modules.py | 1 + src/simulation/Offers.py | 3 + .../example_study/scenarios/example_im.csv | 7 +- 8 files changed, 684 insertions(+), 1184 deletions(-) create mode 100644 src/broker/PTBrokerBasic.py diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index f2f570c4..ee8e0490 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -466,12 +466,12 @@ def _load_broker_module(self): LOG.info(prt_msg) BrokerClass = load_broker_module("BrokerBasic") self.broker = BrokerClass(self.n_op, self.operators) - elif broker_type == "PTBroker": - prt_msg: str = "PTBroker specified, using PTBroker" + elif broker_type == "PTBroker" or broker_type == "PTBrokerEI": + prt_msg: str = f"Broker specified, using {broker_type}" LOG.info(prt_msg) if self.pt_operator is None: raise ValueError("PT operator should be loaded before loading PTBroker.") - BrokerClass = load_broker_module("PTBroker") + BrokerClass = load_broker_module(broker_type) self.broker = BrokerClass(self.n_op, self.operators, self.pt_operator, self.demand, self.routing_engine, self.scenario_parameters) else: raise ValueError(f"Unknown broker type: {broker_type}!") diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index 5e0f4fc4..7780b40a 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -15,7 +15,7 @@ # src imports # ----------- -from src.broker.BrokerBasic import BrokerBasic +from src.broker.PTBrokerBasic import PTBrokerBasic from src.simulation.Offers import IntermodalOffer if tp.TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase @@ -37,7 +37,7 @@ INPUT_PARAMETERS_PTBroker = { "doc" : "this class represents a broker platform which handles intermodal requests", - "inherit" : BrokerBasic, + "inherit" : PTBrokerBasic, "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], "input_parameters_optional": [], "mandatory_modules": [], @@ -47,7 +47,7 @@ # -------------------------------------------------------------------------------------------------------------------- # # main # ---- -class PTBroker(BrokerBasic): +class PTBroker(PTBrokerBasic): def __init__( self, n_amod_op: int, @@ -56,7 +56,6 @@ def __init__( demand: 'Demand', routing_engine: 'NetworkBase', scenario_parameters: dict, - always_query_pt: bool = False, # TODO: make it a scenario parameter ): """ The general attributes for the broker are initialized. @@ -68,241 +67,8 @@ def __init__( demand (Demand): demand object routing_engine (NetworkBase): routing engine scenario_parameters (dict): scenario parameters - always_query_pt (bool): if True, the pure PT offers are always requested """ - super().__init__(n_amod_op, amod_operators) - - self.demand: Demand = demand - self.routing_engine: NetworkBase = routing_engine - self.pt_operator: PTControlBase = pt_operator - - self.pt_operator_id: int = self.pt_operator.pt_operator_id - self.scenario_parameters: dict = scenario_parameters - self.always_query_pt: bool = always_query_pt - - # set simulation start date for Raptor routing - self.sim_start_datetime: datetime = None - self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) - - # method for finding transfer stations - self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") - # read necessary files based on the transfer search method - # default method: closest transfer station search. - if self.transfer_search_method == "closest": - # load the street-station transfers: used for finding closest station to a street node, or vice versa - try: - self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) - except FileNotFoundError: - LOG.error("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - raise FileNotFoundError("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - - - def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): - """This method informs the broker that a new request has been made. - Based on the request modal state, the broker will create the appropriate sub-requests - and inform the operators. - - Args: - rid (int): parent request id - rq_obj (RequestBase): request object - sim_time (int): simulation time - """ - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") - - if self.always_query_pt: - # 1. query the PT operator for the pure PT travel costs - _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) - - # 2.1 pure AMoD request or PT request - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.2 AMoD as firstmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.3 AMoD as lastmile request - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.4 AMoD as firstlastmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: - """This method collects the offers from the operators. - - Args: - rid (int): parent request id - sim_time (int): simulation time - Returns: - tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators - """ - # get parent request modal state - parent_rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() - offers: tp.Dict[int, TravellerOffer] = {} - LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") - - # 1. collect PT offers for multimodal requests - if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) - LOG.debug(f"pt offer {pt_offer}") - - if pt_offer is not None and not pt_offer.service_declined(): - offers[self.pt_operator_id] = pt_offer - # register the pt offer in the sub-request - self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) - - # 2.1 collect AMoD offers for MONOMODAL and PT requests - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) - - # 2.2 collect AMoD offers for FIRSTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - offers = self._process_collect_firstmile_offers(rid, parent_rq_obj, parent_modal_state, offers) - - # 2.3 collect AMoD offers for LASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) - - # 2.4 collect AMoD offers for FIRSTLASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - offers = self._process_collect_firstlastmile_offers(rid, parent_rq_obj, parent_modal_state, offers, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - return offers - - def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: - """This method informs the broker that the user has booked a trip. - """ - amod_confirmed_rids = [] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - # 1. Pure PT offer has been selected - if chosen_operator == self.pt_operator_id: - amod_confirmed_rids.append((rid, rq_obj)) - - # inform all AMoD operators that the request is cancelled - self.inform_user_leaving_system(rid, sim_time) - - # inform PT operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) - # 2. AMoD involved offer has been selected - else: - # non-intermodal offer has been selected - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for i, operator in enumerate(self.amod_operators): - if i != chosen_operator: # Non-intermodal requests: the chosen operator has the data type int - operator.user_cancels_request(rid, sim_time) - else: - operator.user_confirms_booking(rid, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - # intermodal offer has been selected - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - # chosen_operator has the data type tuple: ((operator_id, sub_trip_id), ...) - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - # inform the pt operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{sub_trip_id}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - - if parent_modal_state == RQ_MODAL_STATE.LASTMILE: - previous_amod_operator_id = None # no previous amod operator - else: # firstmile or firstlastmile - previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) - else: - # inform the amod operator that the request is confirmed - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - for i, operator in enumerate(self.amod_operators): - if i != operator_id: - operator.user_cancels_request(amod_rid_struct, sim_time) - else: - operator.user_confirms_booking(amod_rid_struct, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - return amod_confirmed_rids - - def inform_user_leaving_system(self, rid: int, sim_time: int): - """This method informs the broker that the user is leaving the system. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(rid, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(fm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(lm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) - try: - operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) - except KeyError: - # LM AMoD sub-request may not be created if no PT offer is available - LOG.info(f"LM AMoD sub-request {flm_amod_rid_struct_1} not found when user leaves system, possibly no FM or PT offer available so the LM sub-request was not created.") - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): - """This method informs the operators that the waiting requests have been cancelled. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if chosen_operator == self.pt_operator_id: - return - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) - - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - continue - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - operator_id = int(operator_id) - self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): - """This method processes the new monomodal request. - - Args: - rid (int): the request id - rq_obj ('RequestBase'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - for op_id in range(self.n_amod_op): - LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(rq_obj, sim_time) + super().__init__(n_amod_op, amod_operators, pt_operator, demand, routing_engine, scenario_parameters) def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): """This method processes the new firstmile request. @@ -363,109 +129,6 @@ def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermod for op_id in range(self.n_amod_op): # firstmile AMoD sub-request self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, rq_obj.get_origin_node(), transfer_street_node_0, rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time) - - def _inform_amod_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int - ): - """ - This method informs the AMoD operators that a new sub-request has been made. - - Args: - rq_obj ('RequestBase'): the parent request object - sub_trip_id (int): the sub-trip id - leg_o_node (int): the origin node of the sub-request - leg_d_node (int): the destination node of the sub-request - leg_start_time (int): the start time of the sub-request - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") - - # get customizable wait time for last mile AMoD pickups - if parent_modal_state == RQ_MODAL_STATE.LASTMILE or (parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE and sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value): - # in this case, the parent request type must be BasicIntermodalRequest - max_wait_time: tp.Optional[int] = rq_obj.get_lastmile_max_wait_time() - else: - max_wait_time: tp.Optional[int] = None - - self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time, max_wait_time=max_wait_time) - - def _inform_pt_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None - ) -> tp.Optional[int]: - """ - This method informs the PT operator that a new sub-request has been made. - - Args: - rq_obj (RequestBase): the parent request object - sub_trip_id (int): the sub_trip id - leg_o_node (int): the origin street node of the sub-request - leg_d_node (int): the destination street node of the sub-request - leg_start_time (int): the start time [s] of the sub-request at the origin street node - parent_modal_state (RQ_MODAL_STATE): the parent modal state - firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests - Returns: - t_d_node_arrival (tp.Optional[int]): - the pt arrival time of the sub-request at the destination street node - or None if the pt travel costs are not available - """ - pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") - - costs_info = self._query_street_node_pt_travel_costs_1to1( - pt_sub_rq_obj.get_origin_node(), - pt_sub_rq_obj.get_destination_node(), - pt_sub_rq_obj.earliest_start_time, - pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest - ) - - if costs_info is not None: - source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") - else: - source_pt_station_id = None - t_source_walk = None - target_pt_station_id = None - t_target_walk = None - pt_journey_plan_dict = None - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") - - pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() - - self.pt_operator.create_and_record_pt_offer_db( - rid_struct = pt_rid_struct, - operator_id = self.pt_operator_id, - source_station_id = source_pt_station_id, - target_station_id = target_pt_station_id, - source_walking_time = t_source_walk, - target_walking_time = t_target_walk, - pt_journey_plan_dict = pt_journey_plan_dict, - firstmile_amod_operator_id = firstmile_amod_operator_id, - ) - if pt_journey_plan_dict is not None: - t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer - return t_d_node_arrival - else: - return None - - def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of monomodal offers. - - Args: - rid (int): the request id - parent_modal_state (RQ_MODAL_STATE): the parent modal state - offers (tp.Dict[int, TravellerOffer]): the current offers dictionary - Returns: - tp.Dict[int, TravellerOffer]: the updated offers dictionary - """ - for amod_op_id in range(self.n_amod_op): - amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) - LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") - if amod_offer is not None and not amod_offer.service_declined(): - offers[amod_op_id] = amod_offer - return offers def _process_collect_firstmile_offers( self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, @@ -648,114 +311,6 @@ def _process_collect_firstlastmile_offers( offers[intermodal_offer.operator_id] = intermodal_offer return offers - - def _set_sim_start_datetime(self, sim_start_date: str): - """This method sets the simulation start date. - Converts the date string (format YYYYMMDD) to a datetime object. - - Args: - sim_start_date (str): the simulation start date in format YYYYMMDD - """ - if sim_start_date is None: - LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - - if type(sim_start_date) is not str: - sim_start_date = str(int(sim_start_date)) - self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") - - def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: - """This method returns the current datetime based on the simulation time in seconds. - """ - return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) - - def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: - """This method loads the FleetPy-specific street station transfers file. - - Args: - gtfs_dir (str): The directory containing the GTFS data of the operator. - Returns: - pd.DataFrame: The transfer data between the street nodes and the PT stations. - """ - dtypes = { - 'node_id': 'int', - 'closest_station_id': 'str', - 'street_station_transfer_time': 'int', - } - return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) - - def _query_street_node_pt_travel_costs_1to1( - self, o_node: int, d_node: int, est: int, - max_transfers: int = 999, detailed: bool = False - ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - """This method queries the pt travel costs between two street nodes at a given datetime. - The pt station ids will be the closest pt station ids to the street nodes. - - Args: - o_node (int): The origin street node id. - d_node (int): The destination street node id. - est (int): The earliest start time of the request at the origin street node in seconds. - max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. - detailed (bool): Whether to return detailed journey information. Defaults to False. - Returns: - tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - Returns a tuple containing: - (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) - if a public transport journey plan is found. - Returns None if no public transport journey plan is available. - """ - # find pt transfer stations - source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") - target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") - - source_station_departure_seconds: int = est + t_source_walk - source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) - LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") - pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( - source_pt_station_id, target_pt_station_id, - source_station_departure_datetime, - max_transfers, detailed, - ) - if pt_journey_plan_dict is None: - return None - else: - return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict - - def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: - """This method finds the transfer possibility between pt station and street node. - - Args: - node_id (tp.Union[int, str]): The street node id. - direction (str): "pt2street" or "street2pt" - Returns: - tp.Tuple[str, int]: The transfer node id and the walking time. - """ - if self.transfer_search_method == "closest": # closest station or street node - if direction == "street2pt": # find closest pt station from street node - street_node_id: int = int(node_id) - # TODO: allow multiple closest stations? - street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] - if street_station_transfer.empty: - raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") - closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] - walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] - return closest_station_id, walking_time - elif direction == "pt2street": # find closest street node from pt station - pt_station_id: str = str(node_id) - street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] - if street_station_transfers.empty: - raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") - # find the record with the minimum street_station_transfer_time - # TODO: if multiple exist, return all? - min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] - closest_street_node_id: int = min_transfer["node_id"] - walking_time: int = min_transfer["street_station_transfer_time"] - return closest_street_node_id, walking_time - else: - raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") - else: - LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") - raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: """This method determines the earliest start time for the pt sub-request. @@ -770,9 +325,4 @@ def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: # add latest dropoff time constraint check if t_do_latest > old_t_do_latest: t_do_latest = old_t_do_latest - return t_do_latest - - def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': - """This method merges the amod and pt offers into an intermodal offer. - """ - return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) \ No newline at end of file + return t_do_latest \ No newline at end of file diff --git a/src/broker/PTBrokerBasic.py b/src/broker/PTBrokerBasic.py new file mode 100644 index 00000000..6a560e32 --- /dev/null +++ b/src/broker/PTBrokerBasic.py @@ -0,0 +1,584 @@ +# TODO: +# - Adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. +# - Support multiple AMoD operators for firstlastmile requests. + +# -------------------------------------------------------------------------------------------------------------------- # +# standard distribution imports +# ----------------------------- +import logging +from datetime import datetime, timedelta +import typing as tp +import pandas as pd +# additional module imports (> requirements) +# ------------------------------------------ + + +# src imports +# ----------- +from src.broker.BrokerBasic import BrokerBasic +from src.simulation.Offers import IntermodalOffer +if tp.TYPE_CHECKING: + from src.fleetctrl.FleetControlBase import FleetControlBase + from src.fleetctrl.planning.PlanRequest import PlanRequest + from src.ptctrl.PTControlBase import PTControlBase + from src.demand.demand import Demand + from src.routing.road.NetworkBase import NetworkBase + from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest + from src.simulation.Offers import TravellerOffer, PTOffer + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +# ---------------- +from src.misc.globals import * + +LOG = logging.getLogger(__name__) +LARGE_INT = 100000000 +BUFFER_SIZE = 100 + +INPUT_PARAMETERS_PTBroker = { + "doc" : "this class represents a broker platform which handles intermodal requests", + "inherit" : BrokerBasic, + "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + +# -------------------------------------------------------------------------------------------------------------------- # +# main +# ---- +class PTBrokerBasic(BrokerBasic): + def __init__( + self, + n_amod_op: int, + amod_operators: tp.List['FleetControlBase'], + pt_operator: 'PTControlBase', + demand: 'Demand', + routing_engine: 'NetworkBase', + scenario_parameters: dict, + ): + """ + The general attributes for the broker are initialized. + + Args: + n_amod_op (int): number of AMoD operators + amod_operators (tp.List['FleetControlBase']): list of AMoD operators + pt_operator (PTControlBase): PT operator + demand (Demand): demand object + routing_engine (NetworkBase): routing engine + scenario_parameters (dict): scenario parameters + """ + super().__init__(n_amod_op, amod_operators) + + self.demand: Demand = demand + self.routing_engine: NetworkBase = routing_engine + self.pt_operator: PTControlBase = pt_operator + + self.pt_operator_id: int = self.pt_operator.pt_operator_id + self.scenario_parameters: dict = scenario_parameters + + # set whether to always query pure PT offers + self.always_query_pt: bool = self.scenario_parameters.get(G_BROKER_ALWAYS_QUERY_PT, False) + + # set simulation start date for Raptor routing + self.sim_start_datetime: datetime = None + self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) + + # method for finding transfer stations + self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") + # read necessary files based on the transfer search method + # default method: closest transfer station search. + if self.transfer_search_method == "closest": + # load the street-station transfers: used for finding closest station to a street node, or vice versa + try: + self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) + except FileNotFoundError: + LOG.error("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + raise FileNotFoundError("PTBroker: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") + + + def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): + """This method informs the broker that a new request has been made. + Based on the request modal state, the broker will create the appropriate sub-requests + and inform the operators. + + Args: + rid (int): parent request id + rq_obj (RequestBase): request object + sim_time (int): simulation time + """ + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") + + if self.always_query_pt: + # 1. query the PT operator for the pure PT travel costs + _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) + + # 2.1 pure AMoD request or PT request + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.2 AMoD as firstmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.3 AMoD as lastmile request + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + # 2.4 AMoD as firstlastmile request + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: + """This method collects the offers from the operators. + + Args: + rid (int): parent request id + sim_time (int): simulation time + Returns: + tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators + """ + # get parent request modal state + parent_rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + offers: tp.Dict[int, TravellerOffer] = {} + LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") + + # 1. collect PT offers for multimodal requests + if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) + LOG.debug(f"pt offer {pt_offer}") + + if pt_offer is not None and not pt_offer.service_declined(): + offers[self.pt_operator_id] = pt_offer + # register the pt offer in the sub-request + self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) + + # 2.1 collect AMoD offers for MONOMODAL and PT requests + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) + + # 2.2 collect AMoD offers for FIRSTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + offers = self._process_collect_firstmile_offers(rid, parent_rq_obj, parent_modal_state, offers) + + # 2.3 collect AMoD offers for LASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) + + # 2.4 collect AMoD offers for FIRSTLASTMILE requests + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + offers = self._process_collect_firstlastmile_offers(rid, parent_rq_obj, parent_modal_state, offers, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + return offers + + def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: + """This method informs the broker that the user has booked a trip. + """ + amod_confirmed_rids = [] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + # 1. Pure PT offer has been selected + if chosen_operator == self.pt_operator_id: + amod_confirmed_rids.append((rid, rq_obj)) + + # inform all AMoD operators that the request is cancelled + self.inform_user_leaving_system(rid, sim_time) + + # inform PT operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) + # 2. AMoD involved offer has been selected + else: + # non-intermodal offer has been selected + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: # Non-intermodal requests: the chosen operator has the data type int + operator.user_cancels_request(rid, sim_time) + else: + operator.user_confirms_booking(rid, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + # intermodal offer has been selected + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + # chosen_operator has the data type tuple: ((operator_id, sub_trip_id), ...) + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + # inform the pt operator that the request is confirmed + pt_rid_struct: str = f"{rid}_{sub_trip_id}" + pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] + + if parent_modal_state == RQ_MODAL_STATE.LASTMILE: + previous_amod_operator_id = None # no previous amod operator + else: # firstmile or firstlastmile + previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) + else: + # inform the amod operator that the request is confirmed + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + for i, operator in enumerate(self.amod_operators): + if i != operator_id: + operator.user_cancels_request(amod_rid_struct, sim_time) + else: + operator.user_confirms_booking(amod_rid_struct, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + return amod_confirmed_rids + + def inform_user_leaving_system(self, rid: int, sim_time: int): + """This method informs the broker that the user is leaving the system. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(rid, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(fm_amod_rid_struct, sim_time) + + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" + for _, operator in enumerate(self.amod_operators): + try: + operator.user_cancels_request(lm_amod_rid_struct, sim_time) + except KeyError: + # LM AMoD sub-request may not be created if no PT offer is available + LOG.info(f"LM AMoD sub-request {lm_amod_rid_struct} not found when user leaves system, possibly no PT offer available so the LM sub-request was not created.") + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + for _, operator in enumerate(self.amod_operators): + operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) + try: + operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) + except KeyError: + # LM AMoD sub-request may not be created if no PT offer is available + LOG.info(f"LM AMoD sub-request {flm_amod_rid_struct_1} not found when user leaves system, possibly no FM or PT offer available so the LM sub-request was not created.") + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): + """This method informs the operators that the waiting requests have been cancelled. + """ + rq_obj: RequestBase = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + if chosen_operator == self.pt_operator_id: + return + + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) + + elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: + for operator_id, sub_trip_id in chosen_operator: + if operator_id == self.pt_operator_id: + continue + amod_rid_struct: str = f"{rid}_{sub_trip_id}" + operator_id = int(operator_id) + self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): + """This method processes the new monomodal request. + + Args: + rid (int): the request id + rq_obj ('RequestBase'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + for op_id in range(self.n_amod_op): + LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") + self.amod_operators[op_id].user_request(rq_obj, sim_time) + + def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): + """This method processes the new firstmile request. + In this stage, only the first-mile AMoD sub-request is created first; the PT sub-request will be created after receiving the AMoD offer. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + pass + + def _process_inform_lastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE): + """This method processes the new lastmile request. + First, the PT sub-request is created. If the PT offer is available, then the last-mile AMoD sub-request is created. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + pass + + def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE): + """This method processes the new firstlastmile request. + In this stage, only the first-mile AMoD sub-request is created first; the PT and last-mile AMoD sub-requests will be created after receiving the first-mile AMoD offer. + + Args: + rid (int): the request id + rq_obj ('BasicIntermodalRequest'): the request object + sim_time (int): the simulation time + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + pass + + def _inform_amod_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int + ): + """ + This method informs the AMoD operators that a new sub-request has been made. + + Args: + rq_obj ('RequestBase'): the parent request object + sub_trip_id (int): the sub-trip id + leg_o_node (int): the origin node of the sub-request + leg_d_node (int): the destination node of the sub-request + leg_start_time (int): the start time of the sub-request + parent_modal_state (RQ_MODAL_STATE): the parent modal state + """ + amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") + + # get customizable wait time for last mile AMoD pickups + if parent_modal_state == RQ_MODAL_STATE.LASTMILE or (parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE and sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value): + # in this case, the parent request type must be BasicIntermodalRequest + max_wait_time: tp.Optional[int] = rq_obj.get_lastmile_max_wait_time() + else: + # no customizable wait time, operator default wait time will be used + max_wait_time: tp.Optional[int] = None + + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time, max_wait_time=max_wait_time) + + def _inform_pt_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None + ) -> tp.Optional[int]: + """ + This method informs the PT operator that a new sub-request has been made. + + Args: + rq_obj (RequestBase): the parent request object + sub_trip_id (int): the sub_trip id + leg_o_node (int): the origin street node of the sub-request + leg_d_node (int): the destination street node of the sub-request + leg_start_time (int): the start time [s] of the sub-request at the origin street node + parent_modal_state (RQ_MODAL_STATE): the parent modal state + firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests + Returns: + t_d_node_arrival (tp.Optional[int]): + the pt arrival time of the sub-request at the destination street node + or None if the pt travel costs are not available + """ + pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") + + costs_info = self._query_street_node_pt_travel_costs_1to1( + pt_sub_rq_obj.get_origin_node(), + pt_sub_rq_obj.get_destination_node(), + pt_sub_rq_obj.earliest_start_time, + pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest + ) + + if costs_info is not None: + source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") + else: + source_pt_station_id = None + t_source_walk = None + target_pt_station_id = None + t_target_walk = None + pt_journey_plan_dict = None + LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") + + pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() + + self.pt_operator.create_and_record_pt_offer_db( + rid_struct = pt_rid_struct, + operator_id = self.pt_operator_id, + source_station_id = source_pt_station_id, + target_station_id = target_pt_station_id, + source_walking_time = t_source_walk, + target_walking_time = t_target_walk, + pt_journey_plan_dict = pt_journey_plan_dict, + firstmile_amod_operator_id = firstmile_amod_operator_id, + ) + if pt_journey_plan_dict is not None: + t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer + return t_d_node_arrival + else: + return None + + def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of monomodal offers. + + Args: + rid (int): the request id + parent_modal_state (RQ_MODAL_STATE): the parent modal state + offers (tp.Dict[int, TravellerOffer]): the current offers dictionary + Returns: + tp.Dict[int, TravellerOffer]: the updated offers dictionary + """ + for amod_op_id in range(self.n_amod_op): + amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) + LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") + if amod_offer is not None and not amod_offer.service_declined(): + offers[amod_op_id] = amod_offer + return offers + + def _process_collect_firstmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'] + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstmile offers and try to optimize the waiting time of the PT leg. + """ + # get rid struct for all sections + pass + + def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of LM offers. + """ + pass + + def _process_collect_firstlastmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """This method processes the collection of firstlastmile offers. + """ + pass + + def _set_sim_start_datetime(self, sim_start_date: str): + """This method sets the simulation start date. + Converts the date string (format YYYYMMDD) to a datetime object. + + Args: + sim_start_date (str): the simulation start date in format YYYYMMDD + """ + if sim_start_date is None: + LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") + + if type(sim_start_date) is not str: + sim_start_date = str(int(sim_start_date)) + self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") + + def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: + """This method returns the current datetime based on the simulation time in seconds. + """ + return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) + + def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: + """This method loads the FleetPy-specific street station transfers file. + + Args: + gtfs_dir (str): The directory containing the GTFS data of the operator. + Returns: + pd.DataFrame: The transfer data between the street nodes and the PT stations. + """ + dtypes = { + 'node_id': 'int', + 'closest_station_id': 'str', + 'street_station_transfer_time': 'int', + } + return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) + + def _query_street_node_pt_travel_costs_1to1( + self, o_node: int, d_node: int, est: int, + max_transfers: int = 999, detailed: bool = False + ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + """This method queries the pt travel costs between two street nodes at a given datetime. + The pt station ids will be the closest pt station ids to the street nodes. + + Args: + o_node (int): The origin street node id. + d_node (int): The destination street node id. + est (int): The earliest start time of the request at the origin street node in seconds. + max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. + detailed (bool): Whether to return detailed journey information. Defaults to False. + Returns: + tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: + Returns a tuple containing: + (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) + if a public transport journey plan is found. + Returns None if no public transport journey plan is available. + """ + # find pt transfer stations + source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") + target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") + + source_station_departure_seconds: int = est + t_source_walk + source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) + LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") + pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( + source_pt_station_id, target_pt_station_id, + source_station_departure_datetime, + max_transfers, detailed, + ) + if pt_journey_plan_dict is None: + return None + else: + return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict + + def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: + """This method finds the transfer possibility between pt station and street node. + + Args: + node_id (tp.Union[int, str]): The street node id. + direction (str): "pt2street" or "street2pt" + Returns: + tp.Tuple[str, int]: The transfer node id and the walking time. + """ + if self.transfer_search_method == "closest": # closest station or street node + if direction == "street2pt": # find closest pt station from street node + street_node_id: int = int(node_id) + # TODO: allow multiple closest stations? + street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] + if street_station_transfer.empty: + raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") + closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] + walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] + return closest_station_id, walking_time + elif direction == "pt2street": # find closest street node from pt station + pt_station_id: str = str(node_id) + street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] + if street_station_transfers.empty: + raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") + # find the record with the minimum street_station_transfer_time + # TODO: if multiple exist, return all? + min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] + closest_street_node_id: int = min_transfer["node_id"] + walking_time: int = min_transfer["street_station_transfer_time"] + return closest_street_node_id, walking_time + else: + raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") + else: + LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") + raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") + + def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': + """This method merges the amod and pt offers into an intermodal offer. + """ + return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) \ No newline at end of file diff --git a/src/broker/PTBrokerEI.py b/src/broker/PTBrokerEI.py index 9d667e13..239b5e11 100644 --- a/src/broker/PTBrokerEI.py +++ b/src/broker/PTBrokerEI.py @@ -11,7 +11,7 @@ # src imports # ----------- -from src.broker.BrokerBasic import BrokerBasic +from src.broker.PTBrokerBasic import PTBrokerBasic from src.simulation.Offers import IntermodalOffer if tp.TYPE_CHECKING: from src.fleetctrl.FleetControlBase import FleetControlBase @@ -33,7 +33,7 @@ INPUT_PARAMETERS_PTBroker = { "doc" : "this class represents a broker platform which handles intermodal requests", - "inherit" : BrokerBasic, + "inherit" : PTBrokerBasic, "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], "input_parameters_optional": [], "mandatory_modules": [], @@ -43,7 +43,7 @@ # -------------------------------------------------------------------------------------------------------------------- # # main # ---- -class PTBrokerEI(BrokerBasic): +class PTBrokerEI(PTBrokerBasic): def __init__( self, n_amod_op: int, @@ -52,7 +52,6 @@ def __init__( demand: 'Demand', routing_engine: 'NetworkBase', scenario_parameters: dict, - always_query_pt: bool = False, # TODO: make it a scenario parameter ): """ The general attributes for the broker are initialized. @@ -64,236 +63,11 @@ def __init__( demand (Demand): demand object routing_engine (NetworkBase): routing engine scenario_parameters (dict): scenario parameters - always_query_pt (bool): if True, the pure PT offers are always requested """ - super().__init__(n_amod_op, amod_operators) - - self.demand: Demand = demand - self.routing_engine: NetworkBase = routing_engine - self.pt_operator: PTControlBase = pt_operator - - self.pt_operator_id: int = self.pt_operator.pt_operator_id - self.scenario_parameters: dict = scenario_parameters - self.always_query_pt: bool = always_query_pt - - # set simulation start date for Raptor routing - self.sim_start_datetime: datetime = None - self._set_sim_start_datetime(self.scenario_parameters.get(G_PT_SIM_START_DATE, None)) + super().__init__(n_amod_op, amod_operators, pt_operator, demand, routing_engine, scenario_parameters) # set MaaS detour time estimation parameter - self.maas_detour_time_factor: float = self.scenario_parameters.get(G_BROKER_MAAS_DETOUR_TIME_FACTOR , 100) - - # method for finding transfer stations - self.transfer_search_method: str = self.scenario_parameters.get(G_BROKER_TRANSFER_SEARCH_METHOD, "closest") - # read necessary files based on the transfer search method - if self.transfer_search_method == "closest": - # load the street-station transfers: used for finding closest station to a street node, or vice versa - try: - self.street_station_transfers_fp_df = self._load_street_station_transfers_from_gtfs(self.pt_operator.gtfs_dir) - except FileNotFoundError: - LOG.error("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - raise FileNotFoundError("PTBrokerTPCS: street_station_transfers_fp.txt file not found in the GTFS directory, which is required for finding closest transfer stations!") - - - def inform_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int): - """This method informs the broker that a new request has been made. - Based on the request modal state, the broker will create the appropriate sub-requests - and inform the operators. - - Args: - rid (int): parent request id - rq_obj (RequestBase): request object - sim_time (int): simulation time - """ - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - LOG.debug(f"inform request: {rid} at sim time {sim_time} with modal state {parent_modal_state}; query pure PT offer: {self.always_query_pt}") - - if self.always_query_pt: - # 1. query the PT operator for the pure PT travel costs - _ = self._inform_pt_sub_request(rq_obj, RQ_SUB_TRIP_ID.PT.value, rq_obj.get_origin_node(), rq_obj.get_destination_node(), rq_obj.earliest_start_time, parent_modal_state) - - # 2.1 pure AMoD request or PT request - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self._process_inform_monomodal_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.2 AMoD as firstmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - self._process_inform_firstmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.3 AMoD as lastmile request - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - self._process_inform_lastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - # 2.4 AMoD as firstlastmile request - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - self._process_inform_firstlastmile_request(rid, rq_obj, sim_time, parent_modal_state) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: - """This method collects the offers from the operators. - - Args: - rid (int): parent request id - sim_time (int): simulation time - Returns: - tp.Dict[int, TravellerOffer]: a dictionary of offers from the operators - """ - # get parent request modal state - parent_rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() - offers: tp.Dict[int, TravellerOffer] = {} - LOG.debug(f"Collecting offers for request {rid} with modal state {parent_modal_state}") - - # 1. collect PT offers for multimodal requests - if parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value or self.always_query_pt: - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_offer = self.pt_operator.get_current_offer(pt_rid_struct) - LOG.debug(f"pt offer {pt_offer}") - - if pt_offer is not None and not pt_offer.service_declined(): - offers[self.pt_operator_id] = pt_offer - # register the pt offer in the sub-request - self.demand[pt_rid_struct].receive_offer(self.pt_operator_id, pt_offer, None) - - # 2.1 collect AMoD offers for MONOMODAL and PT requests - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - offers = self._process_collect_monomodal_offers(rid, parent_modal_state, offers) - - # 2.2 collect AMoD offers for FIRSTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - offers = self._process_collect_firstmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) - - # 2.3 collect AMoD offers for LASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - offers = self._process_collect_lastmile_offers(rid, parent_modal_state, offers) - - # 2.4 collect AMoD offers for FIRSTLASTMILE requests - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - offers = self._process_collect_firstlastmile_offers_tpcs(rid, parent_rq_obj, parent_modal_state, offers, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - return offers - - def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: - """This method informs the broker that the user has booked a trip. - """ - amod_confirmed_rids = [] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - # 1. Pure PT offer has been selected - if chosen_operator == self.pt_operator_id: - amod_confirmed_rids.append((rid, rq_obj)) - - # inform all AMoD operators that the request is cancelled - self.inform_user_leaving_system(rid, sim_time) - - # inform PT operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) - # 2. AMoD involved offer has been selected - else: - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for i, operator in enumerate(self.amod_operators): - if i != chosen_operator: # Non-multimodal requests: the chosen operator has the data type int - operator.user_cancels_request(rid, sim_time) - else: - operator.user_confirms_booking(rid, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - # inform the pt operator that the request is confirmed - pt_rid_struct: str = f"{rid}_{sub_trip_id}" - pt_sub_rq_obj: BasicIntermodalRequest = self.demand[pt_rid_struct] - - if parent_modal_state == RQ_MODAL_STATE.LASTMILE: - previous_amod_operator_id = None # no previous amod operator - else: # firstmile or firstlastmile - previous_amod_operator_id: int = chosen_operator[0][0] # the first amod operator - self.pt_operator.user_confirms_booking(pt_sub_rq_obj, previous_amod_operator_id) - else: - # inform the amod operator that the request is confirmed - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - for i, operator in enumerate(self.amod_operators): - if i != operator_id: - operator.user_cancels_request(amod_rid_struct, sim_time) - else: - operator.user_confirms_booking(amod_rid_struct, sim_time) - amod_confirmed_rids.append((rid, rq_obj)) - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - return amod_confirmed_rids - - def inform_user_leaving_system(self, rid: int, sim_time: int): - """This method informs the broker that the user is leaving the system. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(rid, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: - fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(fm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: - lm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_AMOD.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(lm_amod_rid_struct, sim_time) - - elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" - flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" - for _, operator in enumerate(self.amod_operators): - operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) - operator.user_cancels_request(flm_amod_rid_struct_1, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def inform_waiting_request_cancellations(self, chosen_operator: int, rid: int, sim_time: int): - """This method informs the operators that the waiting requests have been cancelled. - """ - rq_obj: RequestBase = self.demand[rid] - parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() - - if chosen_operator == self.pt_operator_id: - return - - if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: - self.amod_operators[chosen_operator].user_cancels_request(rid, sim_time) - - elif parent_modal_state.value > RQ_MODAL_STATE.MONOMODAL.value and parent_modal_state.value < RQ_MODAL_STATE.PT.value: - for operator_id, sub_trip_id in chosen_operator: - if operator_id == self.pt_operator_id: - continue - amod_rid_struct: str = f"{rid}_{sub_trip_id}" - operator_id = int(operator_id) - self.amod_operators[operator_id].user_cancels_request(amod_rid_struct, sim_time) - - else: - raise ValueError(f"Invalid modal state: {parent_modal_state}") - - def _process_inform_monomodal_request(self, rid: int, rq_obj: 'RequestBase', sim_time: int, parent_modal_state: RQ_MODAL_STATE,): - """This method processes the new monomodal request. - - Args: - rid (int): the request id - rq_obj ('RequestBase'): the request object - sim_time (int): the simulation time - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - for op_id in range(self.n_amod_op): - LOG.debug(f"AMoD Request {rid} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(rq_obj, sim_time) + self.maas_detour_time_factor: float = self.scenario_parameters.get(G_BROKER_MAAS_DETOUR_TIME_FACTOR , 100) def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): """This method processes the new firstmile request. @@ -316,7 +90,7 @@ def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRe fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" fm_amod_sub_rq_obj: BasicIntermodalRequest = self.demand[fm_amod_rid_struct] # create sub-request for PT - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj, "latest") + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, fm_amod_sub_rq_obj) # estimate the earliest start time of the pt sub-request fm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt # create the pt sub-request @@ -366,7 +140,7 @@ def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermod flm_amod_sub_rq_obj_0: BasicIntermodalRequest = self.demand[flm_amod_rid_struct_0] # create sub-request for PT # estimate the dropoff time of the amod sub-request - estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0, "latest") + estimated_amod_dropoff_time: int = self._estimate_amod_dropoff_time(op_id, flm_amod_sub_rq_obj_0) # estimate the earliest start time of the pt sub-request flm_est_pt_mod: int = estimated_amod_dropoff_time + self.amod_operators[op_id].const_bt # create the pt sub-request @@ -374,143 +148,15 @@ def _process_inform_firstlastmile_request(self, rid: int, rq_obj: 'BasicIntermod # create sub-request for the same AMoD operator if flm_pt_arrival is None: - raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}") + raise ValueError(f"PT offer is not available for sub_request {rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}, skipping to the next AMoD operator.") else: # last mile AMoD sub-request self._inform_amod_sub_request(rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_1.value, transfer_street_node_1, rq_obj.get_destination_node(), flm_pt_arrival, parent_modal_state, op_id, sim_time) - - def _inform_amod_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int - ): - """ - This method informs the AMoD operators that a new sub-request has been made. - - Args: - rq_obj ('RequestBase'): the parent request object - sub_trip_id (int): the sub-trip id - leg_o_node (int): the origin node of the sub-request - leg_d_node (int): the destination node of the sub-request - leg_start_time (int): the start time of the sub-request - parent_modal_state (RQ_MODAL_STATE): the parent modal state - """ - amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") - self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) - - def _inform_pt_sub_request( - self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, - parent_modal_state: RQ_MODAL_STATE, firstmile_amod_operator_id: int = None - ) -> tp.Optional[int]: - """ - This method informs the PT operator that a new sub-request has been made. - - Args: - rq_obj (RequestBase): the parent request object - sub_trip_id (int): the sub_trip id - leg_o_node (int): the origin street node of the sub-request - leg_d_node (int): the destination street node of the sub-request - leg_start_time (int): the start time [s] of the sub-request at the origin street node - parent_modal_state (RQ_MODAL_STATE): the parent modal state - firstmile_amod_operator_id (int): the id of the firstmile amod operator, only used for FM and FLM requests - Returns: - t_d_node_arrival (tp.Optional[int]): - the pt arrival time of the sub-request at the destination street node - or None if the pt travel costs are not available - """ - pt_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To PT operator {self.pt_operator_id} ...") - - costs_info = self._query_street_node_pt_travel_costs_1to1( - pt_sub_rq_obj.get_origin_node(), - pt_sub_rq_obj.get_destination_node(), - pt_sub_rq_obj.earliest_start_time, - pt_sub_rq_obj.get_max_transfers(), # the request type should be BasicIntermodalRequest - ) - - if costs_info is not None: - source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict = costs_info - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: Found offer with source_pt_station_id {source_pt_station_id}, t_source_walk {t_source_walk}, target_pt_station_id {target_pt_station_id}, t_target_walk {t_target_walk}, pt_journey_plan_dict {pt_journey_plan_dict}") - else: - source_pt_station_id = None - t_source_walk = None - target_pt_station_id = None - t_target_walk = None - pt_journey_plan_dict = None - LOG.debug(f"PT sub-request {pt_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: No PT offer has been found!") - - pt_rid_struct: str = pt_sub_rq_obj.get_rid_struct() - - self.pt_operator.create_and_record_pt_offer_db( - rid_struct = pt_rid_struct, - operator_id = self.pt_operator_id, - source_station_id = source_pt_station_id, - target_station_id = target_pt_station_id, - source_walking_time = t_source_walk, - target_walking_time = t_target_walk, - pt_journey_plan_dict = pt_journey_plan_dict, - firstmile_amod_operator_id = firstmile_amod_operator_id, - ) - if pt_journey_plan_dict is not None: - t_d_node_arrival: int = self.pt_operator.get_current_offer(pt_rid_struct, firstmile_amod_operator_id).destination_node_arrival_time # Offer type: PTOffer - return t_d_node_arrival - else: - return None - - def _process_collect_monomodal_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of monomodal offers. - - Args: - rid (int): the request id - parent_modal_state (RQ_MODAL_STATE): the parent modal state - offers (tp.Dict[int, TravellerOffer]): the current offers dictionary - Returns: - tp.Dict[int, TravellerOffer]: the updated offers dictionary - """ - for amod_op_id in range(self.n_amod_op): - amod_offer = self.amod_operators[amod_op_id].get_current_offer(rid) - LOG.debug(f"Collecting amod offer for request {rid} with modal state {parent_modal_state} from operator {amod_op_id}: {amod_offer}") - if amod_offer is not None and not amod_offer.service_declined(): - offers[amod_op_id] = amod_offer - return offers - def _process_collect_firstmile_offers_tpcs_phase1( - self, rid: int, fm_amod_rid_struct: str, fm_pt_rid_struct: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstmile offers using Phase 1 of the TPCS approach. - """ - # collect all offers - fm_amod_offer_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) - self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer_p1, None) - LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer_p1} in 1st phase.") - - fm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p1, None) - LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer_p1} in 1st phase.") - - if fm_amod_offer_p1 is None or fm_amod_offer_p1.service_declined(): - LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct} in FM 1st phase.") - return None, None - - if fm_pt_offer_p1 is None or fm_pt_offer_p1.service_declined(): - LOG.info(f"PT offer is not available for request {rid} in FM 1st phase.") - return None, fm_amod_offer_p1 - - if fm_pt_offer_p1 is not None and not fm_pt_offer_p1.service_declined() and fm_amod_offer_p1 is not None and not fm_amod_offer_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - return intermodal_offer_p1, fm_amod_offer_p1 - - def _process_collect_firstmile_offers_tpcs( - self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, - offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + def _process_collect_firstmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer'], ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstmile offers using TPCS approach. + """This method processes the collection of firstmile offers. """ # get rid struct for all sections fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" @@ -518,78 +164,37 @@ def _process_collect_firstmile_offers_tpcs( for amod_op_id in range(self.n_amod_op): # TODO: if there are multiple AMoD operators, the PT offer can be overwritten here!!! - # 1. Phase 1 - intermodal_offer_p1, fm_amod_offer_p1 = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - # No amod offer in phase 1, skip to next amod operator - if fm_amod_offer_p1 is None: + # 1. collect FM AMoD offer + fm_amod_offer: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + LOG.debug(f"Collecting fm_amod offer for request {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer}.") + # check if FM AMoD offer is available + if fm_amod_offer is None or fm_amod_offer.service_declined(): + LOG.info(f"FM AMoD offer is not available for sub_request {fm_amod_rid_struct}, skipping to next AMoD operator.") continue - - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + # register the FM AMoD offer in the sub-request + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer, None) + + # 2. collect FM PT offer + fm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) + LOG.debug(f"Collecting fm_pt offer for request {fm_pt_rid_struct} from operator {self.pt_operator_id}: {fm_pt_offer}.") + # check if PT offer is available + if fm_pt_offer is None or fm_pt_offer.service_declined(): + LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct}, skipping to next AMoD operator.") continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: - continue - else: - # 2. Phase 2 - # 2.1 re-query the pt offer - # 2.1.1 get the transfer station id and its closest pt station - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # register the PT offer in the sub-request + self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer, None) - # 2.1.2 determine the earliest start time of the pt sub-request - fm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj,amod_op_id, fm_amod_offer_p1) - # 2.1.3 create the pt sub-request and get the pt arrival time - fm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FM_PT.value, - transfer_street_node, - parent_rq_obj.get_destination_node(), - fm_est_pt_mod, - parent_modal_state, - amod_op_id, - ) - fm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(fm_pt_rid_struct, amod_op_id) - # self.demand[fm_pt_rid_struct].receive_offer(self.pt_operator_id, fm_pt_offer_p2, None) - if fm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {fm_pt_rid_struct} in FM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.2 create intermodal offer - sub_trip_offers: tp.Dict[int, TravellerOffer] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") + # 3. create intermodal offer + sub_trip_offers: tp.Dict[int, TravellerOffer] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FM_AMOD.value] = fm_amod_offer + sub_trip_offers[RQ_SUB_TRIP_ID.FM_PT.value] = fm_pt_offer + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer for request {rid}: {intermodal_offer}") - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 + # for this communication strategy, the FM AMoD DO time does not need to be updated. - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: 'PlanRequest' = self.amod_operators[amod_op_id].rq_dict[fm_amod_rid_struct] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, fm_amod_offer_p1, fm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self._process_inform_firstmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, _ = self._process_collect_firstmile_offers_tpcs_phase1(rid, fm_amod_rid_struct, fm_pt_rid_struct, parent_modal_state, amod_op_id) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 - - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") + # 4. register the intermodal offer + offers[intermodal_offer.operator_id] = intermodal_offer return offers def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer']) -> tp.Dict[int, 'TravellerOffer']: @@ -625,46 +230,10 @@ def _process_collect_lastmile_offers(self, rid: int, parent_modal_state: RQ_MODA LOG.info(f"PT offer is not available for sub_request {lm_pt_rid_struct}") return offers - def _process_collect_firstlastmile_offers_tpcs_phase1( - self, rid: int, flm_amod_rid_struct_0: str, flm_pt_rid_struct: str, flm_amod_rid_struct_1: str, - parent_modal_state: RQ_MODAL_STATE, amod_op_id: int - ) -> tp.Tuple[tp.Optional['IntermodalOffer'], tp.Optional['TravellerOffer']]: - """This method processes the collection of firstlastmile offers using phase 1 of the TPCS approach. - """ - flm_amod_offer_0_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) - self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0_p1, None) - LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0_p1} in FLM 1st phase.") - - flm_pt_offer_p1: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p1, None) - LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer_p1} in FLM 1st phase.") - - flm_amod_offer_1_p1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p1, None) - LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1_p1} in FLM 1st phase.") - - if flm_amod_offer_0_p1 is None or flm_amod_offer_0_p1.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0} in FLM 1st phase.") - return None, None - - if flm_pt_offer_p1 is not None and not flm_pt_offer_p1.service_declined() and flm_amod_offer_1_p1 is not None and not flm_amod_offer_1_p1.service_declined(): - LOG.info(f"All offers are available for request {rid} in FLM 1st phase, creating intermodal offer.") - # create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p1 - intermodal_offer_p1: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - else: - LOG.info(f"PT offer or LastMile AMoD offer is not available for request {rid} in FLM 1st phase.") - intermodal_offer_p1 = None - return intermodal_offer_p1, flm_amod_offer_0_p1 - - def _process_collect_firstlastmile_offers_tpcs( - self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, - offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + def _process_collect_firstlastmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, offers: tp.Dict[int, 'TravellerOffer'], sim_time: int ) -> tp.Dict[int, 'TravellerOffer']: - """This method processes the collection of firstlastmile offers using 3-phases approach. + """This method processes the collection of firstlastmile offers. """ # get rid struct for all sections flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" @@ -672,218 +241,50 @@ def _process_collect_firstlastmile_offers_tpcs( flm_amod_rid_struct_1: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" for amod_op_id in range(self.n_amod_op): - # 1. Phase 1 - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - # No firstmile amod offer in phase 1, skip to next amod operator - if flm_amod_offer_0_p1 is None: + # 1. collect FLM AMoD offer 0 + flm_amod_offer_0: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + LOG.debug(f"Collecting flm_amod_0 offer for request {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0}") + # check if FLM AMoD offer 0 is available + if flm_amod_offer_0 is None or flm_amod_offer_0.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_0}, skipping to next AMoD operator.") continue - - # check if only phase 1 is used and process accordingly - if self.use_phase_1_only and intermodal_offer_p1 is not None: - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Default"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0, None) + + # 2. collect FLM PT offer + flm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) + LOG.debug(f"Collecting flm_pt offer for request {flm_pt_rid_struct} from operator {self.pt_operator_id}: {flm_pt_offer}") + # check if PT offer is available + if flm_pt_offer is None or flm_pt_offer.service_declined(): + LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct}, skipping to next AMoD operator.") continue - elif self.use_phase_1_only and intermodal_offer_p1 is None: + self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer, None) + + # 3. collect FLM AMoD offer 1 + flm_amod_offer_1: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) + LOG.debug(f"Collecting flm_amod_1 offer for request {flm_amod_rid_struct_1} from operator {amod_op_id}: {flm_amod_offer_1}") + # check if FLM AMoD offer 1 is available + if flm_amod_offer_1 is None or flm_amod_offer_1.service_declined(): + LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1}, skipping to next AMoD operator.") continue - else: - # 2. Phase 2 - # 2.0 cancel lastmile amod sub-request - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - - # 2.2 re-query the pt offer - # 2.2.1 get the transfer station ids and their closest pt stations - transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() - transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") - transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1, None) - # 2.2.2 determine the earliest start time of the pt sub-request - flm_est_pt_mod: int = self._determine_est_pt_mod(parent_rq_obj, amod_op_id, flm_amod_offer_0_p1) - - # 2.2.3 create the pt sub-request and get the pt arrival time - flm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_PT.value, - transfer_street_node_0, - transfer_street_node_1, - flm_est_pt_mod, - parent_modal_state, - amod_op_id, - ) - flm_pt_offer_p2: 'TravellerOffer' = self.pt_operator.get_current_offer(flm_pt_rid_struct, amod_op_id) - self.demand[flm_pt_rid_struct].receive_offer(self.pt_operator_id, flm_pt_offer_p2, None) - if flm_pt_arrival is None: - LOG.info(f"PT offer is not available for sub_request {flm_pt_rid_struct} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.3 re-query the lastmile amod offer - self._inform_amod_sub_request( - parent_rq_obj, - RQ_SUB_TRIP_ID.FLM_AMOD_1.value, - transfer_street_node_1, - parent_rq_obj.get_destination_node(), - flm_pt_arrival, - parent_modal_state, - amod_op_id, - sim_time, - ) - flm_amod_offer_1_p2: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_1) - self.demand[flm_amod_rid_struct_1].receive_offer(amod_op_id, flm_amod_offer_1_p2, None) - if flm_amod_offer_1_p2 is None or flm_amod_offer_1_p2.service_declined(): - LOG.info(f"AMoD offer is not available for sub_request {flm_amod_rid_struct_1} in FLM 2nd phase, creating rejection.") - intermodal_offer_p2 = None - else: - # 2.4 create intermodal offer - sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0_p1 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer_p2 - sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1_p2 - intermodal_offer_p2: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) - LOG.info(f"Created intermodal offer in 2nd phase: {intermodal_offer_p2}") - - # 3. Phase 3 - # 3.1 check if the offer from phase 2 is better than the offer from phase 1 - comparison_results: int = self._compare_two_intermodal_offers(intermodal_offer_p1, intermodal_offer_p2) - if comparison_results == 2: - LOG.info(f"Offer from phase 2 is better than the offer from phase 1, accepting the offer from phase 2.") - intermodal_offer_p2.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 2"}) - offers[intermodal_offer_p2.operator_id] = intermodal_offer_p2 - - # 3.2 update the first amod offer with the latest dropoff time - sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict[flm_amod_rid_struct_0] - old_t_do_latest: int = sub_prq_obj.t_do_latest - new_t_do_latest: int = self._determine_amod_latest_dropoff_time(parent_rq_obj, flm_amod_offer_0_p1, flm_pt_offer_p2.get(G_OFFER_WAIT), old_t_do_latest) - sub_prq_obj.set_new_dropoff_time_constraint(new_t_do_latest) - - elif comparison_results == 1: - LOG.info(f"Offer from phase 2 is not better than the offer from phase 1, accepting the offer from phase 1, rolling back all changes in phase 2.") - # 3.2 rollback all changes in phase 2 - self.amod_operators[amod_op_id].user_cancels_request(flm_amod_rid_struct_1, sim_time) - self._process_inform_firstlastmile_request(rid, parent_rq_obj, sim_time, parent_modal_state) - intermodal_offer_p1, flm_amod_offer_0_p1 = self._process_collect_firstlastmile_offers_tpcs_phase1( - rid, flm_amod_rid_struct_0, flm_pt_rid_struct, flm_amod_rid_struct_1, parent_modal_state, amod_op_id - ) - intermodal_offer_p1.extend_offer(additional_offer_parameters={G_IM_OFFER_TYPE: "TPCS Phase 1"}) - offers[intermodal_offer_p1.operator_id] = intermodal_offer_p1 + # 4. create intermodal offer + sub_trip_offers: tp.Dict[int, 'TravellerOffer'] = {} + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_0.value] = flm_amod_offer_0 + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_PT.value] = flm_pt_offer + sub_trip_offers[RQ_SUB_TRIP_ID.FLM_AMOD_1.value] = flm_amod_offer_1 + intermodal_offer: 'IntermodalOffer' = self._create_intermodal_offer(rid, sub_trip_offers, parent_modal_state) + LOG.info(f"Created intermodal offer for request {rid}: {intermodal_offer}") + + # for this communication strategy, the FLM AMoD DO time does not need to be updated. - elif comparison_results == 0: - LOG.info(f"Both offers from phase 1 and phase 2 are not available, skipping to next operator.") - continue - else: - raise ValueError(f"Invalid comparison results: {comparison_results}") + # 5. register the intermodal offer + offers[intermodal_offer.operator_id] = intermodal_offer return offers - - def _set_sim_start_datetime(self, sim_start_date: str): - """This method sets the simulation start date. - Converts the date string (format YYYYMMDD) to a datetime object. - - Args: - sim_start_date (str): the simulation start date in format YYYYMMDD - """ - if sim_start_date is None: - LOG.error("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - raise ValueError("PTBrokerTPCS: Simulation start date for PT routing not provided in scenario parameters!") - - if type(sim_start_date) is not str: - sim_start_date = str(int(sim_start_date)) - self.sim_start_datetime = datetime.strptime(sim_start_date, "%Y%m%d") - - def _get_current_datetime(self, sim_time_in_seconds: int) -> datetime: - """This method returns the current datetime based on the simulation time in seconds. - """ - return self.sim_start_datetime + timedelta(seconds=int(sim_time_in_seconds)) - - def _load_street_station_transfers_from_gtfs(self, gtfs_dir: str) -> pd.DataFrame: - """This method loads the FleetPy-specific street station transfers file. - - Args: - gtfs_dir (str): The directory containing the GTFS data of the operator. - Returns: - pd.DataFrame: The transfer data between the street nodes and the PT stations. - """ - dtypes = { - 'node_id': 'int', - 'closest_station_id': 'str', - 'street_station_transfer_time': 'int', - } - return pd.read_csv(os.path.join(gtfs_dir, "street_station_transfers_fp.txt"), dtype=dtypes) - - def _query_street_node_pt_travel_costs_1to1( - self, o_node: int, d_node: int, est: int, - max_transfers: int = 999, detailed: bool = False - ) -> tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - """This method queries the pt travel costs between two street nodes at a given datetime. - The pt station ids will be the closest pt station ids to the street nodes. - - Args: - o_node (int): The origin street node id. - d_node (int): The destination street node id. - est (int): The earliest start time of the request at the origin street node in seconds. - max_transfers (int): The maximum number of transfers allowed in the journey, 999 for no limit. - detailed (bool): Whether to return detailed journey information. Defaults to False. - Returns: - tp.Optional[tp.Tuple[int, int, int, int, tp.Dict[str, tp.Any]]]: - Returns a tuple containing: - (source_pt_station_id, t_source_walking, target_pt_station_id, t_target_walking, pt_journey_plan_dict) - if a public transport journey plan is found. - Returns None if no public transport journey plan is available. - """ - # find pt transfer stations - source_pt_station_id, t_source_walk = self._find_transfer_info(o_node, "street2pt") - target_pt_station_id, t_target_walk = self._find_transfer_info(d_node, "street2pt") - - source_station_departure_seconds: int = est + t_source_walk - source_station_departure_datetime: datetime = self._get_current_datetime(source_station_departure_seconds) - LOG.debug(f"Query PT travel costs: {o_node} -> {d_node} (stations: {source_pt_station_id} -> {target_pt_station_id}) at {est} (station departure: {source_station_departure_datetime})") - pt_journey_plan_dict: tp.Union[tp.Dict[str, tp.Any], None] = self.pt_operator.return_fastest_pt_journey_1to1( - source_pt_station_id, target_pt_station_id, - source_station_departure_datetime, - max_transfers, detailed, - ) - if pt_journey_plan_dict is None: - return None - else: - return source_pt_station_id, t_source_walk, target_pt_station_id, t_target_walk, pt_journey_plan_dict - - def _find_transfer_info(self, node_id: tp.Union[int, str], direction: str) -> tp.Tuple[str, int]: - """This method finds the transfer possibility between pt station and street node. - - Args: - node_id (tp.Union[int, str]): The street node id. - direction (str): "pt2street" or "street2pt" - Returns: - tp.Tuple[str, int]: The transfer node id and the walking time. - """ - if self.transfer_search_method == "closest": # closest station or street node - if direction == "street2pt": # find closest pt station from street node - street_node_id: int = int(node_id) - # TODO: allow multiple closest stations? - street_station_transfer = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["node_id"] == street_node_id] - if street_station_transfer.empty: - raise ValueError(f"Street node id {street_node_id} not found in the street station transfers file") - closest_station_id: str = street_station_transfer["closest_station_id"].iloc[0] - walking_time: int = street_station_transfer["street_station_transfer_time"].iloc[0] - return closest_station_id, walking_time - elif direction == "pt2street": # find closest street node from pt station - pt_station_id: str = str(node_id) - street_station_transfers = self.street_station_transfers_fp_df[self.street_station_transfers_fp_df["closest_station_id"] == pt_station_id] - if street_station_transfers.empty: - raise ValueError(f"PT station id {pt_station_id} not found in the street station transfers file") - # find the record with the minimum street_station_transfer_time - # TODO: if multiple exist, return all? - min_transfer = street_station_transfers.loc[street_station_transfers["street_station_transfer_time"].idxmin()] - closest_street_node_id: int = min_transfer["node_id"] - walking_time: int = min_transfer["street_station_transfer_time"] - return closest_street_node_id, walking_time - else: - raise ValueError(f"Invalid direction: {direction}. Must be 'pt2street' or 'street2pt'.") - else: - LOG.debug(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented. Using 'closest' instead.") - raise NotImplementedError(f"PTBrokerTPCS: Transfer search method '{self.transfer_search_method}' not implemented.") def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermodalRequest') -> tp.Optional[int]: """This method estimates the dropoff time of an amod sub-request. + This time point marks the start of alighting the FM amod vehicle. Args: amod_op_id (int): the id of the amod operator @@ -891,54 +292,13 @@ def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermo Returns: int: the dropoff time of the sub-request """ - # get amod dropoff time range sub_rq_rid_struct: str = sub_rq_obj.get_rid_struct() sub_prq_obj: PlanRequest = self.amod_operators[amod_op_id].rq_dict.get(sub_rq_rid_struct, None) - amod_service_latest_dropoff_time: int = sub_prq_obj.t_do_latest + self.amod_operators[amod_op_id].const_bt # TODO: check if const_bt should be added here - maas_estimated_latest_dropoff_time: int = sub_rq_obj.earliest_start_time * self.maas_detour_time_factor - return sub_prq_obj.t_do_latest - - def _determine_est_pt_mod(self, rq_obj: 'RequestBase', amod_op_id: int, amod_offer: 'TravellerOffer') -> int: - """This method determines the earliest start time for the pt sub-request. - """ - t_est_pt_mod: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + self.amod_operators[amod_op_id].const_bt - return t_est_pt_mod - - def _determine_amod_latest_dropoff_time(self, rq_obj: 'RequestBase', amod_offer: 'TravellerOffer', pt_waiting_time: int, old_t_do_latest: int) -> tp.Optional[int]: - """This method determines the latest dropoff time for the amod sub-request. - """ - t_do_latest: int = rq_obj.earliest_start_time + amod_offer.get(G_OFFER_WAIT) + amod_offer.get(G_OFFER_DRIVE) + pt_waiting_time - # add latest dropoff time constraint check - if t_do_latest > old_t_do_latest: - t_do_latest = old_t_do_latest - return t_do_latest - - def _create_intermodal_offer(self, rid: int, sub_trip_offers: tp.Dict[int, 'TravellerOffer'], rq_modal_state: RQ_MODAL_STATE) -> 'IntermodalOffer': - """This method merges the amod and pt offers into an intermodal offer. - """ - return IntermodalOffer(rid, sub_trip_offers, rq_modal_state) - - def _compare_two_intermodal_offers(self, offer_1: 'IntermodalOffer', offer_2: 'IntermodalOffer') -> int: - """This method compares two intermodal offers based on availability and arrival time at destination node. - If offer_1 and offer_2 are both None, it returns 0. - If offer_1 is None and offer_2 is not None, it returns 2. - If offer_1 is not None and offer_2 is None, it returns 1. - If offer_1 is better than offer_2, it returns 1. - If offer_1 is worse than offer_2, it returns 2. - If offer_1 and offer_2 are equally good, it returns 2. - """ - if offer_1 is None and offer_2 is None: - return 0 - elif offer_1 is None and offer_2 is not None: - return 2 - elif offer_1 is not None and offer_2 is None: - return 1 - else: - duration_p1: int = offer_1.get(G_IM_OFFER_DURATION) - duration_p2: int = offer_2.get(G_IM_OFFER_DURATION) - if duration_p1 <= duration_p2: - return 1 - elif duration_p1 > duration_p2: - return 2 - else: - raise ValueError(f"Invalid comparison results: {duration_p1} and {duration_p2}") \ No newline at end of file + + prq_direct_tt = sub_prq_obj.init_direct_tt + amod_boarding_time = self.amod_operators[amod_op_id].const_bt + prq_pu_latest = sub_prq_obj.t_pu_latest + maas_estimated_prq_max_trip_time = (100 + self.maas_detour_time_factor) * (prq_direct_tt + amod_boarding_time) / 100 + + maas_estimated_latest_dropoff_time: int = prq_pu_latest + int(maas_estimated_prq_max_trip_time) + return maas_estimated_latest_dropoff_time \ No newline at end of file diff --git a/src/misc/globals.py b/src/misc/globals.py index 3be8a265..d474e389 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -75,6 +75,7 @@ G_BROKER_TYPE = "broker_type" G_BROKER_TRANSFER_SEARCH_METHOD = "broker_transfer_search_method" # method for finding transfer stations: "closest" or "best_overall" G_BROKER_MAAS_DETOUR_TIME_FACTOR = "broker_maas_detour_time_factor" # factor to estimate detour time for MaaS intermodal trips (default: 1.0) +G_BROKER_ALWAYS_QUERY_PT = "broker_always_query_pt" # if true, pure PT offers are always queried as a backup option # public transport specific attributes G_PT_TYPE = "pt_type" diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index 5c80bd88..c601840c 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -119,6 +119,7 @@ def get_src_broker_modules(): broker_dict = {} # str -> (module path, class name) broker_dict["BrokerBasic"] = ("src.broker.BrokerBasic", "BrokerBasic") broker_dict["PTBroker"] = ("src.broker.PTBroker", "PTBroker") + broker_dict["PTBrokerEI"] = ("src.broker.PTBrokerEI", "PTBrokerEI") # add development content if dev_content is not None: dev_broker_dict = dev_content.add_broker_modules() diff --git a/src/simulation/Offers.py b/src/simulation/Offers.py index 5f1a511a..7b38e02c 100644 --- a/src/simulation/Offers.py +++ b/src/simulation/Offers.py @@ -175,6 +175,9 @@ def __init__( self.origin_node_arrival_time = source_station_departure_time - source_walking_time self.destination_node_arrival_time = target_station_arrival_time + target_walking_time + # the latest arrival time at the origin node is the arrival time plus the waiting time buffer + self.origin_node_latest_arrival_time = self.origin_node_arrival_time + waiting_time + self.pt_segment_duration = self.destination_node_arrival_time - self.origin_node_arrival_time offered_driving_time = self.pt_segment_duration - waiting_time diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv index 8b1b006d..7a44e9d1 100644 --- a/studies/example_study/scenarios/example_im.csv +++ b/studies/example_study/scenarios/example_im.csv @@ -1,3 +1,4 @@ -scenario_name,op_module,rq_file,op_fleet_composition,broker_type,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,evaluation_method,sim_env,user_max_decision_time -example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBroker,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file +scenario_name,op_module,rq_file,op_fleet_composition,broker_type,broker_maas_detour_time_factor,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,evaluation_method,sim_env,user_max_decision_time +example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbrokerEI_mdtf30,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,30,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From f6b6eeb0af24363202a28ae1dd89db543e55fbe2 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Wed, 4 Feb 2026 15:27:18 +0100 Subject: [PATCH 25/31] Add automatic cancellation mechanism when FM AMoD is late for PT connection. --- src/broker/PTBrokerEI.py | 114 +++++++++++- src/demand/TravelerModels.py | 10 ++ src/evaluation/intermodal.py | 167 +++++++++++++++++- src/misc/globals.py | 1 + src/ptctrl/PTControlBasic.py | 20 +++ .../example_study/scenarios/example_im.csv | 4 +- 6 files changed, 313 insertions(+), 3 deletions(-) diff --git a/src/broker/PTBrokerEI.py b/src/broker/PTBrokerEI.py index 239b5e11..89e381c3 100644 --- a/src/broker/PTBrokerEI.py +++ b/src/broker/PTBrokerEI.py @@ -301,4 +301,116 @@ def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermo maas_estimated_prq_max_trip_time = (100 + self.maas_detour_time_factor) * (prq_direct_tt + amod_boarding_time) / 100 maas_estimated_latest_dropoff_time: int = prq_pu_latest + int(maas_estimated_prq_max_trip_time) - return maas_estimated_latest_dropoff_time \ No newline at end of file + return maas_estimated_latest_dropoff_time + + def acknowledge_user_alighting(self, op_id: int, rid_struct: str, vid: int, alighting_time: int): + """Override to check if FM passenger can catch their PT connection. + + After FM AMoD alighting completes, check if the alighting time is still + within the PT offer's origin_node_latest_arrival_time. If not, cancel + subsequent offers and mark the request as uncatchable. + + Args: + op_id (int): the AMoD operator id + rid_struct (str): the request id struct (e.g., "123_1" for sub-request) + vid (int): the vehicle id + alighting_time (int): the simulation time when alighting completes + """ + # Call parent implementation first + super().acknowledge_user_alighting(op_id, rid_struct, vid, alighting_time) + + # Check if this is a FM or FLM first-leg AMoD sub-request + rid_struct_str = str(rid_struct) + if "_" in rid_struct_str: + parts = rid_struct_str.rsplit("_", 1) + parent_rid = int(parts[0]) + sub_trip_id = int(parts[1]) + + # Check FM case: FM_AMOD alighting completed + if sub_trip_id == RQ_SUB_TRIP_ID.FM_AMOD.value: + self._check_fm_pt_catchability(parent_rid, sub_trip_id, alighting_time, RQ_SUB_TRIP_ID.FM_PT.value, op_id) + # Check FLM case: FLM_AMOD_0 alighting completed + elif sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_0.value: + self._check_fm_pt_catchability(parent_rid, sub_trip_id, alighting_time, RQ_SUB_TRIP_ID.FLM_PT.value, op_id) + + def _check_fm_pt_catchability(self, parent_rid: int, amod_sub_trip_id: int, alighting_time: int, pt_sub_trip_id: int, amod_op_id: int): + """Check if passenger can catch their PT connection after FM AMoD alighting. + + Args: + parent_rid (int): the parent request id + amod_sub_trip_id (int): the sub-trip id of the completed AMoD leg + alighting_time (int): the simulation time when alighting completes + pt_sub_trip_id (int): the sub-trip id of the PT leg to check + amod_op_id (int): the AMoD operator id that served the FM leg + """ + # Get PT offer + pt_rid_struct = f"{parent_rid}_{pt_sub_trip_id}" + + # Get the PT offer for the specific AMoD operator that served the FM leg + pt_offer: 'PTOffer' = self.pt_operator.get_current_offer(pt_rid_struct, amod_op_id) + + if pt_offer is None or pt_offer.service_declined(): + LOG.debug(f"No PT offer found for {pt_rid_struct}, skipping catchability check") + return + + # Check catchability: alighting_time vs origin_node_latest_arrival_time + origin_node_latest_arrival_time = pt_offer.origin_node_latest_arrival_time + + if alighting_time > origin_node_latest_arrival_time: + LOG.warning(f"Request {parent_rid}: PT uncatchable! " + f"Alighting time {alighting_time} > PT latest arrival {origin_node_latest_arrival_time} " + f"(delay: {alighting_time - origin_node_latest_arrival_time}s)") + self._handle_uncatchable_pt(parent_rid, alighting_time, amod_op_id) + else: + LOG.debug(f"Request {parent_rid}: PT catchable. " + f"Alighting time {alighting_time} <= PT latest arrival {origin_node_latest_arrival_time} " + f"(buffer: {origin_node_latest_arrival_time - alighting_time}s)") + + def _handle_uncatchable_pt(self, parent_rid: int, sim_time: int, amod_op_id: int): + """Handle the case when passenger cannot catch their PT connection. + + This method: + 1. Marks the parent request as uncatchable + 2. Cancels subsequent sub-requests (PT and any LM AMoD) + + Args: + parent_rid (int): the parent request id + sim_time (int): the current simulation time + amod_op_id (int): the AMoD operator id that served the FM leg + """ + parent_rq_obj: 'BasicIntermodalRequest' = self.demand[parent_rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + + # Mark the request as uncatchable + parent_rq_obj.set_uncatchable_pt(True) + LOG.info(f"Request {parent_rid} marked as uncatchable_pt") + + # Cancel subsequent sub-requests based on modal state + if parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + # For FM: cancel PT sub-request + pt_rid_struct = f"{parent_rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" + try: + self.pt_operator.user_cancels_request(pt_rid_struct, sim_time, amod_op_id) + LOG.info(f"Cancelled PT sub-request {pt_rid_struct} due to uncatchable PT") + except (KeyError, AttributeError) as e: + LOG.debug(f"Could not cancel PT sub-request {pt_rid_struct}: {e}") + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + # For FLM: cancel PT and last-mile AMoD sub-requests + pt_rid_struct = f"{parent_rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" + lm_amod_rid_struct = f"{parent_rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_1.value}" + + # Cancel PT sub-request + try: + self.pt_operator.user_cancels_request(pt_rid_struct, sim_time, amod_op_id) + LOG.info(f"Cancelled PT sub-request {pt_rid_struct} due to uncatchable PT") + except (KeyError, AttributeError) as e: + LOG.debug(f"Could not cancel PT sub-request {pt_rid_struct}: {e}") + + # Cancel last-mile AMoD sub-request + for op in self.amod_operators: + try: + op.user_cancels_request(lm_amod_rid_struct, sim_time) + LOG.info(f"Cancelled LM AMoD sub-request {lm_amod_rid_struct} due to uncatchable PT") + except KeyError: + LOG.debug(f"LM AMoD sub-request {lm_amod_rid_struct} not found for operator, may not exist") \ No newline at end of file diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 445c80df..5f3139e0 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -772,6 +772,7 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.transfer_station_ids: tp.Optional[tp.List[str]] = self._load_transfer_station_ids(rq_row) self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit self.lastmile_max_wait_time: tp.Optional[int] = rq_row.get(G_IM_LM_WAIT_TIME, None) # the customizable max waiting time for lastmile amod service + self.uncatchable_pt: bool = False # flag for requests that missed their PT connection after FM leg def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: raw_transfer_station_ids = rq_row.get(G_RQ_TRANSFER_STATION_IDS, None) @@ -789,6 +790,14 @@ def get_max_transfers(self) -> int: def get_lastmile_max_wait_time(self) -> tp.Optional[int]: return self.lastmile_max_wait_time + def set_uncatchable_pt(self, value: bool): + """Set the uncatchable_pt flag indicating the passenger missed their PT connection.""" + self.uncatchable_pt = value + + def is_uncatchable_pt(self) -> bool: + """Return whether this request missed its PT connection after FM leg.""" + return self.uncatchable_pt + def record_data(self): record_dict = {} # input @@ -837,6 +846,7 @@ def record_data(self): record_dict[G_RQ_DO] = self.do_time record_dict[G_RQ_FARE] = self.fare record_dict[G_RQ_MODAL_STATE_VALUE] = self.modal_state_int + record_dict[G_RQ_UNCATCHABLE_PT] = self.uncatchable_pt return self._add_record(record_dict) def choose_offer(self, scenario_parameters, simulation_time): diff --git a/src/evaluation/intermodal.py b/src/evaluation/intermodal.py index fc41f511..58a74931 100644 --- a/src/evaluation/intermodal.py +++ b/src/evaluation/intermodal.py @@ -87,6 +87,12 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ total_wait_time = 0 total_travel_time = 0 + # AMoD-only metrics (excluding PT segments for comparability with standard evaluation) + amod_fare = 0 + amod_wait_time = 0 # Only AMoD wait time (initial wait + LM wait if applicable) + amod_travel_time = 0 # Only AMoD in-vehicle time + amod_direct_distance = 0 # Direct distance for AMoD segments + # Store leg-specific information leg_info = {} @@ -97,6 +103,11 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ total_fare = parent_row.get(G_RQ_FARE, 0) total_wait_time = parent_row.get(G_RQ_PU, 0) - parent_row.get(G_RQ_TIME, 0) total_travel_time = parent_row.get(G_RQ_DO, 0) - parent_row.get(G_RQ_PU, 0) + # AMoD-only metrics (same as total for MONOMODAL) + amod_fare = total_fare + amod_wait_time = total_wait_time + amod_travel_time = total_travel_time + amod_direct_distance = parent_row.get(G_RQ_DRD, 0) elif modal_state == RQ_MODAL_STATE.FIRSTMILE.value: # FM: Need FM_AMOD (1) and FM_PT (2) @@ -127,11 +138,19 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ # Total travel time from AMoD pickup to PT drop-off total_travel_time = fm_pt_row.get(G_RQ_DO, 0) - fm_amod_row.get(G_RQ_PU, 0) + # AMoD-only metrics (FM has one AMoD leg) + amod_fare = fm_amod_row.get(G_RQ_FARE, 0) + amod_wait_time = fm_amod_wait # Only initial AMoD wait + amod_travel_time = fm_amod_row.get(G_RQ_DO, 0) - fm_amod_row.get(G_RQ_PU, 0) + amod_direct_distance = fm_amod_row.get(G_RQ_DRD, 0) + # Store leg info leg_info['fm_amod_pu'] = fm_amod_row.get(G_RQ_PU) leg_info['fm_amod_do'] = fm_amod_row.get(G_RQ_DO) leg_info['fm_amod_wait'] = fm_amod_wait leg_info['fm_amod_fare'] = fm_amod_row.get(G_RQ_FARE, 0) + leg_info['fm_amod_travel_time'] = amod_travel_time + leg_info['fm_amod_direct_distance'] = amod_direct_distance leg_info['fm_pt_pu'] = fm_pt_row.get(G_RQ_PU) leg_info['fm_pt_do'] = fm_pt_row.get(G_RQ_DO) leg_info['fm_pt_wait'] = fm_pt_wait @@ -165,6 +184,13 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ # Total travel time from PT pickup to AMoD drop-off total_travel_time = lm_amod_row.get(G_RQ_DO, 0) - lm_pt_row.get(G_RQ_PU, 0) + # AMoD-only metrics (LM has one AMoD leg) + amod_fare = lm_amod_row.get(G_RQ_FARE, 0) + amod_wait_time = lm_amod_wait # AMoD wait after PT + lm_amod_travel_time = lm_amod_row.get(G_RQ_DO, 0) - lm_amod_row.get(G_RQ_PU, 0) + amod_travel_time = lm_amod_travel_time + amod_direct_distance = lm_amod_row.get(G_RQ_DRD, 0) + # Store leg info leg_info['lm_pt_pu'] = lm_pt_row.get(G_RQ_PU) leg_info['lm_pt_do'] = lm_pt_row.get(G_RQ_DO) @@ -174,6 +200,8 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ leg_info['lm_amod_do'] = lm_amod_row.get(G_RQ_DO) leg_info['lm_amod_wait'] = lm_amod_wait leg_info['lm_amod_fare'] = lm_amod_row.get(G_RQ_FARE, 0) + leg_info['lm_amod_travel_time'] = lm_amod_travel_time + leg_info['lm_amod_direct_distance'] = amod_direct_distance elif modal_state == RQ_MODAL_STATE.FIRSTLASTMILE.value: # FLM: Need FLM_AMOD_0 (5), FLM_PT (6), FLM_AMOD_1 (7) @@ -208,11 +236,21 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ # Total travel time from first AMoD pickup to last AMoD drop-off total_travel_time = flm_amod_1_row.get(G_RQ_DO, 0) - flm_amod_0_row.get(G_RQ_PU, 0) + # AMoD-only metrics (FLM has two AMoD legs) + amod_fare = flm_amod_0_row.get(G_RQ_FARE, 0) + flm_amod_1_row.get(G_RQ_FARE, 0) + amod_wait_time = flm_amod_0_wait + flm_amod_1_wait # Both AMoD wait times + flm_amod_0_travel_time = flm_amod_0_row.get(G_RQ_DO, 0) - flm_amod_0_row.get(G_RQ_PU, 0) + flm_amod_1_travel_time = flm_amod_1_row.get(G_RQ_DO, 0) - flm_amod_1_row.get(G_RQ_PU, 0) + amod_travel_time = flm_amod_0_travel_time + flm_amod_1_travel_time + amod_direct_distance = flm_amod_0_row.get(G_RQ_DRD, 0) + flm_amod_1_row.get(G_RQ_DRD, 0) + # Store leg info leg_info['flm_amod_0_pu'] = flm_amod_0_row.get(G_RQ_PU) leg_info['flm_amod_0_do'] = flm_amod_0_row.get(G_RQ_DO) leg_info['flm_amod_0_wait'] = flm_amod_0_wait leg_info['flm_amod_0_fare'] = flm_amod_0_row.get(G_RQ_FARE, 0) + leg_info['flm_amod_0_travel_time'] = flm_amod_0_travel_time + leg_info['flm_amod_0_direct_distance'] = flm_amod_0_row.get(G_RQ_DRD, 0) leg_info['flm_pt_pu'] = flm_pt_row.get(G_RQ_PU) leg_info['flm_pt_do'] = flm_pt_row.get(G_RQ_DO) leg_info['flm_pt_wait'] = flm_pt_wait @@ -221,6 +259,8 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ leg_info['flm_amod_1_do'] = flm_amod_1_row.get(G_RQ_DO) leg_info['flm_amod_1_wait'] = flm_amod_1_wait leg_info['flm_amod_1_fare'] = flm_amod_1_row.get(G_RQ_FARE, 0) + leg_info['flm_amod_1_travel_time'] = flm_amod_1_travel_time + leg_info['flm_amod_1_direct_distance'] = flm_amod_1_row.get(G_RQ_DRD, 0) # Update parent aggregation with computed values parent_agg['is_served'] = is_served @@ -228,6 +268,12 @@ def create_parent_user_stats(output_dir, evaluation_start_time=None, evaluation_ parent_agg['total_wait_time'] = total_wait_time if is_served else np.nan parent_agg['total_travel_time'] = total_travel_time if is_served else np.nan + # AMoD-only metrics (excluding PT segments for comparability with standard evaluation) + parent_agg['amod_fare'] = amod_fare if is_served else np.nan + parent_agg['amod_wait_time'] = amod_wait_time if is_served else np.nan + parent_agg['amod_travel_time'] = amod_travel_time if is_served else np.nan + parent_agg['amod_direct_distance'] = amod_direct_distance if is_served else np.nan + # Add leg info as columns for key, val in leg_info.items(): parent_agg[key] = val @@ -345,6 +391,46 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end service_rates[f'{category}_service_rate'] = cat_served / cat_total * 100 if cat_total > 0 else np.nan service_rates[f'{category}_count'] = cat_served + # Calculate uncatchable PT statistics (requests that missed their PT connection after FM leg) + uncatchable_stats = {} + if G_RQ_UNCATCHABLE_PT in parent_user_stats.columns: + # Count uncatchable requests by category (only FM and FLM can be uncatchable) + fm_uncatchable = parent_user_stats[ + (parent_user_stats[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) == 'FM') & + (parent_user_stats[G_RQ_UNCATCHABLE_PT] == True) + ] + flm_uncatchable = parent_user_stats[ + (parent_user_stats[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) == 'FLM') & + (parent_user_stats[G_RQ_UNCATCHABLE_PT] == True) + ] + total_uncatchable = len(fm_uncatchable) + len(flm_uncatchable) + + uncatchable_stats['FM_uncatchable_count'] = len(fm_uncatchable) + uncatchable_stats['FLM_uncatchable_count'] = len(flm_uncatchable) + uncatchable_stats['total_uncatchable_count'] = total_uncatchable + + # Calculate uncatchable rate (as % of FM+FLM requests) + fm_total = len(parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) == 'FM']) + flm_total = len(parent_user_stats[parent_user_stats[G_RQ_MODAL_STATE_VALUE].apply(categorize_modal_state) == 'FLM']) + intermodal_with_fm_total = fm_total + flm_total + + uncatchable_stats['FM_uncatchable_rate'] = len(fm_uncatchable) / fm_total * 100 if fm_total > 0 else np.nan + uncatchable_stats['FLM_uncatchable_rate'] = len(flm_uncatchable) / flm_total * 100 if flm_total > 0 else np.nan + uncatchable_stats['total_uncatchable_rate'] = total_uncatchable / intermodal_with_fm_total * 100 if intermodal_with_fm_total > 0 else np.nan + + if print_comments and total_uncatchable > 0: + print(f" Uncatchable PT requests: {total_uncatchable} (FM: {len(fm_uncatchable)}, FLM: {len(flm_uncatchable)})") + else: + # No uncatchable_pt column, set defaults + uncatchable_stats = { + 'FM_uncatchable_count': 0, + 'FLM_uncatchable_count': 0, + 'total_uncatchable_count': 0, + 'FM_uncatchable_rate': np.nan, + 'FLM_uncatchable_rate': np.nan, + 'total_uncatchable_rate': np.nan + } + # Calculate PT wait times for FM and FLM fm_requests = served_requests[served_requests['modal_category'] == 'FM'] flm_requests = served_requests[served_requests['modal_category'] == 'FLM'] @@ -377,9 +463,48 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end # Overall metrics avg_wait_time = served_requests['total_wait_time'].mean() med_wait_time = served_requests['total_wait_time'].median() + quantile_90_wait_time = served_requests['total_wait_time'].quantile(q=0.9) avg_travel_time = served_requests['total_travel_time'].mean() total_revenue = served_requests['total_fare'].sum() + # AMoD-only metrics (excluding PT segments for comparability with standard evaluation) + amod_avg_wait_time = served_requests['amod_wait_time'].mean() + amod_med_wait_time = served_requests['amod_wait_time'].median() + amod_quantile_90_wait_time = served_requests['amod_wait_time'].quantile(q=0.9) + amod_avg_travel_time = served_requests['amod_travel_time'].mean() + amod_total_revenue = served_requests['amod_fare'].sum() + amod_total_direct_distance = served_requests['amod_direct_distance'].sum() / 1000.0 # Convert to km + + # Detour time calculation (AMoD segments only, excluding PT) + # Detour = actual_travel_time - direct_route_time - boarding_time + # Get boarding time from operator attributes (will be set later when processing operators) + boarding_time = scenario_parameters.get("op_const_boarding_time", 30) # Default 30s + + # Calculate detour for each request based on AMoD segments + # For requests with direct_route_time available + if G_RQ_DRT in served_requests.columns: + # MONOMODAL: use parent's direct route time + monomodal_mask = served_requests['modal_category'] == 'DRT_only' + served_requests.loc[monomodal_mask, 'amod_direct_route_time'] = served_requests.loc[monomodal_mask, G_RQ_DRT] + + # Calculate detour time for AMoD segments + served_requests['amod_detour_time'] = served_requests['amod_travel_time'] - served_requests.get('amod_direct_route_time', served_requests['amod_travel_time']) - boarding_time + # For intermodal, estimate direct route time from direct distance (assuming avg speed ~30 km/h = 8.33 m/s) + avg_speed_ms = 8.33 # m/s, approximately 30 km/h + served_requests.loc[served_requests['amod_detour_time'].isna(), 'amod_detour_time'] = ( + served_requests.loc[served_requests['amod_detour_time'].isna(), 'amod_travel_time'] - + served_requests.loc[served_requests['amod_detour_time'].isna(), 'amod_direct_distance'] / avg_speed_ms - boarding_time + ) + + amod_avg_detour_time = served_requests['amod_detour_time'].mean() + + # Relative detour (percentage) + served_requests['amod_rel_detour'] = ( + (served_requests['amod_travel_time'] - boarding_time - served_requests['amod_direct_distance'] / avg_speed_ms) / + (served_requests['amod_direct_distance'] / avg_speed_ms) + ) * 100.0 + amod_avg_rel_detour = served_requests['amod_rel_detour'].mean() + # Standard metrics (matching standard_eval.csv format) result_dict = { 'operator_id': -3, # Intermodal operator @@ -403,9 +528,18 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end 'FLM_service_rate [%]': service_rates.get('FLM_service_rate', np.nan), 'PT_only_service_rate [%]': service_rates.get('PT_only_service_rate', np.nan), - # Wait times + # Uncatchable PT statistics (requests that missed their PT connection after FM leg) + 'FM_uncatchable_count': uncatchable_stats.get('FM_uncatchable_count', 0), + 'FLM_uncatchable_count': uncatchable_stats.get('FLM_uncatchable_count', 0), + 'total_uncatchable_count': uncatchable_stats.get('total_uncatchable_count', 0), + 'FM_uncatchable_rate [%]': uncatchable_stats.get('FM_uncatchable_rate', np.nan), + 'FLM_uncatchable_rate [%]': uncatchable_stats.get('FLM_uncatchable_rate', np.nan), + 'total_uncatchable_rate [%]': uncatchable_stats.get('total_uncatchable_rate', np.nan), + + # Wait times (total, including PT wait) 'waiting time': avg_wait_time, 'waiting time (median)': med_wait_time, + 'waiting time (90% quantile)': quantile_90_wait_time, 'PT_Wait_Time_FM [s]': pt_wait_time_fm, 'PT_Wait_Time_FLM [s]': pt_wait_time_flm, 'PT_Wait_Time_Combined [s]': pt_wait_time_combined, @@ -413,6 +547,16 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end 'LM_Wait_Time_FLM [s]': lm_wait_time_flm, 'LM_Wait_Time_Combined [s]': lm_wait_time_combined, + # AMoD-only metrics (excluding PT, for comparability with standard evaluation) + 'amod_waiting_time': amod_avg_wait_time, + 'amod_waiting_time (median)': amod_med_wait_time, + 'amod_waiting_time (90% quantile)': amod_quantile_90_wait_time, + 'amod_travel_time': amod_avg_travel_time, + 'amod_detour_time': amod_avg_detour_time, + 'amod_rel_detour [%]': amod_avg_rel_detour, + 'amod_revenue': amod_total_revenue, + 'amod_customer_direct_distance [km]': amod_total_direct_distance, + # Travel metrics 'travel time': avg_travel_time, 'mod revenue': total_revenue, @@ -463,10 +607,22 @@ def weight_ob_pax(entries): empty_df = op_vehicle_df[op_vehicle_df[G_VR_OB_RID].isnull()] empty_vkm = empty_df[G_VR_LEG_DISTANCE].sum() / 1000.0 / total_km * 100.0 if total_km > 0 else 0 + # Repositioning VKM (new) + repositioning_df = empty_df[empty_df[G_VR_STATUS] == "reposition"] + repositioning_vkm = repositioning_df[G_VR_LEG_DISTANCE].sum() / 1000.0 / total_km * 100.0 if total_km > 0 else 0 + # Revenue metrics rev_df = op_vehicle_df[op_vehicle_df["status"].isin([x.display_name for x in G_REVENUE_STATUS])] vehicle_revenue_hours = (rev_df["VRL_end_sim_end_time"].sum() - rev_df["VRL_start_sim_end_time"].sum()) / 3600.0 + # Rides per vehicle revenue hours (new) + rides_per_veh_rev_hours = total_served_pax / vehicle_revenue_hours if vehicle_revenue_hours > 0 else 0 + rides_per_veh_rev_hours_rq = total_served / vehicle_revenue_hours if vehicle_revenue_hours > 0 else 0 + + # Shared rides and customer in-vehicle distance (new) + op_shared_rides = shared_rides(op_vehicle_df) + op_customer_in_vehicle_distance = avg_in_vehicle_distance(op_vehicle_df) + # By-vehicle stats op_veh_types = veh_type_stats[veh_type_stats[G_V_OP_ID] == op_id] op_veh_types.set_index(G_V_VID, inplace=True) @@ -502,15 +658,24 @@ def weight_ob_pax(entries): fix_costs = all_vid_df["fix costs"].sum() if len(all_vid_df) > 0 else 0 var_costs = all_vid_df["total variable costs"].sum() if len(all_vid_df) > 0 else 0 + # External emission costs (new) + external_emission_costs = np.rint(EMISSION_CPG * total_co2) + # Add to result dict with operator prefix result_dict[f'op{op_id}_fleet_utilization [%]'] = fleet_utilization result_dict[f'op{op_id}_total_vkm'] = total_km result_dict[f'op{op_id}_occupancy'] = distance_avg_occupancy result_dict[f'op{op_id}_empty_vkm [%]'] = empty_vkm + result_dict[f'op{op_id}_repositioning_vkm [%]'] = repositioning_vkm result_dict[f'op{op_id}_vehicle_revenue_hours'] = vehicle_revenue_hours + result_dict[f'op{op_id}_rides_per_veh_rev_hours'] = rides_per_veh_rev_hours + result_dict[f'op{op_id}_rides_per_veh_rev_hours_rq'] = rides_per_veh_rev_hours_rq result_dict[f'op{op_id}_total_CO2_emissions [t]'] = total_co2 / 10**6 + result_dict[f'op{op_id}_external_emission_costs'] = external_emission_costs result_dict[f'op{op_id}_fix_costs'] = fix_costs result_dict[f'op{op_id}_var_costs'] = var_costs + result_dict[f'op{op_id}_shared_rides [%]'] = op_shared_rides + result_dict[f'op{op_id}_customer_in_vehicle_distance'] = op_customer_in_vehicle_distance except FileNotFoundError: if print_comments: diff --git a/src/misc/globals.py b/src/misc/globals.py index d474e389..4db5d6f2 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -486,6 +486,7 @@ G_RQ_TRANSFER_STATION_IDS = "transfer_station_ids" G_RQ_MAX_TRANSFERS = "max_transfers" G_RQ_SUB_TRIP_ID = "sub_trip_id" +G_RQ_UNCATCHABLE_PT = "uncatchable_pt" # flag for requests that missed their PT connection after FM leg class RQ_MODAL_STATE(Enum): """ This enum is used to identify different modal states of a traveler request. diff --git a/src/ptctrl/PTControlBasic.py b/src/ptctrl/PTControlBasic.py index 1c4f5488..c938a9e5 100644 --- a/src/ptctrl/PTControlBasic.py +++ b/src/ptctrl/PTControlBasic.py @@ -168,6 +168,26 @@ def user_confirms_booking( do_pos = None, t_egress = pt_offer.get(G_PT_OFFER_TARGET_WALKING_TIME, None), ) + + def user_cancels_request( + self, + rid_struct: str, + sim_time: int, + firstmile_amod_operator_id: int = None + ): + """This method is used to cancel a pt request. This removes the offer from the database. + + Args: + rid_struct (str): The sub-request id struct of the journey. + sim_time (int): The simulation time when the cancellation occurs. + firstmile_amod_operator_id (int, optional): The operator id of the firstmile amod operator. Defaults to None. + """ + offer_key = (rid_struct, firstmile_amod_operator_id) + if offer_key in self.pt_offer_db: + del self.pt_offer_db[offer_key] + LOG.debug(f"PT request {rid_struct} cancelled at time {sim_time}") + else: + LOG.debug(f"PT request {rid_struct} not found in offer database, may have been cancelled already") def _update_gtfs_data(self): """This method will update the gtfs data of the pt router to reflect any changes in the pt network or schedule. diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv index 7a44e9d1..6132df08 100644 --- a/studies/example_study/scenarios/example_im.csv +++ b/studies/example_study/scenarios/example_im.csv @@ -1,4 +1,6 @@ scenario_name,op_module,rq_file,op_fleet_composition,broker_type,broker_maas_detour_time_factor,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,evaluation_method,sim_env,user_max_decision_time example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbrokerEI_mdtf30,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,30,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file +example_im_ptbrokerEI_mdtf30,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,30,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbrokerEI_mdtf10,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,10,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbrokerEI_mdtf0,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,0,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From eacf0149c76b5e940210f4081a8164471ba2ec19 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 5 Feb 2026 14:41:29 +0100 Subject: [PATCH 26/31] Add PAYG --- src/FleetSimulationBase.py | 3 +- src/broker/PTBrokerPAYG.py | 518 ++++++++++++++++++ src/demand/TravelerModels.py | 24 + src/evaluation/intermodal.py | 100 ++++ src/misc/globals.py | 16 + src/misc/init_modules.py | 1 + .../example_study/scenarios/example_im.csv | 3 +- 7 files changed, 663 insertions(+), 2 deletions(-) create mode 100644 src/broker/PTBrokerPAYG.py diff --git a/src/FleetSimulationBase.py b/src/FleetSimulationBase.py index ee8e0490..d4f5b62b 100644 --- a/src/FleetSimulationBase.py +++ b/src/FleetSimulationBase.py @@ -461,12 +461,13 @@ def _load_broker_module(self): """ Loads the broker """ broker_type: str = self.scenario_parameters.get(G_BROKER_TYPE, None) + implemented_brokers = ["PTBroker", "PTBrokerEI", "PTBrokerPAYG"] if broker_type is None: prt_msg: str = "No broker type specified, using default BrokerBasic" LOG.info(prt_msg) BrokerClass = load_broker_module("BrokerBasic") self.broker = BrokerClass(self.n_op, self.operators) - elif broker_type == "PTBroker" or broker_type == "PTBrokerEI": + elif broker_type in implemented_brokers: prt_msg: str = f"Broker specified, using {broker_type}" LOG.info(prt_msg) if self.pt_operator is None: diff --git a/src/broker/PTBrokerPAYG.py b/src/broker/PTBrokerPAYG.py new file mode 100644 index 00000000..1ef2ed45 --- /dev/null +++ b/src/broker/PTBrokerPAYG.py @@ -0,0 +1,518 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# PTBrokerPAYG: Plan-As-You-Go Broker Strategy +# +# This broker simulates traveler behavior without a MaaS platform - travelers plan their trip step by step: +# - For FM/FLM: After FM AMoD alighting, query PT in real-time +# - For LM/FLM: After PT alighting, request LM AMoD in real-time +# - If any step fails (no offer available), mark the trip as interrupted +# -------------------------------------------------------------------------------------------------------------------- # + +# standard distribution imports +import logging +import typing as tp + +# src imports +from src.broker.PTBrokerBasic import PTBrokerBasic +from src.simulation.Offers import TravellerOffer + +if tp.TYPE_CHECKING: + from src.fleetctrl.FleetControlBase import FleetControlBase + from src.ptctrl.PTControlBase import PTControlBase + from src.demand.demand import Demand + from src.routing.road.NetworkBase import NetworkBase + from src.demand.TravelerModels import RequestBase, BasicIntermodalRequest + from src.simulation.Offers import PTOffer + +# -------------------------------------------------------------------------------------------------------------------- # +# global variables +from src.misc.globals import * + +LOG = logging.getLogger(__name__) + + +INPUT_PARAMETERS_PTBrokerPAYG = { + "doc": "Plan-As-You-Go broker: simulates travelers planning trips step by step without MaaS platform integration", + "inherit": PTBrokerBasic, + "input_parameters_mandatory": ["n_amod_op", "amod_operators", "pt_operator", "demand", "routing_engine", "scenario_parameters"], + "input_parameters_optional": [], + "mandatory_modules": [], + "optional_modules": [] +} + + +class PTBrokerPAYG(PTBrokerBasic): + """ + Plan-As-You-Go (PAYG) broker strategy. + + Unlike typical PTBroker which plans the entire intermodal trip upfront, PAYG simulates + travelers who plan only the next step of their journey: + + - FM/FLM requests: Only create FM_AMOD at request time; PT is queried after AMoD alighting + - LM requests: Query PT at request time; LM_AMOD is requested after PT alighting + - FLM requests: FM_AMOD -> (alighting) -> PT query -> (PT arrival) -> LM_AMOD request + + If any step fails to find an available service, the trip is marked as interrupted. + """ + + def __init__( + self, + n_amod_op: int, + amod_operators: tp.List['FleetControlBase'], + pt_operator: 'PTControlBase', + demand: 'Demand', + routing_engine: 'NetworkBase', + scenario_parameters: dict, + ): + super().__init__(n_amod_op, amod_operators, pt_operator, demand, routing_engine, scenario_parameters) + + # PAYG-specific state tracking + self.payg_trip_states: tp.Dict[int, PAYG_TRIP_STATE] = {} # rid -> state + + # Pending PT arrivals: rid -> (pt_arrival_time, pt_alighting_node) + # Used to trigger LM_AMOD requests when PT arrives + self.pending_pt_arrivals: tp.Dict[int, tp.Tuple[int, int]] = {} + + # ============================================================================================================== # + # Request Processing Methods + # ============================================================================================================== # + + def _process_inform_firstmile_request( + self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, + parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE + ): + """Process FM request: Only create FM_AMOD sub-request. + PT will be queried after FM_AMOD alighting. + """ + # Get transfer station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # Create FM_AMOD sub-request for each operator + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request( + rq_obj, RQ_SUB_TRIP_ID.FM_AMOD.value, + rq_obj.get_origin_node(), transfer_street_node, + rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time + ) + + # Initialize PAYG state + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PENDING + LOG.debug(f"PAYG FM request {rid}: Created FM_AMOD sub-request, PT will be queried after alighting") + + def _process_inform_lastmile_request( + self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, + parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.LASTMILE + ): + """Process LM request: Query PT first. LM_AMOD will be scheduled after user confirms booking. + """ + # Get transfer station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # Query PT immediately + lm_pt_arrival: tp.Optional[int] = self._inform_pt_sub_request( + rq_obj, RQ_SUB_TRIP_ID.LM_PT.value, + rq_obj.get_origin_node(), transfer_street_node, + rq_obj.earliest_start_time, parent_modal_state + ) + + if lm_pt_arrival is not None: + # PT offer available - state will be updated when user confirms booking + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PENDING + LOG.debug(f"PAYG LM request {rid}: PT offer available, waiting for user booking confirmation") + else: + # No PT available - mark as interrupted + self._mark_trip_interrupted(rid, PAYG_TRIP_STATE.INTERRUPTED_NO_PT, sim_time) + LOG.info(f"PAYG LM request {rid}: No PT available, trip interrupted") + + def _process_inform_firstlastmile_request( + self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, + parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTLASTMILE + ): + """Process FLM request: Only create FLM_AMOD_0 sub-request. + PT and LM_AMOD will be created after respective alighting events. + """ + # Get first transfer station + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + transfer_street_node_0, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + + # Create FLM_AMOD_0 sub-request for each operator + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request( + rq_obj, RQ_SUB_TRIP_ID.FLM_AMOD_0.value, + rq_obj.get_origin_node(), transfer_street_node_0, + rq_obj.earliest_start_time, parent_modal_state, op_id, sim_time + ) + + # Initialize PAYG state + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PENDING + LOG.debug(f"PAYG FLM request {rid}: Created FLM_AMOD_0 sub-request, PT will be queried after alighting") + + # ============================================================================================================== # + # Offer Collection Methods + # ============================================================================================================== # + + def collect_offers(self, rid: int, sim_time: int) -> tp.Dict[int, 'TravellerOffer']: + """Collect offers, processing any pending PT arrivals first.""" + # Process pending PT arrivals before collecting offers + self._process_pending_pt_arrivals(sim_time) + + # Call parent implementation + return super().collect_offers(rid, sim_time) + + def _process_collect_firstmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'] + ) -> tp.Dict[int, 'TravellerOffer']: + """Collect FM offers: Only return FM_AMOD offers (PT is not yet queried in PAYG mode).""" + fm_amod_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + + for amod_op_id in range(self.n_amod_op): + fm_amod_offer: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(fm_amod_rid_struct) + LOG.debug(f"PAYG collecting FM_AMOD offer for {fm_amod_rid_struct} from operator {amod_op_id}: {fm_amod_offer}") + + if fm_amod_offer is not None and not fm_amod_offer.service_declined(): + # Register offer + self.demand[fm_amod_rid_struct].receive_offer(amod_op_id, fm_amod_offer, None) + # Return single-leg offer (not IntermodalOffer since PT is unknown) + offers[amod_op_id] = fm_amod_offer + + return offers + + def _process_collect_lastmile_offers( + self, rid: int, parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'] + ) -> tp.Dict[int, 'TravellerOffer']: + """Collect LM offers: Return PT offer only (LM_AMOD not yet requested in PAYG mode).""" + lm_pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" + lm_pt_offer: 'TravellerOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) + LOG.debug(f"PAYG collecting LM_PT offer for {lm_pt_rid_struct}: {lm_pt_offer}") + + if lm_pt_offer is not None and not lm_pt_offer.service_declined(): + self.demand[lm_pt_rid_struct].receive_offer(self.pt_operator_id, lm_pt_offer, None) + # Return PT offer only + offers[self.pt_operator_id] = lm_pt_offer + + return offers + + def _process_collect_firstlastmile_offers( + self, rid: int, parent_rq_obj: 'BasicIntermodalRequest', parent_modal_state: RQ_MODAL_STATE, + offers: tp.Dict[int, 'TravellerOffer'], sim_time: int + ) -> tp.Dict[int, 'TravellerOffer']: + """Collect FLM offers: Only return FLM_AMOD_0 offers (PT and LM not yet queried in PAYG mode).""" + flm_amod_rid_struct_0: str = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + + for amod_op_id in range(self.n_amod_op): + flm_amod_offer_0: 'TravellerOffer' = self.amod_operators[amod_op_id].get_current_offer(flm_amod_rid_struct_0) + LOG.debug(f"PAYG collecting FLM_AMOD_0 offer for {flm_amod_rid_struct_0} from operator {amod_op_id}: {flm_amod_offer_0}") + + if flm_amod_offer_0 is not None and not flm_amod_offer_0.service_declined(): + self.demand[flm_amod_rid_struct_0].receive_offer(amod_op_id, flm_amod_offer_0, None) + # Return single-leg offer + offers[amod_op_id] = flm_amod_offer_0 + + return offers + + # ============================================================================================================== # + # Booking Methods + # ============================================================================================================== # + + def inform_user_booking(self, rid: int, rq_obj: 'RequestBase', sim_time: int, chosen_operator: tp.Union[int, tuple]) -> tp.List[tuple[int, 'RequestBase']]: + """Handle user booking for PAYG mode.""" + amod_confirmed_rids = [] + parent_modal_state: RQ_MODAL_STATE = rq_obj.get_modal_state() + + # Check if this is a pure PT offer selection (not LM PT offer in PAYG mode) + # For LM requests in PAYG, chosen_operator == pt_operator_id means LM_PT offer, not pure PT + if chosen_operator == self.pt_operator_id and parent_modal_state != RQ_MODAL_STATE.LASTMILE: + amod_confirmed_rids.append((rid, rq_obj)) + # inform all AMoD operators that the request is cancelled + self.inform_user_leaving_system(rid, sim_time) + pt_rid_struct: str = f"{rid}_{RQ_SUB_TRIP_ID.PT.value}" + pt_sub_rq_obj = self.demand[pt_rid_struct] + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, None) + return amod_confirmed_rids + + # PAYG mode: Handle single-leg bookings for FM/FLM + if parent_modal_state == RQ_MODAL_STATE.MONOMODAL or parent_modal_state == RQ_MODAL_STATE.PT: + # Standard monomodal handling + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: + operator.user_cancels_request(rid, sim_time) + else: + operator.user_confirms_booking(rid, sim_time) + amod_confirmed_rids.append((rid, rq_obj)) + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTMILE: + # PAYG FM: Book only FM_AMOD, PT will be queried later + fm_amod_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.FM_AMOD.value}" + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: + operator.user_cancels_request(fm_amod_rid_struct, sim_time) + else: + operator.user_confirms_booking(fm_amod_rid_struct, sim_time) + self.payg_trip_states[rid] = PAYG_TRIP_STATE.FM_AMOD_BOOKED + amod_confirmed_rids.append((rid, rq_obj)) + LOG.debug(f"PAYG FM booking {rid}: FM_AMOD booked with operator {chosen_operator}") + + elif parent_modal_state == RQ_MODAL_STATE.LASTMILE: + # PAYG LM: Book PT, schedule LM_AMOD request for after PT arrival + lm_pt_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.LM_PT.value}" + lm_pt_sub_rq_obj = self.demand[lm_pt_rid_struct] + self.pt_operator.user_confirms_booking(lm_pt_sub_rq_obj, None) + + # Get PT offer to retrieve arrival time and transfer node + lm_pt_offer: 'PTOffer' = self.pt_operator.get_current_offer(lm_pt_rid_struct) + if lm_pt_offer is not None and not lm_pt_offer.service_declined(): + pt_arrival_time = lm_pt_offer.destination_node_arrival_time + # Get transfer street node from request + transfer_station_ids = rq_obj.get_transfer_station_ids() + transfer_street_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + # Schedule LM_AMOD request for PT arrival + self.pending_pt_arrivals[rid] = (pt_arrival_time, transfer_street_node) + LOG.debug(f"PAYG LM booking {rid}: PT booked, LM_AMOD scheduled at {pt_arrival_time}") + + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PT_BOOKED + amod_confirmed_rids.append((rid, rq_obj)) + LOG.debug(f"PAYG LM booking {rid}: PT booked") + + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + # PAYG FLM: Book only FLM_AMOD_0, PT and LM will be handled later + flm_amod_rid_struct_0 = f"{rid}_{RQ_SUB_TRIP_ID.FLM_AMOD_0.value}" + for i, operator in enumerate(self.amod_operators): + if i != chosen_operator: + operator.user_cancels_request(flm_amod_rid_struct_0, sim_time) + else: + operator.user_confirms_booking(flm_amod_rid_struct_0, sim_time) + self.payg_trip_states[rid] = PAYG_TRIP_STATE.FM_AMOD_BOOKED + amod_confirmed_rids.append((rid, rq_obj)) + LOG.debug(f"PAYG FLM booking {rid}: FLM_AMOD_0 booked with operator {chosen_operator}") + + else: + raise ValueError(f"Invalid modal state: {parent_modal_state}") + + return amod_confirmed_rids + + # ============================================================================================================== # + # Alighting Event Handlers + # ============================================================================================================== # + + def acknowledge_user_alighting(self, op_id: int, rid_struct: str, vid: int, alighting_time: int): + """Handle AMoD alighting events - trigger next step in PAYG flow.""" + # Call parent implementation first + super().acknowledge_user_alighting(op_id, rid_struct, vid, alighting_time) + + # Parse rid_struct + rid_struct_str = str(rid_struct) + if "_" not in rid_struct_str: + return # Not a sub-request + + parts = rid_struct_str.rsplit("_", 1) + parent_rid = int(parts[0]) + sub_trip_id = int(parts[1]) + + parent_rq_obj: 'BasicIntermodalRequest' = self.demand[parent_rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + + # Get alighting node from parent request's transfer station info + # (sub-request is already deleted from rq_db by user_ends_alighting) + transfer_station_ids: tp.List[str] = parent_rq_obj.get_transfer_station_ids() + + # FM_AMOD alighting -> Query PT + if sub_trip_id == RQ_SUB_TRIP_ID.FM_AMOD.value: + # FM_AMOD destination is the first transfer station + alighting_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + self._handle_fm_amod_alighting(parent_rid, parent_rq_obj, op_id, alighting_time, parent_modal_state, alighting_node) + + # FLM_AMOD_0 alighting -> Query PT + elif sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_0.value: + # FLM_AMOD_0 destination is the first transfer station + alighting_node, _ = self._find_transfer_info(transfer_station_ids[0], "pt2street") + self._handle_flm_amod_0_alighting(parent_rid, parent_rq_obj, op_id, alighting_time, parent_modal_state, alighting_node) + + # LM_AMOD alighting -> Trip completed + elif sub_trip_id == RQ_SUB_TRIP_ID.LM_AMOD.value: + self._handle_trip_completed(parent_rid, alighting_time) + + # FLM_AMOD_1 alighting -> Trip completed + elif sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value: + self._handle_trip_completed(parent_rid, alighting_time) + + def _handle_fm_amod_alighting( + self, rid: int, rq_obj: 'BasicIntermodalRequest', amod_op_id: int, + alighting_time: int, parent_modal_state: RQ_MODAL_STATE, alighting_node: int + ): + """Handle FM_AMOD alighting: Query PT in real-time.""" + LOG.debug(f"PAYG FM alighting: rid={rid}, time={alighting_time}, node={alighting_node}") + + # Query PT from current location/time to destination + pt_arrival = self._inform_pt_sub_request( + rq_obj, RQ_SUB_TRIP_ID.FM_PT.value, + alighting_node, rq_obj.get_destination_node(), + alighting_time, parent_modal_state, amod_op_id + ) + + if pt_arrival is None: + # No PT available + self._mark_trip_interrupted(rid, PAYG_TRIP_STATE.INTERRUPTED_NO_PT, alighting_time) + LOG.info(f"PAYG FM {rid}: No PT available after alighting, trip interrupted") + return + + # Get PT offer and record it on sub-request + pt_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" + pt_sub_rq_obj = self.demand[pt_rid_struct] + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct, amod_op_id) + if pt_offer is not None: + pt_sub_rq_obj.receive_offer(self.pt_operator_id, pt_offer, None) + + # Auto-confirm PT booking (user is already at the station) + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, amod_op_id) + + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PT_BOOKED + LOG.info(f"PAYG FM {rid}: PT booked after alighting, arrival at {pt_arrival}") + + def _handle_flm_amod_0_alighting( + self, rid: int, rq_obj: 'BasicIntermodalRequest', amod_op_id: int, + alighting_time: int, parent_modal_state: RQ_MODAL_STATE, alighting_node: int + ): + """Handle FLM_AMOD_0 alighting: Query PT in real-time.""" + LOG.debug(f"PAYG FLM_AMOD_0 alighting: rid={rid}, time={alighting_time}, node={alighting_node}") + + # Get transfer stations + transfer_station_ids: tp.List[str] = rq_obj.get_transfer_station_ids() + + # Get second transfer station for PT destination + transfer_street_node_1, _ = self._find_transfer_info(transfer_station_ids[1], "pt2street") + + # Query PT from current location/time + pt_arrival = self._inform_pt_sub_request( + rq_obj, RQ_SUB_TRIP_ID.FLM_PT.value, + alighting_node, transfer_street_node_1, + alighting_time, parent_modal_state, amod_op_id + ) + + if pt_arrival is None: + # No PT available + self._mark_trip_interrupted(rid, PAYG_TRIP_STATE.INTERRUPTED_NO_PT, alighting_time) + LOG.info(f"PAYG FLM {rid}: No PT available after FM alighting, trip interrupted") + return + + # Get PT offer and record it on sub-request + pt_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" + pt_sub_rq_obj = self.demand[pt_rid_struct] + pt_offer = self.pt_operator.get_current_offer(pt_rid_struct, amod_op_id) + if pt_offer is not None: + pt_sub_rq_obj.receive_offer(self.pt_operator_id, pt_offer, None) + + # Auto-confirm PT booking + self.pt_operator.user_confirms_booking(pt_sub_rq_obj, amod_op_id) + + # Schedule LM_AMOD request for PT arrival + self.pending_pt_arrivals[rid] = (pt_arrival, transfer_street_node_1) + self.payg_trip_states[rid] = PAYG_TRIP_STATE.PT_BOOKED + LOG.info(f"PAYG FLM {rid}: PT booked, LM_AMOD will be requested at {pt_arrival}") + + # ============================================================================================================== # + # PT Arrival Processing + # ============================================================================================================== # + + def _process_pending_pt_arrivals(self, sim_time: int): + """Process pending PT arrivals and trigger LM_AMOD requests.""" + completed_arrivals = [] + + for rid, (pt_arrival_time, alighting_node) in self.pending_pt_arrivals.items(): + if sim_time >= pt_arrival_time: + # PT has arrived, request LM_AMOD + self._handle_pt_alighting(rid, pt_arrival_time, alighting_node) + completed_arrivals.append(rid) + + # Remove processed arrivals + for rid in completed_arrivals: + del self.pending_pt_arrivals[rid] + + def _handle_pt_alighting(self, rid: int, alighting_time: int, alighting_node: int): + """Handle PT alighting: Request LM_AMOD in real-time.""" + LOG.debug(f"PAYG PT alighting: rid={rid}, time={alighting_time}") + + parent_rq_obj: 'BasicIntermodalRequest' = self.demand[rid] + parent_modal_state: RQ_MODAL_STATE = parent_rq_obj.get_modal_state() + + # Determine sub-trip ID based on modal state + if parent_modal_state == RQ_MODAL_STATE.LASTMILE: + lm_sub_trip_id = RQ_SUB_TRIP_ID.LM_AMOD.value + elif parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: + lm_sub_trip_id = RQ_SUB_TRIP_ID.FLM_AMOD_1.value + else: + LOG.warning(f"PAYG PT alighting for unexpected modal state: {parent_modal_state}") + return + + # Create LM_AMOD sub-request + for op_id in range(self.n_amod_op): + self._inform_amod_sub_request( + parent_rq_obj, lm_sub_trip_id, + alighting_node, parent_rq_obj.get_destination_node(), + alighting_time, parent_modal_state, op_id, alighting_time + ) + + # Get offers and select best one + # TODO: Could implement user choice here instead of auto-selecting best offer + lm_amod_rid_struct = f"{rid}_{lm_sub_trip_id}" + best_offer = None + best_op_id = None + + for amod_op_id in range(self.n_amod_op): + offer = self.amod_operators[amod_op_id].get_current_offer(lm_amod_rid_struct) + if offer is not None and not offer.service_declined(): + if best_offer is None or offer.offered_waiting_time < best_offer.offered_waiting_time: + best_offer = offer + best_op_id = amod_op_id + + if best_offer is None: + # No AMoD available + self._mark_trip_interrupted(rid, PAYG_TRIP_STATE.INTERRUPTED_NO_LM_AMOD, alighting_time) + LOG.info(f"PAYG {rid}: No LM_AMOD available after PT alighting, trip interrupted") + return + + # Auto-confirm best LM_AMOD offer + for op_id in range(self.n_amod_op): + if op_id != best_op_id: + self.amod_operators[op_id].user_cancels_request(lm_amod_rid_struct, alighting_time) + else: + self.amod_operators[op_id].user_confirms_booking(lm_amod_rid_struct, alighting_time) + self.demand[lm_amod_rid_struct].receive_offer(op_id, best_offer, None) + + self.payg_trip_states[rid] = PAYG_TRIP_STATE.LM_AMOD_BOOKED + LOG.info(f"PAYG {rid}: LM_AMOD booked with operator {best_op_id}, wait time {best_offer.offered_waiting_time}s") + + # ============================================================================================================== # + # Trip State Management + # ============================================================================================================== # + + def _handle_trip_completed(self, rid: int, completion_time: int): + """Mark trip as completed.""" + self.payg_trip_states[rid] = PAYG_TRIP_STATE.COMPLETED + LOG.info(f"PAYG trip {rid} completed at {completion_time}") + + def _mark_trip_interrupted(self, rid: int, interrupt_state: PAYG_TRIP_STATE, interrupt_time: int): + """Mark trip as interrupted and record the state.""" + self.payg_trip_states[rid] = interrupt_state + + # Set interrupted flag on parent request + parent_rq_obj: 'BasicIntermodalRequest' = self.demand[rid] + if hasattr(parent_rq_obj, 'set_payg_interrupted'): + parent_rq_obj.set_payg_interrupted(True, interrupt_state.value, interrupt_time) + + LOG.warning(f"PAYG trip {rid} interrupted: {interrupt_state.name} at time {interrupt_time}") + + # ============================================================================================================== # + # User Leaving System + # ============================================================================================================== # + + def inform_user_leaving_system(self, rid: int, sim_time: int): + """Handle user leaving system - cancel any pending requests.""" + # Remove from pending PT arrivals if present + if rid in self.pending_pt_arrivals: + del self.pending_pt_arrivals[rid] + + # Call parent implementation + super().inform_user_leaving_system(rid, sim_time) diff --git a/src/demand/TravelerModels.py b/src/demand/TravelerModels.py index 5f3139e0..2a3efa77 100644 --- a/src/demand/TravelerModels.py +++ b/src/demand/TravelerModels.py @@ -773,6 +773,10 @@ def __init__(self, rq_row, routing_engine, simulation_time_step, scenario_parame self.max_transfers: int = rq_row.get(G_RQ_MAX_TRANSFERS, 999) # 999 means no limit self.lastmile_max_wait_time: tp.Optional[int] = rq_row.get(G_IM_LM_WAIT_TIME, None) # the customizable max waiting time for lastmile amod service self.uncatchable_pt: bool = False # flag for requests that missed their PT connection after FM leg + # PAYG (Plan-As-You-Go) specific attributes + self.payg_interrupted: bool = False # flag for PAYG trips that were interrupted + self.payg_interrupt_state: tp.Optional[int] = None # PAYG_TRIP_STATE value when interrupted + self.payg_interrupt_time: tp.Optional[int] = None # simulation time when interrupted def _load_transfer_station_ids(self, rq_row) -> tp.Optional[tp.List[str]]: raw_transfer_station_ids = rq_row.get(G_RQ_TRANSFER_STATION_IDS, None) @@ -798,6 +802,22 @@ def is_uncatchable_pt(self) -> bool: """Return whether this request missed its PT connection after FM leg.""" return self.uncatchable_pt + def set_payg_interrupted(self, interrupted: bool, interrupt_state: tp.Optional[int] = None, interrupt_time: tp.Optional[int] = None): + """Set the PAYG interrupted flag and related information. + + Args: + interrupted: Whether the trip was interrupted + interrupt_state: PAYG_TRIP_STATE value (e.g., -1 for NO_PT, -2 for NO_LM_AMOD) + interrupt_time: Simulation time when the interruption occurred + """ + self.payg_interrupted = interrupted + self.payg_interrupt_state = interrupt_state + self.payg_interrupt_time = interrupt_time + + def is_payg_interrupted(self) -> bool: + """Return whether this PAYG trip was interrupted.""" + return self.payg_interrupted + def record_data(self): record_dict = {} # input @@ -847,6 +867,10 @@ def record_data(self): record_dict[G_RQ_FARE] = self.fare record_dict[G_RQ_MODAL_STATE_VALUE] = self.modal_state_int record_dict[G_RQ_UNCATCHABLE_PT] = self.uncatchable_pt + # PAYG specific records + record_dict[G_RQ_PAYG_INTERRUPTED] = self.payg_interrupted + record_dict[G_RQ_PAYG_INTERRUPT_STATE] = self.payg_interrupt_state + record_dict[G_RQ_PAYG_INTERRUPT_TIME] = self.payg_interrupt_time return self._add_record(record_dict) def choose_offer(self, scenario_parameters, simulation_time): diff --git a/src/evaluation/intermodal.py b/src/evaluation/intermodal.py index 58a74931..b987d4e6 100644 --- a/src/evaluation/intermodal.py +++ b/src/evaluation/intermodal.py @@ -313,6 +313,96 @@ def categorize_modal_state(modal_state_value): return 'Unknown' +def calculate_payg_metrics(parent_user_stats, is_payg_scenario=False, print_comments=False): + """ + Calculate PAYG-specific metrics from parent user stats. + + PAYG (Plan-As-You-Go) trips may be interrupted if: + - No PT available after FM alighting (INTERRUPTED_NO_PT) + - No LM AMoD available after PT alighting (INTERRUPTED_NO_LM_AMOD) + + :param parent_user_stats: DataFrame with parent request data + :param is_payg_scenario: whether this is a PAYG scenario (determined by broker_type in config) + :param print_comments: whether to print status messages + :return: dict with PAYG-specific metrics, empty dict if not a PAYG scenario + """ + payg_stats = {} + + # Check if this is a PAYG scenario based on broker type from config + if not is_payg_scenario: + return {} # Not a PAYG scenario + + # Check if PAYG columns exist (for backwards compatibility) + if G_RQ_PAYG_INTERRUPTED not in parent_user_stats.columns: + if print_comments: + print(" Warning: PAYG scenario but no payg_interrupted column found") + return {} + + # Filter to intermodal requests only (FM, LM, FLM) - these are the ones that can be interrupted + intermodal_mask = parent_user_stats[G_RQ_MODAL_STATE_VALUE].isin([ + RQ_MODAL_STATE.FIRSTMILE.value, + RQ_MODAL_STATE.LASTMILE.value, + RQ_MODAL_STATE.FIRSTLASTMILE.value + ]) + intermodal_df = parent_user_stats[intermodal_mask].copy() + + total_intermodal = len(intermodal_df) + if total_intermodal == 0: + return {} + + # Count interrupted requests + interrupted_df = intermodal_df[intermodal_df[G_RQ_PAYG_INTERRUPTED] == True] + interrupted_count = len(interrupted_df) + completed_count = total_intermodal - interrupted_count + + # Overall rates + payg_stats['payg_total_intermodal_requests'] = total_intermodal + payg_stats['payg_completed_count'] = completed_count + payg_stats['payg_interrupted_count'] = interrupted_count + payg_stats['payg_completion_rate [%]'] = completed_count / total_intermodal * 100 + payg_stats['payg_interrupt_rate [%]'] = interrupted_count / total_intermodal * 100 + + # Breakdown by interrupt state + if G_RQ_PAYG_INTERRUPT_STATE in interrupted_df.columns: + no_pt_count = len(interrupted_df[ + interrupted_df[G_RQ_PAYG_INTERRUPT_STATE] == PAYG_TRIP_STATE.INTERRUPTED_NO_PT.value + ]) + no_amod_count = len(interrupted_df[ + interrupted_df[G_RQ_PAYG_INTERRUPT_STATE] == PAYG_TRIP_STATE.INTERRUPTED_NO_LM_AMOD.value + ]) + else: + no_pt_count = 0 + no_amod_count = 0 + + payg_stats['payg_interrupt_no_pt_count'] = no_pt_count + payg_stats['payg_interrupt_no_pt_rate [%]'] = no_pt_count / total_intermodal * 100 if total_intermodal > 0 else 0 + payg_stats['payg_interrupt_no_amod_count'] = no_amod_count + payg_stats['payg_interrupt_no_amod_rate [%]'] = no_amod_count / total_intermodal * 100 if total_intermodal > 0 else 0 + + # Breakdown by modal state + for category, modal_value in [('FM', RQ_MODAL_STATE.FIRSTMILE.value), + ('LM', RQ_MODAL_STATE.LASTMILE.value), + ('FLM', RQ_MODAL_STATE.FIRSTLASTMILE.value)]: + cat_df = intermodal_df[intermodal_df[G_RQ_MODAL_STATE_VALUE] == modal_value] + cat_total = len(cat_df) + if cat_total > 0: + cat_interrupted = len(cat_df[cat_df[G_RQ_PAYG_INTERRUPTED] == True]) + payg_stats[f'payg_{category}_total'] = cat_total + payg_stats[f'payg_{category}_interrupted_count'] = cat_interrupted + payg_stats[f'payg_{category}_interrupt_rate [%]'] = cat_interrupted / cat_total * 100 + else: + payg_stats[f'payg_{category}_total'] = 0 + payg_stats[f'payg_{category}_interrupted_count'] = 0 + payg_stats[f'payg_{category}_interrupt_rate [%]'] = np.nan + + if print_comments and interrupted_count > 0: + print(f" PAYG Interruptions: {interrupted_count}/{total_intermodal} ({payg_stats['payg_interrupt_rate [%]']:.1f}%)") + print(f" - No PT available: {no_pt_count}") + print(f" - No LM AMoD available: {no_amod_count}") + + return payg_stats + + def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end_time=None, print_comments=False, dir_names_in={}): """ Main intermodal evaluation function. @@ -431,6 +521,12 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end 'total_uncatchable_rate': np.nan } + # Calculate PAYG-specific metrics (if applicable) + # Determine if this is a PAYG scenario based on broker_type in config + broker_type = scenario_parameters.get(G_BROKER_TYPE, "") + is_payg_scenario = broker_type == "PTBrokerPAYG" + payg_stats = calculate_payg_metrics(parent_user_stats, is_payg_scenario, print_comments) + # Calculate PT wait times for FM and FLM fm_requests = served_requests[served_requests['modal_category'] == 'FM'] flm_requests = served_requests[served_requests['modal_category'] == 'FLM'] @@ -562,6 +658,10 @@ def intermodal_evaluation(output_dir, evaluation_start_time=None, evaluation_end 'mod revenue': total_revenue, } + # Add PAYG-specific metrics if available + if payg_stats: + result_dict.update(payg_stats) + # Vehicle-level analysis for AMoD operators if print_comments: print("\nAnalyzing vehicle operations...") diff --git a/src/misc/globals.py b/src/misc/globals.py index 4db5d6f2..38457c61 100644 --- a/src/misc/globals.py +++ b/src/misc/globals.py @@ -487,6 +487,10 @@ G_RQ_MAX_TRANSFERS = "max_transfers" G_RQ_SUB_TRIP_ID = "sub_trip_id" G_RQ_UNCATCHABLE_PT = "uncatchable_pt" # flag for requests that missed their PT connection after FM leg +# PAYG (Plan-As-You-Go) specific +G_RQ_PAYG_INTERRUPTED = "payg_interrupted" # flag for PAYG trips that were interrupted +G_RQ_PAYG_INTERRUPT_STATE = "payg_interrupt_state" # PAYG_TRIP_STATE value when interrupted +G_RQ_PAYG_INTERRUPT_TIME = "payg_interrupt_time" # simulation time when interrupted class RQ_MODAL_STATE(Enum): """ This enum is used to identify different modal states of a traveler request. @@ -517,6 +521,18 @@ class RQ_SUB_TRIP_ID(Enum): FLM_AMOD_1: int = 7 PT: int = 8 +class PAYG_TRIP_STATE(Enum): + """PAYG trip state tracking""" + PENDING = 0 # Waiting for processing + FM_AMOD_BOOKED = 1 # FM/FLM: First AMoD leg booked + FM_AMOD_COMPLETED = 2 # FM/FLM: First AMoD leg completed + PT_BOOKED = 3 # PT leg booked + PT_COMPLETED = 4 # PT leg completed + LM_AMOD_BOOKED = 5 # LM/FLM: Last AMoD leg booked + COMPLETED = 10 # Trip completed + INTERRUPTED_NO_PT = -1 # Interrupted: No PT available + INTERRUPTED_NO_LM_AMOD = -2 # Interrupted: No LM AMoD available + # output general # -------------- G_RQ_TYPE = "rq_type" diff --git a/src/misc/init_modules.py b/src/misc/init_modules.py index c601840c..1b945c56 100644 --- a/src/misc/init_modules.py +++ b/src/misc/init_modules.py @@ -120,6 +120,7 @@ def get_src_broker_modules(): broker_dict["BrokerBasic"] = ("src.broker.BrokerBasic", "BrokerBasic") broker_dict["PTBroker"] = ("src.broker.PTBroker", "PTBroker") broker_dict["PTBrokerEI"] = ("src.broker.PTBrokerEI", "PTBrokerEI") + broker_dict["PTBrokerPAYG"] = ("src.broker.PTBrokerPAYG", "PTBrokerPAYG") # add development content if dev_content is not None: dev_broker_dict = dev_content.add_broker_modules() diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv index 6132df08..fb1e6a3e 100644 --- a/studies/example_study/scenarios/example_im.csv +++ b/studies/example_study/scenarios/example_im.csv @@ -3,4 +3,5 @@ example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5, example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 example_im_ptbrokerEI_mdtf30,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,30,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 example_im_ptbrokerEI_mdtf10,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,10,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbrokerEI_mdtf0,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,0,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file +example_im_ptbrokerEI_mdtf0,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,0,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbrokerPAYG,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerPAYG,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From 918b55d41f0393078160d79cbf96c31345bdc120 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Thu, 5 Feb 2026 16:45:50 +0100 Subject: [PATCH 27/31] Modify the logic of implementing MaaS estimated detour time factor --- src/broker/PTBrokerEI.py | 7 +++++-- studies/example_study/scenarios/example_im.csv | 4 +--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/broker/PTBrokerEI.py b/src/broker/PTBrokerEI.py index 89e381c3..cee18605 100644 --- a/src/broker/PTBrokerEI.py +++ b/src/broker/PTBrokerEI.py @@ -67,7 +67,7 @@ def __init__( super().__init__(n_amod_op, amod_operators, pt_operator, demand, routing_engine, scenario_parameters) # set MaaS detour time estimation parameter - self.maas_detour_time_factor: float = self.scenario_parameters.get(G_BROKER_MAAS_DETOUR_TIME_FACTOR , 100) + self.maas_detour_time_factor: float = self.scenario_parameters.get(G_BROKER_MAAS_DETOUR_TIME_FACTOR , 100) / 100 def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): """This method processes the new firstmile request. @@ -297,8 +297,11 @@ def _estimate_amod_dropoff_time(self, amod_op_id: int, sub_rq_obj: 'BasicIntermo prq_direct_tt = sub_prq_obj.init_direct_tt amod_boarding_time = self.amod_operators[amod_op_id].const_bt + amod_max_dtf = self.amod_operators[amod_op_id].max_dtf / 100 prq_pu_latest = sub_prq_obj.t_pu_latest - maas_estimated_prq_max_trip_time = (100 + self.maas_detour_time_factor) * (prq_direct_tt + amod_boarding_time) / 100 + + # MaaS estimates that only a certain percentage of the operator maximum detour time will be realized + maas_estimated_prq_max_trip_time = (1 + self.maas_detour_time_factor * amod_max_dtf) * (prq_direct_tt + amod_boarding_time) maas_estimated_latest_dropoff_time: int = prq_pu_latest + int(maas_estimated_prq_max_trip_time) return maas_estimated_latest_dropoff_time diff --git a/studies/example_study/scenarios/example_im.csv b/studies/example_study/scenarios/example_im.csv index fb1e6a3e..d6380964 100644 --- a/studies/example_study/scenarios/example_im.csv +++ b/studies/example_study/scenarios/example_im.csv @@ -1,7 +1,5 @@ scenario_name,op_module,rq_file,op_fleet_composition,broker_type,broker_maas_detour_time_factor,pt_operator_type,gtfs_name,pt_simulation_start_date,rq_type,op_rh_reservation_max_routes,evaluation_method,sim_env,user_max_decision_time example_im_ptbroker,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 example_im_ptbroker_lmwt30,PoolingIRSOnly,example_100_intermodal_lmwt30.csv,default_vehtype:5,PTBroker,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbrokerEI_mdtf30,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,30,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbrokerEI_mdtf10,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,10,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 -example_im_ptbrokerEI_mdtf0,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,0,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 +example_im_ptbrokerEI_mdtf50,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerEI,50,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 example_im_ptbrokerPAYG,PoolingIRSOnly,example_100_intermodal.csv,default_vehtype:5,PTBrokerPAYG,,PTControlBasic,example_gtfs,20250101,BasicIntermodalRequest,5,intermodal_evaluation,ImmediateDecisionsSimulation,0 \ No newline at end of file From 9ae9e781ef97c0abb2d52261d21495ebd0c682f4 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Fri, 13 Feb 2026 21:33:12 +0100 Subject: [PATCH 28/31] Fix bugs --- src/broker/PTBroker.py | 16 ++++++++++++++++ src/broker/PTBrokerBasic.py | 10 +--------- src/broker/PTBrokerPAYG.py | 4 ++++ src/fleetctrl/reservation/RollingHorizon.py | 9 +++++++++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index 7780b40a..b46ffa1f 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -70,6 +70,22 @@ def __init__( """ super().__init__(n_amod_op, amod_operators, pt_operator, demand, routing_engine, scenario_parameters) + def _inform_amod_sub_request( + self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, + parent_modal_state: RQ_MODAL_STATE, op_id: int, sim_time: int + ): + """Overrides PTBrokerBasic to support customizable max_wait_time for last-mile AMoD pickups.""" + amod_sub_rq_obj: 'RequestBase' = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) + LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") + + # get customizable wait time for last mile AMoD pickups + if parent_modal_state == RQ_MODAL_STATE.LASTMILE or (parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE and sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value): + max_wait_time: tp.Optional[int] = rq_obj.get_lastmile_max_wait_time() + else: + max_wait_time: tp.Optional[int] = None + + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time, max_wait_time=max_wait_time) + def _process_inform_firstmile_request(self, rid: int, rq_obj: 'BasicIntermodalRequest', sim_time: int, parent_modal_state: RQ_MODAL_STATE = RQ_MODAL_STATE.FIRSTMILE): """This method processes the new firstmile request. In this stage, only the first-mile AMoD sub-request is created first; the PT sub-request will be created after receiving the AMoD offer. diff --git a/src/broker/PTBrokerBasic.py b/src/broker/PTBrokerBasic.py index 6a560e32..e308e4e6 100644 --- a/src/broker/PTBrokerBasic.py +++ b/src/broker/PTBrokerBasic.py @@ -362,15 +362,7 @@ def _inform_amod_sub_request( amod_sub_rq_obj: RequestBase = self.demand.create_sub_requests(rq_obj, sub_trip_id, leg_o_node, leg_d_node, leg_start_time, parent_modal_state) LOG.debug(f"AMoD sub-request {amod_sub_rq_obj.get_rid_struct()} with modal state {parent_modal_state}: To operator {op_id} ...") - # get customizable wait time for last mile AMoD pickups - if parent_modal_state == RQ_MODAL_STATE.LASTMILE or (parent_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE and sub_trip_id == RQ_SUB_TRIP_ID.FLM_AMOD_1.value): - # in this case, the parent request type must be BasicIntermodalRequest - max_wait_time: tp.Optional[int] = rq_obj.get_lastmile_max_wait_time() - else: - # no customizable wait time, operator default wait time will be used - max_wait_time: tp.Optional[int] = None - - self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time, max_wait_time=max_wait_time) + self.amod_operators[op_id].user_request(amod_sub_rq_obj, sim_time) def _inform_pt_sub_request( self, rq_obj: 'RequestBase', sub_trip_id: int, leg_o_node: int, leg_d_node: int, leg_start_time: int, diff --git a/src/broker/PTBrokerPAYG.py b/src/broker/PTBrokerPAYG.py index 1ef2ed45..44969b69 100644 --- a/src/broker/PTBrokerPAYG.py +++ b/src/broker/PTBrokerPAYG.py @@ -361,6 +361,8 @@ def _handle_fm_amod_alighting( # Get PT offer and record it on sub-request pt_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.FM_PT.value}" pt_sub_rq_obj = self.demand[pt_rid_struct] + # Clear inherited AMOD offers from deepcopy of parent request + pt_sub_rq_obj.offer = {} pt_offer = self.pt_operator.get_current_offer(pt_rid_struct, amod_op_id) if pt_offer is not None: pt_sub_rq_obj.receive_offer(self.pt_operator_id, pt_offer, None) @@ -400,6 +402,8 @@ def _handle_flm_amod_0_alighting( # Get PT offer and record it on sub-request pt_rid_struct = f"{rid}_{RQ_SUB_TRIP_ID.FLM_PT.value}" pt_sub_rq_obj = self.demand[pt_rid_struct] + # Clear inherited AMOD offers from deepcopy of parent request + pt_sub_rq_obj.offer = {} pt_offer = self.pt_operator.get_current_offer(pt_rid_struct, amod_op_id) if pt_offer is not None: pt_sub_rq_obj.receive_offer(self.pt_operator_id, pt_offer, None) diff --git a/src/fleetctrl/reservation/RollingHorizon.py b/src/fleetctrl/reservation/RollingHorizon.py index b393f60d..3dd0125a 100644 --- a/src/fleetctrl/reservation/RollingHorizon.py +++ b/src/fleetctrl/reservation/RollingHorizon.py @@ -101,6 +101,7 @@ def user_cancels_request(self, rid, simulation_time): :param rid: request id :param simulation_time: current simulation time """ + # If assigned to a vehicle, remove from vehicle plan if self.rid_to_assigned_vid.get(rid) is not None: vid = self.rid_to_assigned_vid[rid] assigned_plan = self.fleetctrl.veh_plans[vid] @@ -109,7 +110,15 @@ def user_cancels_request(self, rid, simulation_time): self.routing_engine, self.fleetctrl.vr_ctrl_f, self.fleetctrl.rq_dict, self.fleetctrl.const_bt, self.fleetctrl.add_bt) self.fleetctrl.assign_vehicle_plan(veh_obj, new_plan, simulation_time) del self.rid_to_assigned_vid[rid] + + # FIX: Unconditionally clean up active_reservation_requests and sorted_rids_with_epa + # This fixes a bug discovered in PTBrokerEI where cancellation after user_confirms_booking + # (e.g., LM AMoD sub-request cancelled due to uncatchable PT) left stale entries in + # sorted_rids_with_epa, causing KeyError in reveal_requests_for_online_optimization. + # Reference: RollingHorizonNoGuarantee has the correct implementation. + if rid in self.active_reservation_requests: del self.active_reservation_requests[rid] + self.sorted_rids_with_epa = [(r, epa) for r, epa in self.sorted_rids_with_epa if r != rid] def time_trigger(self, sim_time): """ this function is triggered during the simulation time and might trigger reoptimization processes for example From de1c55d1ad0898e0da9b386189f7d78307bd7c73 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 23 Feb 2026 14:41:56 +0100 Subject: [PATCH 29/31] add pixi support --- .gitattributes | 2 + .gitignore | 3 + pixi.lock | 7620 ++++++++++++++++++++++++++++++++++++++++++++++++ pixi.toml | 34 + 4 files changed, 7659 insertions(+) create mode 100644 .gitattributes create mode 100644 pixi.lock create mode 100644 pixi.toml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..997504b4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.gitignore b/.gitignore index bb599d12..2f276d51 100644 --- a/.gitignore +++ b/.gitignore @@ -198,3 +198,6 @@ dmypy.json # GTFS preprocessing file !src/preprocessing/pt/PTRouterGTFSPreperation.ipynb +# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 00000000..60444d48 --- /dev/null +++ b/pixi.lock @@ -0,0 +1,7620 @@ +version: 6 +environments: + default: + channels: + - url: https://conda.anaconda.org/conda-forge/ + - url: https://conda.anaconda.org/main/ + - url: https://conda.anaconda.org/r/ + - url: https://conda.anaconda.org/msys2/ + - url: https://conda.anaconda.org/gurobi/ + indexes: + - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py310h3788b33_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py310h25320af_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.10.1-py310h0aed7a2_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py310h3406613_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h9dce30a_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/geos-3.13.0-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.4-h3551947_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda + - conda: https://conda.anaconda.org/gurobi/linux-64/gurobi-13.0.1-py310_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py310haaf941d_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.7-h75ea233_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_8.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libde265-1.0.15-h00ab1b0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-core-3.10.2-h3359108_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-haa4a5bd_1022.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hecd9e04_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h97f6797_17.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.1.0-he57a185_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h1b4f908_12.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py310h3406613_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py310hff52083_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py310hfde16b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.10-h05a5f5f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.3.0-py310h6557065_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.5.1-h0054346_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py310h139afa4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyogrio-0.10.0-py310h0aed7a2_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.7.0-py310h2e9f774_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py310hfd10a26_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py310h89163eb_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py310hc4bea81_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.3.0-py310hfd4b839_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.2-py310h228f341_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.6-py310had3dfd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.51.2-hbc0de68_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py310h7c4b9e2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py310h7c4b9e2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-h988505b_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/f0/89/b1ae45689abecca777f95462781a76e67ff46b55495a481ec5a73a739994/Cython-3.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.1-h7bae524_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.3.0-py310h2d60bed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/blosc-1.21.6-h7dd00d9_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py310h6123dab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.2-py310h7f4e7e6_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/dav1d-1.2.1-hb547adb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py310h19b6747_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.10.1-py310hd68230c_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py310hf4fd40f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-h3ab3353_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/geos-3.13.0-hf9b8971_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/geotiff-1.7.4-hbef4fa4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda + - conda: https://conda.anaconda.org/gurobi/osx-arm64/gurobi-13.0.1-py310_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py310h563d721_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.7-h3c2f2b0_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libavif16-1.3.0-hde9513d_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-hd5a2499_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libde265-1.0.15-h2ffa867_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.23-h5773f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-core-3.10.2-h9ef0d2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libheif-1.19.7-gpl_h79e6334_100.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-hc33e383_1022.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-ha2cf0f4_17.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.1.0-h57eeb1c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-hf92fc0a_12.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1b79a29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h551f018_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.9-h4a9ca0c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py310hf4fd40f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py310hb6292c7_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py310h0181960_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.10-hff1a8ea_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.2.6-py310h4d83441_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py310h5936506_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.44-ha881caa_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-11.3.0-py310h5de80a5_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.5.1-h1318a7e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py310haea493c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyogrio-0.10.0-py310hd68230c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyproj-3.7.0-py310h861c57f_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py310hc74094e_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py310hf0664f0_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rav1e-0.7.1-h0716509_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.3.0-py310h78b29c1_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.2-py310h660f142_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.15.2-py310h32ab4ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.6-py310h6b3522b_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.2.2-hada39a4_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.51.2-h85ec8f2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-4.0.0-h0cb729a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py310hfe3a0ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py310h72544b6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-h92fc2f4_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-hebf3989_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.3.0-h57928b3_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.1-he0c23c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/blosc-1.21.6-hfd34d9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyha7b4d00_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py310hc19bc0b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py310h699e580_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.10.1-py310hf80745b_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py310hdb0e946_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-hf297d47_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.13.0-h5a68840_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.4-h887f4e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda + - conda: https://conda.anaconda.org/gurobi/win-64/gurobi-13.0.1-py310_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.0.0-h9e37d49_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyha7b4d00_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py310h1e1005b_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.7-h5343c79_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.3.0-ha08a409_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.18.0-h43ecb02_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libde265-1.0.15-h91493d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-core-3.10.2-h095903c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.0-h7025463_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libheif-1.19.7-gpl_h2684147_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h88281d1_1000.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-h68a222c_1022.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-hd4c2148_17.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.20-hc70643c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.1.0-h518811d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-h939089a_12.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.9-h741aa76_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h25c3957_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.8-h4fa8253_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py310hdb0e946_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py310h5588dad_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py310h0bdd906_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.10-h9fa1bad_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h24db6dd_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py310hb4db72f_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.3.0-py310hb3a2f59_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.5.1-h4f671f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py310h1637853_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyogrio-0.10.0-py310hf80745b_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyproj-3.7.0-py310h19d4cff_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py310hc1b6536_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.19-hc20f281_3_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py310h282bd7d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py310h38315fa_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py310h78cba24_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h83cda92_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.7.1-ha073cba_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.3.0-py310hdd37b41_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.7.2-py310h21054b0_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py310h15c175c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.6-py310hde62f2e_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.51.2-hdb435a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.0-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py310h29418f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py310h29418f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-he0c23c2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/f9/de/19fdd1c7a52e0534bf5f544e0346c15d71d20338dbd013117f763b94613f/Cython-3.0.11-cp310-cp310-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl +packages: +- conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.3.0-h57928b3_3.conda + sha256: fd43fe0a83a3c42dc2a7244ad8419c47a56916dcf177f7ad0ce2de95f118e159 + md5: 77af412511d5b8e7d9ca63d12cf93672 + purls: [] + size: 10600 + timestamp: 1769477066547 +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 + md5: a9f577daf3de00bca7c3c76c0ecbd1de + depends: + - __glibc >=2.17,<3.0.a0 + - libgomp >=7.5.0 + constrains: + - openmp_impl <0.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 28948 + timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + build_number: 7 + sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd + md5: a44032f282e7d2acdeb1c240308052dd + depends: + - llvm-openmp >=9.0.1 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 8325 + timestamp: 1764092507920 +- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 + md5: 1626967b574d1784b578b52eaeb071e7 + depends: + - libgomp >=7.5.0 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - openmp_impl <0.0a0 + - msys2-conda-epoch <0.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 52252 + timestamp: 1770943776666 +- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda + sha256: d88aa7ae766cf584e180996e92fef2aa7d8e0a0a5ab1d4d49c32390c1b5fff31 + md5: dcdc58c15961dbf17a0621312b01f5cb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-or-later + license_family: GPL + purls: [] + size: 584660 + timestamp: 1768327524772 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda + sha256: b08ef033817b5f9f76ce62dfcac7694e7b6b4006420372de22494503decac855 + md5: 346722a0be40f6edc53f12640d301338 + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 2706396 + timestamp: 1718551242397 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.1-h7bae524_0.conda + sha256: ec238f18ce8140485645252351a0eca9ef4f7a1c568a420f240a585229bc12ef + md5: 7adba36492a1bb22d98ffffe4f6fc6de + depends: + - __osx >=11.0 + - libcxx >=16 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 2235747 + timestamp: 1718551382432 +- conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.1-he0c23c2_0.conda + sha256: 0524d0c0b61dacd0c22ac7a8067f977b1d52380210933b04141f5099c5b6fec7 + md5: 3d7c14285d3eb3239a76ff79063f27a5 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 1958151 + timestamp: 1718551737234 +- conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda + sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf + md5: 54898d0f524c9dee622d44bbb081a8ab + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/appnope?source=hash-mapping + size: 10076 + timestamp: 1733332433806 +- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda + sha256: ee4da0f3fe9d59439798ee399ef3e482791e48784873d546e706d0935f9ff010 + md5: 9673a61a297b00016442e022d689faa6 + depends: + - python >=3.10 + constrains: + - astroid >=2,<5 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/asttokens?source=hash-mapping + size: 28797 + timestamp: 1763410017955 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda + sha256: c13d5e42d187b1d0255f591b7ce91201d4ed8a5370f0d986707a802c20c9d32f + md5: 537296d57ea995666c68c821b00e360b + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/attrs?source=compressed-mapping + size: 64759 + timestamp: 1764875182184 +- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda + sha256: 6660be15a45175c98f750b8bbc3fd07e0da36043624b376de49769bd14a0a16f + md5: 276a3ddf300498921601822e3b407088 + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=hash-mapping + size: 191286 + timestamp: 1767044984395 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.3.0-py310h2d60bed_0.conda + sha256: e1be6c8ed4fc517e56628f1646fb44d9634e7273e87d1bba961163dd3b727caa + md5: 330de33b56b85ac0be5531c0304006f3 + depends: + - python + - python 3.10.* *_cpython + - __osx >=11.0 + - zstd >=1.5.7,<1.6.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=hash-mapping + size: 193486 + timestamp: 1767045052533 +- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda + sha256: ceb8b49b9bf0246b606089ce95e5afe0c4fd39ada3c8c381a3d03fd9beafba88 + md5: 9f9e5cd3aa06ea10681a65355f5dca09 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause AND MIT AND EPL-2.0 + purls: + - pkg:pypi/backports-zstd?source=hash-mapping + size: 190164 + timestamp: 1767045016166 +- conda: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda + sha256: e7af5d1183b06a206192ff440e08db1c4e8b2ca1f8376ee45fb2f3a85d4ee45d + md5: 2c2fae981fd2afd00812c92ac47d023d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - snappy >=1.2.1,<1.3.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 48427 + timestamp: 1733513201413 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/blosc-1.21.6-h7dd00d9_1.conda + sha256: c3fe902114b9a3ac837e1a32408cc2142c147ec054c1038d37aec6814343f48a + md5: 925acfb50a750aa178f7a0aced77f351 + depends: + - __osx >=11.0 + - libcxx >=18 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - snappy >=1.2.1,<1.3.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 33602 + timestamp: 1733513285902 +- conda: https://conda.anaconda.org/conda-forge/win-64/blosc-1.21.6-hfd34d9b_1.conda + sha256: 9303a7a0e03cf118eab3691013f6d6cbd1cbac66efbc70d89b20f5d0145257c0 + md5: 357d7be4146d5fec543bfaa96a8a40de + depends: + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - snappy >=1.2.1,<1.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.6,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 49840 + timestamp: 1733513605730 +- conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda + sha256: 1acf87c77d920edd098ddc91fa785efc10de871465dee0f463815b176e019e8b + md5: 1fcdf88e7a8c296d3df8409bf0690db4 + depends: + - jinja2 >=3 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/branca?source=hash-mapping + size: 30176 + timestamp: 1759755695447 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda + sha256: e511644d691f05eb12ebe1e971fd6dc3ae55a4df5c253b4e1788b789bdf2dfa6 + md5: 8ccf913aaba749a5496c17629d859ed1 + depends: + - __glibc >=2.17,<3.0.a0 + - brotli-bin 1.2.0 hb03c661_1 + - libbrotlidec 1.2.0 hb03c661_1 + - libbrotlienc 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 20103 + timestamp: 1764017231353 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda + sha256: 422ac5c91f8ef07017c594d9135b7ae068157393d2a119b1908c7e350938579d + md5: 48ece20aa479be6ac9a284772827d00c + depends: + - __osx >=11.0 + - brotli-bin 1.2.0 hc919400_1 + - libbrotlidec 1.2.0 hc919400_1 + - libbrotlienc 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 20237 + timestamp: 1764018058424 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda + sha256: a4fffdf1c9b9d3d0d787e20c724cff3a284dfa3773f9ce609c93b1cfd0ce8933 + md5: bc58fdbced45bb096364de0fba1637af + depends: + - brotli-bin 1.2.0 hfd05255_1 + - libbrotlidec 1.2.0 hfd05255_1 + - libbrotlienc 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 20342 + timestamp: 1764017988883 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda + sha256: 64b137f30b83b1dd61db6c946ae7511657eead59fdf74e84ef0ded219605aa94 + md5: af39b9a8711d4a8d437b52c1d78eb6a1 + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlidec 1.2.0 hb03c661_1 + - libbrotlienc 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 21021 + timestamp: 1764017221344 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda + sha256: e2d142052a83ff2e8eab3fe68b9079cad80d109696dc063a3f92275802341640 + md5: 377d015c103ad7f3371be1777f8b584c + depends: + - __osx >=11.0 + - libbrotlidec 1.2.0 hc919400_1 + - libbrotlienc 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 18628 + timestamp: 1764018033635 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda + sha256: e76966232ef9612de33c2087e3c92c2dc42ea5f300050735a3c646f33bce0429 + md5: 6abd7089eb3f0c790235fe469558d190 + depends: + - libbrotlidec 1.2.0 hfd05255_1 + - libbrotlienc 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 22714 + timestamp: 1764017952449 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda + sha256: f036fe554d902549f86689a9650a0996901d5c9242b0a1e3fbfe6dbccd2ae011 + md5: 393fca4557fbd2c4d995dcb89f569048 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + constrains: + - libbrotlicommon 1.2.0 hb03c661_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 367099 + timestamp: 1764017439384 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py310h6123dab_1.conda + sha256: 317f9b0ab95739a6739e577dee1d4fe2d07fbbe1a97109d145f0de3204cfc7d6 + md5: d9359ff9677b23fb89005e3b8dbe8139 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + constrains: + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 359599 + timestamp: 1764018669488 +- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda + sha256: fd250a4f92c2176f23dd4e07de1faf76741dabcc8fa00b182748db4d9578ff7e + md5: 0caf12fa6690b7f64883b2239853dda0 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libbrotlicommon 1.2.0 hfd05255_1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/brotli?source=hash-mapping + size: 335476 + timestamp: 1764018212429 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 260182 + timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 124834 + timestamp: 1771350416561 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda + sha256: 4ddcb01be03f85d3db9d881407fb13a673372f1b9fac9c836ea441893390e049 + md5: 84d389c9eee640dda3d26fc5335c67d8 + depends: + - __win + license: ISC + purls: [] + size: 147139 + timestamp: 1767500904211 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + sha256: b5974ec9b50e3c514a382335efa81ed02b05906849827a34061c496f4defa0b2 + md5: bddacf101bb4dd0e51811cb69c7790e2 + depends: + - __unix + license: ISC + purls: [] + size: 146519 + timestamp: 1767500828366 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda + sha256: 3bd6a391ad60e471de76c0e9db34986c4b5058587fbf2efa5a7f54645e28c2c7 + md5: 09262e66b19567aff4f592fb53b28760 + depends: + - __glibc >=2.17,<3.0.a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - freetype >=2.12.1,<3.0a0 + - icu >=75.1,<76.0a0 + - libexpat >=2.6.4,<3.0a0 + - libgcc >=13 + - libglib >=2.82.2,<3.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libstdcxx >=13 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.44.2,<1.0a0 + - xorg-libice >=1.1.2,<2.0a0 + - xorg-libsm >=1.2.5,<2.0a0 + - xorg-libx11 >=1.8.11,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: LGPL-2.1-only or MPL-1.1 + purls: [] + size: 978114 + timestamp: 1741554591855 +- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda + sha256: b9f577bddb033dba4533e851853924bfe7b7c1623d0697df382eef177308a917 + md5: 20e32ced54300292aff690a69c5e7b97 + depends: + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - freetype >=2.12.1,<3.0a0 + - icu >=75.1,<76.0a0 + - libexpat >=2.6.4,<3.0a0 + - libglib >=2.82.2,<3.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.44.2,<1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-only or MPL-1.1 + purls: [] + size: 1524254 + timestamp: 1741555212198 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda + sha256: 110338066d194a715947808611b763857c15458f8b3b97197387356844af9450 + md5: eacc711330cd46939f66cd401ff9c44b + depends: + - python >=3.10 + license: ISC + purls: + - pkg:pypi/certifi?source=compressed-mapping + size: 150969 + timestamp: 1767500900768 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda + sha256: b32f8362e885f1b8417bac2b3da4db7323faa12d5db62b7fd6691c02d60d6f59 + md5: a22d1fd9bf98827e280a02875d9a007a + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/charset-normalizer?source=hash-mapping + size: 50965 + timestamp: 1760437331772 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda + sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 + md5: ea8a6c3256897cc31263de9f455e25d9 + depends: + - python >=3.10 + - __unix + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/click?source=hash-mapping + size: 97676 + timestamp: 1764518652276 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyha7b4d00_1.conda + sha256: c3bc9a49930fa1c3383a1485948b914823290efac859a2587ca57a270a652e08 + md5: 6cd3ccc98bacfcc92b2bd7f236f01a7e + depends: + - python >=3.10 + - colorama + - __win + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/click?source=hash-mapping + size: 96620 + timestamp: 1764518654675 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda + sha256: ba1ee6e2b2be3da41d70d0d51d1159010de900aa3f33fceaea8c52e9bd30a26e + md5: e9b05deb91c013e5224672a4ba9cf8d1 + depends: + - click >=4.0 + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/click-plugins?source=hash-mapping + size: 12683 + timestamp: 1750848314962 +- conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda + sha256: 1a52ae1febfcfb8f56211d1483a1ac4419b0028b7c3e9e61960a298978a42396 + md5: 55c7804f428719241a90b152016085a1 + depends: + - click >=4.0 + - python >=3.9,<4.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cligj?source=hash-mapping + size: 12521 + timestamp: 1733750069604 +- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 + md5: 962b9857ee8e7018c22f2776ffa0b2d7 + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/colorama?source=hash-mapping + size: 27011 + timestamp: 1733218222191 +- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda + sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 + md5: 2da13f2b299d8e1995bafbbe9689a2f7 + depends: + - python >=3.9 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/comm?source=hash-mapping + size: 14690 + timestamp: 1753453984907 +- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py310h3788b33_0.conda + sha256: 5231c1b68e01a9bc9debabc077a6fb48c4395206d59f40a4598d1d5e353e11d8 + md5: b6420d29123c7c823de168f49ccdfe6a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.23 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/contourpy?source=hash-mapping + size: 261280 + timestamp: 1744743236964 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.2-py310h7f4e7e6_0.conda + sha256: 758a7a858d8a5dca265e0754c73659690a99226e7e8d530666fece3b38e44558 + md5: 18ad60675af8d74a6e49bf40055419d0 + depends: + - __osx >=11.0 + - libcxx >=18 + - numpy >=1.23 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/contourpy?source=hash-mapping + size: 231970 + timestamp: 1744743542215 +- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py310hc19bc0b_0.conda + sha256: 096a7cf6bf77faf3e093936d831118151781ddbd2ab514355ee2f0104b490b1e + md5: 039416813b5290e7d100a05bb4326110 + depends: + - numpy >=1.23 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/contourpy?source=hash-mapping + size: 201075 + timestamp: 1744743764641 +- conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda + sha256: bb47aec5338695ff8efbddbc669064a3b10fe34ad881fb8ad5d64fbfa6910ed1 + md5: 4c2a8fef270f6c69591889b93f9f55c1 + depends: + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/cycler?source=hash-mapping + size: 14778 + timestamp: 1764466758386 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda + sha256: ee09ad7610c12c7008262d713416d0b58bf365bc38584dce48950025850bdf3f + md5: cae723309a49399d2949362f4ab5c9e4 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - libntlm >=1.8,<2.0a0 + - libstdcxx >=13 + - libxcrypt >=4.4.36 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause-Attribution + license_family: BSD + purls: [] + size: 209774 + timestamp: 1750239039316 +- pypi: https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl + name: cython + version: 3.0.11 + sha256: 0e25f6425ad4a700d7f77cd468da9161e63658837d1bc34861a9861a4ef6346d + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/f0/89/b1ae45689abecca777f95462781a76e67ff46b55495a481ec5a73a739994/Cython-3.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: cython + version: 3.0.11 + sha256: d89a82937ce4037f092e9848a7bbcc65bc8e9fc9aef2bb74f5c15e7d21a73080 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- pypi: https://files.pythonhosted.org/packages/f9/de/19fdd1c7a52e0534bf5f544e0346c15d71d20338dbd013117f763b94613f/Cython-3.0.11-cp310-cp310-win_amd64.whl + name: cython + version: 3.0.11 + sha256: d02f4ebe15aac7cdacce1a628e556c1983f26d140fd2e0ac5e0a090e605a2d38 + requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' +- conda: https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda + sha256: 22053a5842ca8ee1cf8e1a817138cdb5e647eb2c46979f84153f6ad7bde73020 + md5: 418c6ca5929a611cbd69204907a83995 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 760229 + timestamp: 1685695754230 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/dav1d-1.2.1-hb547adb_0.conda + sha256: 93e077b880a85baec8227e8c72199220c7f87849ad32d02c14fb3807368260b8 + md5: 5a74cdee497e6b65173e10d94582fae6 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 316394 + timestamp: 1685695959391 +- conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda + sha256: 2aa2083c9c186da7d6f975ccfbef654ed54fff27f4bc321dbcd12cee932ec2c4 + md5: ed2c27bda330e3f0ab41577cf8b9b585 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 618643 + timestamp: 1685696352968 +- conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 + sha256: 8f5f995699a2d9dbdd62c61385bfeeb57c82a681a7c8c5313c395aa0ccab68a5 + md5: ecfff944ba3960ecb334b9a2663d708d + depends: + - expat >=2.4.2,<3.0a0 + - libgcc-ng >=9.4.0 + - libglib >=2.70.2,<3.0a0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 618596 + timestamp: 1640112124844 +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py310h25320af_0.conda + sha256: 129b1c9a2a2ed1fc3cdb2005d0af8bd1e4d12486c9d27fd5b154d39b4c2373a7 + md5: 6ae8cc92dfb0b063519b9203445506af + depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2234314 + timestamp: 1769744974941 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py310h19b6747_0.conda + sha256: 2ab1ec63052db574f7114ce3baa51905f1bc7a45eb546a549f72bcbbede8ff8a + md5: 0ea5aa84f85cb3d7be64bdab143a6b95 + depends: + - python + - __osx >=11.0 + - libcxx >=19 + - python 3.10.* *_cpython + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 2223547 + timestamp: 1769744999621 +- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py310h699e580_0.conda + sha256: 54fe3d0c32dca060666828e216d92a68c59de9a154c8e21d9800714cd3ba32c3 + md5: b2593f2b78589063833a245823e830ed + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/debugpy?source=hash-mapping + size: 3481569 + timestamp: 1769745019386 +- conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda + sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 + md5: 9ce473d1d1be1cc3810856a48b3fab32 + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/decorator?source=hash-mapping + size: 14129 + timestamp: 1740385067843 +- pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl + name: dill + version: 0.3.9 + sha256: 468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a + requires_dist: + - objgraph>=1.7.2 ; extra == 'graph' + - gprof2dot>=2022.7.29 ; extra == 'profile' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda + sha256: 1bcc132fbcc13f9ad69da7aa87f60ea41de7ed4d09f3a00ff6e0e70e1c690bc2 + md5: bfd56492d8346d669010eccafe0ba058 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 69544 + timestamp: 1739569648873 +- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda + sha256: b1fee32ef36a98159f0a2a96c4e734dfc9adff73acd444940831b22c1fb6d5c0 + md5: e9a1402439c18a4e3c7a52e4246e9e1c + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 71355 + timestamp: 1739570178995 +- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda + sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 + md5: 8e662bd460bda79b1ea39194e3c4c9ab + depends: + - python >=3.10 + - typing_extensions >=4.6.0 + license: MIT and PSF-2.0 + purls: + - pkg:pypi/exceptiongroup?source=hash-mapping + size: 21333 + timestamp: 1763918099466 +- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad + md5: ff9efb7f7469aed3c4a8106ffa29593c + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/executing?source=hash-mapping + size: 30753 + timestamp: 1756729456476 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda + sha256: 0cc345e4dead417996ce9a1f088b28d858f03d113d43c1963d29194366dcce27 + md5: a0535741a4934b3e386051065c58761a + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat 2.7.4 hecca717_0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 145274 + timestamp: 1771259434699 +- pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl + name: fastjsonschema + version: 2.21.2 + sha256: 1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 + requires_dist: + - colorama ; extra == 'devel' + - jsonschema ; extra == 'devel' + - json-spec ; extra == 'devel' + - pylint ; extra == 'devel' + - pytest ; extra == 'devel' + - pytest-benchmark ; extra == 'devel' + - pytest-cache ; extra == 'devel' + - validictory ; extra == 'devel' +- conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.10.1-py310h0aed7a2_3.conda + sha256: 69d5f613a3002859784ba82259aa67a930bfe00de70551ba47e28c846ba610ec + md5: 159a16dee358df063730c205f7428993 + depends: + - __glibc >=2.17,<3.0.a0 + - attrs >=19.2.0 + - click >=8.0,<9.dev0 + - click-plugins >=1.0 + - cligj >=0.5 + - libgcc >=13 + - libgdal-core >=3.10.0,<3.11.0a0 + - libstdcxx >=13 + - pyparsing + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - shapely + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fiona?source=hash-mapping + size: 1140688 + timestamp: 1733507676726 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.10.1-py310hd68230c_3.conda + sha256: 2ded6e797861878f87ce5c25c403221f075d10a009c0b6c4ebec8aa81391a159 + md5: e8fc7492c6e613d0d337624031ea404b + depends: + - __osx >=11.0 + - attrs >=19.2.0 + - click >=8.0,<9.dev0 + - click-plugins >=1.0 + - cligj >=0.5 + - libcxx >=18 + - libgdal-core >=3.10.0,<3.11.0a0 + - pyparsing + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + - shapely + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fiona?source=hash-mapping + size: 1002256 + timestamp: 1733507830986 +- conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.10.1-py310hf80745b_3.conda + sha256: 89f54fad0277aacdda7b29ec8aae3cf323174eeb1ec0b0bb3dd6f8fc12682620 + md5: aebf566da9c4b92954a60f6765ac40de + depends: + - attrs >=19.2.0 + - click >=8.0,<9.dev0 + - click-plugins >=1.0 + - cligj >=0.5 + - libgdal-core >=3.10.0,<3.11.0a0 + - pyparsing + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - shapely + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/fiona?source=hash-mapping + size: 957762 + timestamp: 1733507936027 +- conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda + sha256: 782fa186d7677fd3bc1ff7adb4cc3585f7d2c7177c30bcbce21f8c177135c520 + md5: a6997a7dcd6673c0692c61dfeaea14ab + depends: + - branca >=0.6.0 + - jinja2 >=2.9 + - numpy + - python >=3.9 + - requests + - xyzservices + license: MIT + license_family: MIT + purls: + - pkg:pypi/folium?source=hash-mapping + size: 82665 + timestamp: 1750113928159 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + md5: 0c96522c6bdaed4b1566d11387caaf45 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 397370 + timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + md5: 34893075a5c9e55cdafac56607368fc6 + license: OFL-1.1 + license_family: Other + purls: [] + size: 96530 + timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + md5: 4d59c254e01d9cde7957100457e2d5fb + license: OFL-1.1 + license_family: Other + purls: [] + size: 700814 + timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 + md5: 49023d73832ef61042f6a237cb2687e7 + license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 + license_family: Other + purls: [] + size: 1620504 + timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda + sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c + md5: 867127763fbe935bab59815b6e0b7b5c + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libgcc >=14 + - libuuid >=2.41.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 270705 + timestamp: 1771382710863 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda + sha256: ff2db9d305711854de430f946dc59bd40167940a1de38db29c5a78659f219d9c + md5: a0b1b87e871011ca3b783bbf410bc39f + depends: + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 195332 + timestamp: 1771382820659 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + md5: fee5683a3f04bd15cbd8318b096a27ab + depends: + - fonts-conda-forge + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 3667 + timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 + md5: a7970cd949a077b7cb9696379d338681 + depends: + - font-ttf-ubuntu + - font-ttf-inconsolata + - font-ttf-dejavu-sans-mono + - font-ttf-source-code-pro + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4059 + timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py310h3406613_0.conda + sha256: 6dccba7a293b6dbab029da4d921d2d94227c9541152489fc7d7db4ec3c68dff3 + md5: 24fa891e40acdb1c7f51efd0c5f97084 + depends: + - __glibc >=2.17,<3.0.a0 + - brotli + - libgcc >=14 + - munkres + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - unicodedata2 >=15.1.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/fonttools?source=hash-mapping + size: 2446291 + timestamp: 1765632899119 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py310hf4fd40f_0.conda + sha256: 67518a55dc2295409791319e0276fc8ec25e29fe9452867579da45d08cf8aa9c + md5: a85ff44569675422773962490c80dd0b + depends: + - __osx >=11.0 + - brotli + - munkres + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + - unicodedata2 >=15.1.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/fonttools?source=hash-mapping + size: 2353815 + timestamp: 1765633031708 +- conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py310hdb0e946_0.conda + sha256: 433be2ca71f302bb9fa6bde0b842417f2ab9b203fae8547ce95a3def9edfc9e3 + md5: c2b488b68301c02d503e5cc9ee7bafc8 + depends: + - brotli + - munkres + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - unicodedata2 >=15.1.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: + - pkg:pypi/fonttools?source=hash-mapping + size: 2011123 + timestamp: 1765632908321 +- conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda + sha256: bf8e4dffe46f7d25dc06f31038cacb01672c47b9f45201f065b0f4d00ab0a83e + md5: 4afc585cd97ba8a23809406cd8a9eda8 + depends: + - libfreetype 2.14.1 ha770c72_0 + - libfreetype6 2.14.1 h73754d4_0 + license: GPL-2.0-only OR FTL + purls: [] + size: 173114 + timestamp: 1757945422243 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda + sha256: 14427aecd72e973a73d5f9dfd0e40b6bc3791d253de09b7bf233f6a9a190fd17 + md5: 1ec9a1ee7a2c9339774ad9bb6fe6caec + depends: + - libfreetype 2.14.1 hce30654_0 + - libfreetype6 2.14.1 h6da58f4_0 + license: GPL-2.0-only OR FTL + purls: [] + size: 173399 + timestamp: 1757947175403 +- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda + sha256: a9b3313edea0bf14ea6147ea43a1059d0bf78771a1336d2c8282891efc57709a + md5: d69c21967f35eb2ce7f1f85d6b6022d3 + depends: + - libfreetype 2.14.1 h57928b3_0 + - libfreetype6 2.14.1 hdbac1cb_0 + license: GPL-2.0-only OR FTL + purls: [] + size: 184553 + timestamp: 1757946164012 +- conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h9dce30a_2.conda + sha256: c8960e00a6db69b85c16c693ce05484facf20f1a80430552145f652a880e0d2a + md5: ecb5d11305b8ba1801543002e69d2f2f + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.6.4,<3.0a0 + - libgcc >=13 + - libiconv >=1.17,<2.0a0 + - minizip >=4.0.7,<5.0a0 + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 59299 + timestamp: 1734014884486 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-h3ab3353_2.conda + sha256: b4146ac9ba1676494e3d812ca39664dd7dd454e4d0984f3665fd6feec318c71c + md5: dd655a29b40fe0d1bf95c64cf3cb348d + depends: + - __osx >=11.0 + - libexpat >=2.6.4,<3.0a0 + - libiconv >=1.17,<2.0a0 + - minizip >=4.0.7,<5.0a0 + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 53378 + timestamp: 1734014980768 +- conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-hf297d47_2.conda + sha256: 1e62cbc6daa74656034dc4a6e58faa2d50291719c1cba53cc0b1946f0d2b9404 + md5: d6a8059de245e53478b581742b53f71d + depends: + - libexpat >=2.6.4,<3.0a0 + - libiconv >=1.17,<2.0a0 + - minizip >=4.0.7,<5.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 77528 + timestamp: 1734015193826 +- conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda + sha256: 04f7e616ebbf6352ff852b53c57901e43f14e2b3c92411f99b5547f106bc192e + md5: 1baca589eb35814a392eaad6d152447e + depends: + - folium + - geopandas-base 1.0.1 pyha770c72_3 + - mapclassify >=2.4.0 + - matplotlib-base + - pyogrio >=0.7.2 + - pyproj >=3.3.0 + - python >=3.9 + - xyzservices + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7583 + timestamp: 1734346218849 +- conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda + sha256: 2d031871b57c6d4e5e2d6cc23bd6d4e0084bb52ebca5c1b20bf06d03749e0f24 + md5: e8343d1b635bf09dafdd362d7357f395 + depends: + - numpy >=1.22 + - packaging + - pandas >=1.4.0 + - python >=3.9 + - shapely >=2.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/geopandas?source=hash-mapping + size: 239261 + timestamp: 1734346217454 +- conda: https://conda.anaconda.org/conda-forge/linux-64/geos-3.13.0-h5888daf_0.conda + sha256: 5c70d6d16e044859edca85feb9d4f1c3c6062aaf88d650826f5ccdf8c44336de + md5: 40b4ab956c90390e407bb177f8a58bab + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: LGPL-2.1-only + purls: [] + size: 1869233 + timestamp: 1725676083126 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/geos-3.13.0-hf9b8971_0.conda + sha256: 273381020b72bde1597d4e07e855ed50ffac083512e61ccbdd99d93f03c6cbf2 + md5: 45b2e9adb9663644b1eefa5300b9eef3 + depends: + - __osx >=11.0 + - libcxx >=17 + license: LGPL-2.1-only + purls: [] + size: 1481430 + timestamp: 1725676193541 +- conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.13.0-h5a68840_0.conda + sha256: 2b46d6f304f70dfca304169299908b558bd1e83992acb5077766eefa3d3fe35f + md5: 08a30fe29a645fc5c768c0968db116d3 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-only + purls: [] + size: 1665961 + timestamp: 1725676536384 +- conda: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.4-h3551947_0.conda + sha256: a5c6bf5654cf7e96d44aaac68b4b654a9e148b811e5b0f36ba7d70db87416fff + md5: 5998212641e3feb3660295eacc717139 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libstdcxx >=13 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - zlib + license: MIT + license_family: MIT + purls: [] + size: 129359 + timestamp: 1739974781272 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/geotiff-1.7.4-hbef4fa4_0.conda + sha256: e0d914bab03a578ace37cb45446249f8e23a36d80cf866e37c582e7f9d6eca0e + md5: c01fde51346f834d3f80affab45f0740 + depends: + - __osx >=11.0 + - libcxx >=18 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - zlib + license: MIT + license_family: MIT + purls: [] + size: 112457 + timestamp: 1739974826028 +- conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.4-h887f4e7_0.conda + sha256: f0435dd63c97ad9e8d35a2c1d55c823c50dac82a8dffd8d41c79c0305fa0cc2b + md5: d5edee34ab83553450b1225cf0a14273 + depends: + - libjpeg-turbo >=3.0.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zlib + license: MIT + license_family: MIT + purls: [] + size: 123341 + timestamp: 1739975151946 +- conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda + sha256: aac402a8298f0c0cc528664249170372ef6b37ac39fdc92b40601a6aed1e32ff + md5: 3bf7b9fd5a7136126e0234db4b87c8b6 + depends: + - libgcc-ng >=12 + license: MIT + license_family: MIT + purls: [] + size: 77248 + timestamp: 1712692454246 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda + sha256: 843b3f364ff844137e37d5c0a181f11f6d51adcedd216f019d074e5aa5d7e09c + md5: 95fa1486c77505330c20f7202492b913 + license: MIT + license_family: MIT + purls: [] + size: 71613 + timestamp: 1712692611426 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda + sha256: 25ba37da5c39697a77fce2c9a15e48cf0a84f1464ad2aafbe53d8357a9f6cc8c + md5: 2cd94587f3a401ae05e03a6caf09539d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 99596 + timestamp: 1755102025473 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda + sha256: 5f1714b07252f885a62521b625898326ade6ca25fbc20727cfe9a88f68a54bfd + md5: b785694dd3ec77a011ccf0c24725382b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 96336 + timestamp: 1755102441729 +- conda: https://conda.anaconda.org/gurobi/linux-64/gurobi-13.0.1-py310_0.conda + sha256: b42f58d198d7616ac7aec050598c7515bb0de9670eb9fdec147e76fd0afe8601 + md5: 65c0ff34413231cc42e2c5f519981ffd + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: PROPRIETARY + size: 48151839 + timestamp: 1768424392860 +- conda: https://conda.anaconda.org/gurobi/osx-arm64/gurobi-13.0.1-py310_0.conda + sha256: 04430764767d96724ce1f1b053c657c7d30905bd3c5d49a4a68e4ccb208010ee + md5: 93bedecb20f0fe58107ea3553b9c403e + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: PROPRIETARY + size: 44146772 + timestamp: 1768422175898 +- conda: https://conda.anaconda.org/gurobi/win-64/gurobi-13.0.1-py310_0.conda + sha256: ec49cd6abec06877774b53ca1c24e699ac3e162690856b2f5058cc065c28fd15 + md5: 0db05bb47f7fc6975eb24964788f6765 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: PROPRIETARY + size: 44075259 + timestamp: 1768418153345 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda + sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 + md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 + depends: + - python >=3.10 + - hyperframe >=6.1,<7 + - hpack >=4.1,<5 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/h2?source=hash-mapping + size: 95967 + timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda + sha256: 5bd0f3674808862838d6e2efc0b3075e561c34309c5c2f4c976f7f1f57c91112 + md5: 0e6e192d4b3d95708ad192d957cf3163 + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - freetype + - graphite2 + - icu >=75.1,<76.0a0 + - libexpat >=2.7.0,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libglib >=2.84.1,<3.0a0 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1730226 + timestamp: 1747091044218 +- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.0.0-h9e37d49_0.conda + sha256: f1ab5960a52a11186f528249bec5ce5e43bb4c44c87ffa24334255f07c3fd4b8 + md5: b7648427f5b6797ae3904ad76e4c7f19 + depends: + - cairo >=1.18.4,<2.0a0 + - freetype >=2.13.3,<3.0a0 + - graphite2 + - icu >=75.1,<76.0a0 + - libexpat >=2.6.4,<3.0a0 + - libglib >=2.84.0,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 1125019 + timestamp: 1743083466989 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba + md5: 0a802cb9888dd14eeefc611f05c40b6e + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hpack?source=hash-mapping + size: 30731 + timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 + md5: 8e6923fc12f1fe8f8c4e5c9f343256ac + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/hyperframe?source=hash-mapping + size: 17397 + timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda + sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e + md5: 8b189310083baabfb622af68fd9d3ae3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: MIT + license_family: MIT + purls: [] + size: 12129203 + timestamp: 1720853576813 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda + sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 + md5: 5eb22c1d7b3fc4abb50d92d621583137 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 11857802 + timestamp: 1720853997952 +- conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda + sha256: 1d04369a1860a1e9e371b9fc82dd0092b616adcf057d6c88371856669280e920 + md5: 8579b6bb8d18be7c0b27fb08adeeeb40 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 14544252 + timestamp: 1720853966338 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda + sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 + md5: 53abe63df7e10a6ba605dc5f9f961d36 + depends: + - python >=3.10 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/idna?source=hash-mapping + size: 50721 + timestamp: 1760286526795 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda + sha256: 5c1f3e874adaf603449f2b135d48f168c5d510088c78c229bda0431268b43b27 + md5: 4b53d436f3fbc02ce3eeaf8ae9bebe01 + depends: + - appnope + - __osx + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=compressed-mapping + size: 132260 + timestamp: 1770566135697 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda + sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 + md5: b3a7d5842f857414d9ae831a799444dd + depends: + - __win + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=compressed-mapping + size: 132382 + timestamp: 1770566174387 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda + sha256: b77ed58eb235e5ad80e742b03caeed4bbc2a2ef064cb9a2deee3b75dfae91b2a + md5: 8b267f517b81c13594ed68d646fd5dcb + depends: + - __linux + - comm >=0.1.1 + - debugpy >=1.6.5 + - ipython >=7.23.1 + - jupyter_client >=8.8.0 + - jupyter_core >=5.1,!=6.0.* + - matplotlib-inline >=0.1 + - nest-asyncio >=1.4 + - packaging >=22 + - psutil >=5.7 + - python >=3.10 + - pyzmq >=25 + - tornado >=6.4.1 + - traitlets >=5.4.0 + - python + constrains: + - appnope >=0.1.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipykernel?source=compressed-mapping + size: 133644 + timestamp: 1770566133040 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda + sha256: e43fa762183b49c3c3b811d41259e94bb14b7bff4a239b747ef4e1c6bbe2702d + md5: 177cfa19fe3d74c87a8889286dc64090 + depends: + - __unix + - pexpect >4.3 + - decorator + - exceptiongroup + - jedi >=0.16 + - matplotlib-inline + - pickleshare + - prompt-toolkit >=3.0.41,<3.1.0 + - pygments >=2.4.0 + - python >=3.10 + - stack_data + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython?source=hash-mapping + size: 639160 + timestamp: 1748711175284 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyha7b4d00_0.conda + sha256: 4812e69a1c9d6d43746fa7e8efaf9127d257508249e7192e68cd163511a751ee + md5: 2ffea44095ca39b38b67599e8091bca3 + depends: + - __win + - colorama + - decorator + - exceptiongroup + - jedi >=0.16 + - matplotlib-inline + - pickleshare + - prompt-toolkit >=3.0.41,<3.1.0 + - pygments >=2.4.0 + - python >=3.10 + - stack_data + - traitlets >=5.13.0 + - typing_extensions >=4.6 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/ipython?source=hash-mapping + size: 638940 + timestamp: 1748711254071 +- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda + sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 + md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 + depends: + - parso >=0.8.3,<0.9.0 + - python >=3.9 + license: Apache-2.0 AND MIT + purls: + - pkg:pypi/jedi?source=hash-mapping + size: 843646 + timestamp: 1733300981994 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda + sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b + md5: 04558c96691bed63104678757beb4f8d + depends: + - markupsafe >=2.0 + - python >=3.10 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jinja2?source=compressed-mapping + size: 120685 + timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda + sha256: 301539229d7be6420c084490b8145583291123f0ce6b92f56be5948a2c83a379 + md5: 615de2a4d97af50c350e5cf160149e77 + depends: + - python >=3.10 + - setuptools + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/joblib?source=hash-mapping + size: 226448 + timestamp: 1765794135253 +- conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda + sha256: 09e706cb388d3ea977fabcee8e28384bdaad8ce1fc49340df5f868a2bd95a7da + md5: 38f5dbc9ac808e31c00650f7be1db93f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 82709 + timestamp: 1726487116178 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda + sha256: 73179a1cd0b45c09d4f631cb359d9e755e6e573c5d908df42006728e0bf8297c + md5: 94f14ef6157687c30feb44e1abecd577 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 73715 + timestamp: 1726487214495 +- pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl + name: jsonschema + version: 4.26.0 + sha256: d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce + requires_dist: + - attrs>=22.2.0 + - jsonschema-specifications>=2023.3.6 + - referencing>=0.28.4 + - rpds-py>=0.25.0 + - fqdn ; extra == 'format' + - idna ; extra == 'format' + - isoduration ; extra == 'format' + - jsonpointer>1.13 ; extra == 'format' + - rfc3339-validator ; extra == 'format' + - rfc3987 ; extra == 'format' + - uri-template ; extra == 'format' + - webcolors>=1.11 ; extra == 'format' + - fqdn ; extra == 'format-nongpl' + - idna ; extra == 'format-nongpl' + - isoduration ; extra == 'format-nongpl' + - jsonpointer>1.13 ; extra == 'format-nongpl' + - rfc3339-validator ; extra == 'format-nongpl' + - rfc3986-validator>0.1.0 ; extra == 'format-nongpl' + - rfc3987-syntax>=1.1.0 ; extra == 'format-nongpl' + - uri-template ; extra == 'format-nongpl' + - webcolors>=24.6.0 ; extra == 'format-nongpl' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl + name: jsonschema-specifications + version: 2025.9.1 + sha256: 98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe + requires_dist: + - referencing>=0.31.0 + requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda + sha256: e402bd119720862a33229624ec23645916a7d47f30e1711a4af9e005162b84f3 + md5: 8a3d6d0523f66cf004e563a50d9392b3 + depends: + - jupyter_core >=5.1 + - python >=3.10 + - python-dateutil >=2.8.2 + - pyzmq >=25.0 + - tornado >=6.4.1 + - traitlets >=5.3 + - python + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-client?source=compressed-mapping + size: 112785 + timestamp: 1767954655912 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda + sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc + md5: a8db462b01221e9f5135be466faeb3e0 + depends: + - __win + - pywin32 + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 64679 + timestamp: 1760643889625 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda + sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a + md5: b38fe4e78ee75def7e599843ef4c1ab0 + depends: + - __unix + - python + - platformdirs >=2.5 + - python >=3.10 + - traitlets >=5.3 + - python + constrains: + - pywin32 >=300 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/jupyter-core?source=hash-mapping + size: 65503 + timestamp: 1760643864586 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + purls: [] + size: 134088 + timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py310haaf941d_2.conda + sha256: 5ef8337c7a89719427d25b0cdc776b34116fe988efc9bf56f5a2831d74b1584e + md5: 7426d76535fc6347f1b74f85fb17d6eb + depends: + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/kiwisolver?source=hash-mapping + size: 78299 + timestamp: 1762488741951 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py310h563d721_2.conda + sha256: 38d427a3d24ca94b4c424bcb0fdacde5a3a196c1be1aee84cf60edca98d6167a + md5: 1c29ffa84e75a6f8be4a8d8ddce17545 + depends: + - python + - python 3.10.* *_cpython + - __osx >=11.0 + - libcxx >=19 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/kiwisolver?source=hash-mapping + size: 65984 + timestamp: 1762488860157 +- conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py310h1e1005b_2.conda + sha256: dbca5656a0e07dbc998d4d5e51497782d2e0d9c097a1072a9d4df5e2ef797dce + md5: 6b165d2b50fce619244bec7495bbbbc2 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/kiwisolver?source=hash-mapping + size: 73319 + timestamp: 1762488749759 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 + md5: 3f43953b7d3fb3aaa1d0d0723d91e368 + depends: + - keyutils >=1.6.1,<2.0a0 + - libedit >=3.1.20191231,<3.2.0a0 + - libedit >=3.1.20191231,<4.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - openssl >=3.3.1,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1370023 + timestamp: 1719463201255 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed + md5: e446e1822f4da8e5080a9de93474184d + depends: + - __osx >=11.0 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 1160828 + timestamp: 1769770119811 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + sha256: 18e8b3430d7d232dad132f574268f56b3eb1a19431d6d5de8c53c29e6c18fa81 + md5: 31aec030344e962fbd7dbbbbd68e60a9 + depends: + - openssl >=3.3.1,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 712034 + timestamp: 1719463874284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda + sha256: d6a61830a354da022eae93fa896d0991385a875c6bba53c82263a289deda9db8 + md5: 000e85703f0fd9594c81710dd5066471 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + license: MIT + license_family: MIT + purls: [] + size: 248046 + timestamp: 1739160907615 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda + sha256: 310a62c2f074ebd5aa43b3cd4b00d46385ce680fa2132ecee255a200e2d2f15f + md5: 92a61fd30b19ebd5c1621a5bfe6d8b5f + depends: + - __osx >=11.0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + license: MIT + license_family: MIT + purls: [] + size: 212125 + timestamp: 1739161108467 +- conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda + sha256: 7712eab5f1a35ca3ea6db48ead49e0d6ac7f96f8560da8023e61b3dbe4f3b25d + md5: 3538827f77b82a837fa681a4579e37a1 + depends: + - libjpeg-turbo >=3.0.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 510641 + timestamp: 1739161381270 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda + sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 + md5: 12bd9a3f089ee6c9266a37dab82afabd + depends: + - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 725507 + timestamp: 1770267139900 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda + sha256: 412381a43d5ff9bbed82cd52a0bbca5b90623f62e41007c9c42d3870c60945ff + md5: 9344155d33912347b37f0ae6c410a835 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 264243 + timestamp: 1745264221534 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda + sha256: 12361697f8ffc9968907d1a7b5830e34c670e4a59b638117a2cdfed8f63a38f8 + md5: a74332d9b60b62905e3d30709df08bf1 + depends: + - __osx >=11.0 + - libcxx >=18 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 188306 + timestamp: 1745264362794 +- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda + sha256: 868a3dff758cc676fa1286d3f36c3e0101cca56730f7be531ab84dc91ec58e9d + md5: c1b81da6d29a14b542da14a36c9fbf3f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 164701 + timestamp: 1745264384716 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.7-h75ea233_4.conda + sha256: d49b2a3617b689763d1377a5d1fbfc3c914ee0afa26b3c1858e1c4329329c6df + md5: b80309616f188ac77c4740acba40f796 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=13 + - liblzma >=5.8.1,<6.0a0 + - libxml2 >=2.13.7,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - lzo >=2.10,<3.0a0 + - openssl >=3.5.0,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 866358 + timestamp: 1745335292389 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.7-h3c2f2b0_4.conda + sha256: b7f862cfa4522dd4774c61376a95b1b3aea80ff0d42dd5ebf6c9a07d32eb6f18 + md5: 4b12c69a3c3ca02ceac535ae6168f3af + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2 >=2.13.7,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - lzo >=2.10,<3.0a0 + - openssl >=3.5.0,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 774033 + timestamp: 1745335663024 +- conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.7-h5343c79_4.conda + sha256: fd947dfdcf70b56dad679ec4053cc76cc69b208fb1220072d543482640f56c57 + md5: 3bb78f661ec0ac3cdbae48c880545f41 + depends: + - bzip2 >=1.0.8,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libxml2 >=2.13.7,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - lzo >=2.10,<3.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 1085438 + timestamp: 1745336188302 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda + sha256: f5ab201b8b4e1f776ced0340c59f87e441fd6763d3face527b5cf3f2280502c9 + md5: 22d5cc5fb45aab8ed3c00cde2938b825 + depends: + - __glibc >=2.17,<3.0.a0 + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - libgcc >=14 + - rav1e >=0.7.1,<0.8.0a0 + - svt-av1 >=4.0.0,<4.0.1.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 140323 + timestamp: 1769476997956 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libavif16-1.3.0-hde9513d_3.conda + sha256: 92eb3f8134586972145378b21ac789a65ee232d7c1ef01ce5bfc9e850d0e0e60 + md5: 6e9bcb90cfd20178a52f355030aba237 + depends: + - __osx >=11.0 + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - rav1e >=0.7.1,<0.8.0a0 + - svt-av1 >=4.0.0,<4.0.1.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 111474 + timestamp: 1769477399074 +- conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.3.0-ha08a409_3.conda + sha256: 489379a872874af8939f9efeccf3c6ff6461d221fefae00c4c54b2eb3731b093 + md5: b1c835a63bee00ff1aaf94468fa18140 + depends: + - _libavif_api >=1.3.0,<1.3.1.0a0 + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - rav1e >=0.7.1,<0.8.0a0 + - svt-av1 >=4.0.0,<4.0.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 117410 + timestamp: 1769477171156 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda + build_number: 5 + sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c + md5: c160954f7418d7b6e87eaf05a8913fa9 + depends: + - libopenblas >=0.3.30,<0.3.31.0a0 + - libopenblas >=0.3.30,<1.0a0 + constrains: + - mkl <2026 + - liblapack 3.11.0 5*_openblas + - libcblas 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18213 + timestamp: 1765818813880 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda + build_number: 5 + sha256: 620a6278f194dcabc7962277da6835b1e968e46ad0c8e757736255f5ddbfca8d + md5: bcc025e2bbaf8a92982d20863fe1fb69 + depends: + - libopenblas >=0.3.30,<0.3.31.0a0 + - libopenblas >=0.3.30,<1.0a0 + constrains: + - libcblas 3.11.0 5*_openblas + - liblapack 3.11.0 5*_openblas + - liblapacke 3.11.0 5*_openblas + - blas 2.305 openblas + - mkl <2026 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18546 + timestamp: 1765819094137 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda + build_number: 5 + sha256: f0cb7b2697461a306341f7ff32d5b361bb84f3e94478464c1e27ee01fc8f276b + md5: f9decf88743af85c9c9e05556a4c47c0 + depends: + - mkl >=2025.3.0,<2026.0a0 + constrains: + - liblapack 3.11.0 5*_mkl + - libcblas 3.11.0 5*_mkl + - blas 2.305 mkl + - liblapacke 3.11.0 5*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 67438 + timestamp: 1765819100043 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e + md5: 72c8fd1af66bd67bf580645b426513ed + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 79965 + timestamp: 1764017188531 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda + sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 + md5: 006e7ddd8a110771134fcc4e1e3a6ffa + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 79443 + timestamp: 1764017945924 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda + sha256: 5097303c2fc8ebf9f9ea9731520aa5ce4847d0be41764edd7f6dee2100b82986 + md5: 444b0a45bbd1cb24f82eedb56721b9c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 82042 + timestamp: 1764017799966 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b + md5: 366b40a69f0ad6072561c1d09301c886 + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 34632 + timestamp: 1764017199083 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda + sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf + md5: 079e88933963f3f149054eec2c487bc2 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 29452 + timestamp: 1764017979099 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda + sha256: 3239ce545cf1c32af6fffb7fc7c75cb1ef5b6ea8221c66c85416bb2d46f5cccb + md5: 450e3ae947fc46b60f1d8f8f318b40d4 + depends: + - libbrotlicommon 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 34449 + timestamp: 1764017851337 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d + md5: 4ffbb341c8b616aa2494b6afb26a0c5f + depends: + - __glibc >=2.17,<3.0.a0 + - libbrotlicommon 1.2.0 hb03c661_1 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 298378 + timestamp: 1764017210931 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda + sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 + md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 + depends: + - __osx >=11.0 + - libbrotlicommon 1.2.0 hc919400_1 + license: MIT + license_family: MIT + purls: [] + size: 290754 + timestamp: 1764018009077 +- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda + sha256: 3226df6b7df98734440739f75527d585d42ca2bfe912fbe8d1954c512f75341a + md5: ccd93cfa8e54fd9df4e83dbe55ff6e8c + depends: + - libbrotlicommon 1.2.0 hfd05255_1 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 252903 + timestamp: 1764017901735 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda + build_number: 5 + sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 + md5: 6636a2b6f1a87572df2970d3ebc87cc0 + depends: + - libblas 3.11.0 5_h4a7cf45_openblas + constrains: + - liblapacke 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapack 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18194 + timestamp: 1765818837135 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda + build_number: 5 + sha256: 38809c361bbd165ecf83f7f05fae9b791e1baa11e4447367f38ae1327f402fc0 + md5: efd8bd15ca56e9d01748a3beab8404eb + depends: + - libblas 3.11.0 5_h51639a9_openblas + constrains: + - liblapacke 3.11.0 5*_openblas + - liblapack 3.11.0 5*_openblas + - blas 2.305 openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18548 + timestamp: 1765819108956 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda + build_number: 5 + sha256: 49dc59d8e58360920314b8d276dd80da7866a1484a9abae4ee2760bc68f3e68d + md5: b3fa8e8b55310ba8ef0060103afb02b5 + depends: + - libblas 3.11.0 5_hf2e6a31_mkl + constrains: + - liblapack 3.11.0 5*_mkl + - liblapacke 3.11.0 5*_mkl + - blas 2.305 mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 68079 + timestamp: 1765819124349 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_8.conda + sha256: e4dfc9b820a5f7bcc5862f0d275a2c85e838a2de9c6d1d10b048ab7570f8a968 + md5: 0071e5b9af13b5bcf39e371f3100ce3f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm20 >=20.1.8,<20.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 21291311 + timestamp: 1768845917554 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda + sha256: e6c0123b888d6abf03c66c52ed89f9de1798dde930c5fd558774f26e994afbc6 + md5: 327c78a8ce710782425a89df851392f7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libllvm21 >=21.1.0,<21.2.0a0 + - libstdcxx >=14 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 12358102 + timestamp: 1757383373129 +- conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda + sha256: 77ac3fa55fdc5ba0e3709c5830a99dd1abd8f13fd96845768f72ea64ff1baf14 + md5: 06e385238457018ad1071179b67e39d1 + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 28993850 + timestamp: 1770197403573 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda + sha256: cb83980c57e311783ee831832eb2c20ecb41e7dee6e86e8b70b8cef0e43eab55 + md5: d4a250da4737ee127fb1fa6452a9002e + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 4523621 + timestamp: 1749905341688 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda + sha256: 5454709d9fb6e9c3dd6423bc284fa7835a7823bfa8323f6e8786cdd555101fab + md5: 0a5563efed19ca4461cf927419b6eb73 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + purls: [] + size: 462942 + timestamp: 1767821743793 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-hd5a2499_1.conda + sha256: dbc34552fc6f040bbcd52b4246ec068ce8d82be0e76bfe45c6984097758d37c2 + md5: 2742a933ef07e91f38e3d33ad6fe937c + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + purls: [] + size: 402616 + timestamp: 1770893178846 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.18.0-h43ecb02_0.conda + sha256: 86258e30845571ea13855e8a0605275905781476f3edf8ae5df90a06fcada93a + md5: 2688214a9bee5d5650cd4f5f6af5c8f2 + depends: + - krb5 >=1.21.3,<1.22.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + purls: [] + size: 383261 + timestamp: 1767821977053 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda + sha256: 5fbeb2fc2673f0455af6079abf93faaf27f11a92574ad51565fa1ecac9a4e2aa + md5: 4cb5878bdb9ebfa65b7cdff5445087c5 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 570068 + timestamp: 1770238262922 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libde265-1.0.15-h00ab1b0_0.conda + sha256: 7cf7e294e1a7c8219065885e186d8f52002fb900bf384d815f159b5874204e3d + md5: 407fee7a5d7ab2dca12c9ca7f62310ad + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 411814 + timestamp: 1703088639063 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libde265-1.0.15-h2ffa867_0.conda + sha256: 13747fa634f7f16d7f222b7d3869e3c1aab9d3a2791edeb2fc632a87663950e0 + md5: 7c718ee6d8497702145612fa0898a12d + depends: + - libcxx >=15 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 277861 + timestamp: 1703089176970 +- conda: https://conda.anaconda.org/conda-forge/win-64/libde265-1.0.15-h91493d7_0.conda + sha256: f52c603151743486d2faec37e161c60731001d9c955e0f12ac9ad334c1119116 + md5: 9dc3c1fbc1c7bc6204e8a603f45e156b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 252968 + timestamp: 1703089151021 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda + sha256: 4db2f70a1441317d964e84c268e388110ad9cf75ca98994d1336d670e62e6f07 + md5: 27fe770decaf469a53f3e3a6d593067f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 72783 + timestamp: 1745260463421 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.23-h5773f1b_0.conda + sha256: ebc06154e9a2085e8c9edf81f8f5196b73a1698e18ac6386c9b43fb426103327 + md5: 4dc332b504166d7f89e4b3b18ab5e6ea + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 54685 + timestamp: 1745260666631 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda + sha256: 881244050587dc658078ee45dfc792ecb458bbb1fdc861da67948d747b117dc2 + md5: 34f03138e46543944d4d7f8538048842 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 155548 + timestamp: 1745260818985 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda + sha256: c076a213bd3676cc1ef22eeff91588826273513ccc6040d9bea68bccdc849501 + md5: 9314bc5a1fe7d1044dc9dfd3ef400535 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpciaccess >=0.18,<0.19.0a0 + license: MIT + license_family: MIT + purls: [] + size: 310785 + timestamp: 1757212153962 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b + depends: + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda + sha256: 7fd5408d359d05a969133e47af580183fbf38e2235b562193d427bb9dad79723 + md5: c151d5eb730e9b7480e6d48c0fc44048 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + purls: [] + size: 44840 + timestamp: 1731330973553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda + sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 + md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.7.4.* + license: MIT + license_family: MIT + purls: [] + size: 76798 + timestamp: 1771259418166 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda + sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf + md5: a92e310ae8dfc206ff449f362fc4217f + depends: + - __osx >=11.0 + constrains: + - expat 2.7.4.* + license: MIT + license_family: MIT + purls: [] + size: 68199 + timestamp: 1771260020767 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda + sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d + md5: 1c1ced969021592407f16ada4573586d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.7.4.* + license: MIT + license_family: MIT + purls: [] + size: 70323 + timestamp: 1771259521393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab + md5: ede4673863426c0883c0063d853bbd85 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 57433 + timestamp: 1743434498161 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda + sha256: 4641d37faeb97cf8a121efafd6afd040904d4bca8c46798122f417c31d5dfbec + md5: f4084e4e6577797150f9b04a4560ceb0 + depends: + - libfreetype6 >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 7664 + timestamp: 1757945417134 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda + sha256: 9de25a86066f078822d8dd95a83048d7dc2897d5d655c0e04a8a54fca13ef1ef + md5: f35fb38e89e2776994131fbf961fa44b + depends: + - libfreetype6 >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 7810 + timestamp: 1757947168537 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda + sha256: 2029702ec55e968ce18ec38cc8cf29f4c8c4989a0d51797164dab4f794349a64 + md5: 3235024fe48d4087721797ebd6c9d28c + depends: + - libfreetype6 >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 8109 + timestamp: 1757946135015 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda + sha256: 4a7af818a3179fafb6c91111752954e29d3a2a950259c14a2fc7ba40a8b03652 + md5: 8e7251989bca326a28f4a5ffbd74557a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpng >=1.6.50,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - freetype >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 386739 + timestamp: 1757945416744 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda + sha256: cc4aec4c490123c0f248c1acd1aeab592afb6a44b1536734e20937cda748f7cd + md5: 6d4ede03e2a8e20eb51f7f681d2a2550 + depends: + - __osx >=11.0 + - libpng >=1.6.50,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - freetype >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 346703 + timestamp: 1757947166116 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda + sha256: 223710600b1a5567163f7d66545817f2f144e4ef8f84e99e90f6b8a4e19cb7ad + md5: 6e7c5c5ab485057b5d07fd8188ba5c28 + depends: + - libpng >=1.6.50,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - freetype >=2.14.1 + license: GPL-2.0-only OR FTL + purls: [] + size: 340264 + timestamp: 1757946133889 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 + md5: 0aa00f03f9e39fb9876085dee11a85d4 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 1041788 + timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda + sha256: 1d9c4f35586adb71bcd23e31b68b7f3e4c4ab89914c26bed5f2859290be5560e + md5: 92df6107310b1fff92c4cc84f0de247b + depends: + - _openmp_mutex + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 401974 + timestamp: 1771378877463 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda + sha256: da2c96563c76b8c601746f03e03ac75d2b4640fa2ee017cb23d6c9fc31f1b2c6 + md5: b085746891cca3bd2704a450a7b4b5ce + depends: + - _openmp_mutex >=4.5 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - libgcc-ng ==15.2.0=*_18 + - msys2-conda-epoch <0.0a0 + - libgomp 15.2.0 h8ee18e1_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 820022 + timestamp: 1771382190160 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 + md5: d5e96b1ed75ca01906b3d2469b4ce493 + depends: + - libgcc 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27526 + timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-core-3.10.2-h3359108_0.conda + sha256: a3b549ab4a096561ce4046955505c2806bab721948d35c57dcc4cf2a64a19691 + md5: f460a299f5a2f34a8049071f47a81949 + depends: + - __glibc >=2.17,<3.0.a0 + - blosc >=1.21.6,<2.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - geotiff >=1.7.3,<1.8.0a0 + - giflib >=5.2.2,<5.3.0a0 + - json-c >=0.18,<0.19.0a0 + - lerc >=4.0.0,<5.0a0 + - libarchive >=3.7.7,<3.8.0a0 + - libcurl >=8.12.1,<9.0a0 + - libdeflate >=1.23,<1.24.0a0 + - libexpat >=2.6.4,<3.0a0 + - libgcc >=13 + - libheif >=1.19.5,<1.20.0a0 + - libiconv >=1.17,<2.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libkml >=1.3.0,<1.4.0a0 + - liblzma >=5.6.4,<6.0a0 + - libpng >=1.6.46,<1.7.0a0 + - libspatialite >=5.1.0,<5.2.0a0 + - libsqlite >=3.48.0,<4.0a0 + - libstdcxx >=13 + - libtiff >=4.7.0,<4.8.0a0 + - libuuid >=2.38.1,<3.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - openssl >=3.4.1,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - proj >=9.5.1,<9.6.0a0 + - xerces-c >=3.2.5,<3.3.0a0 + - zstd >=1.5.6,<1.6.0a0 + constrains: + - libgdal 3.10.2.* + license: MIT + license_family: MIT + purls: [] + size: 10801211 + timestamp: 1739626046005 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-core-3.10.2-h9ef0d2d_0.conda + sha256: bb72a3c879eddcb0e7e01e662245ec3f9fe07c53cf287217a200e52a39115014 + md5: 5982d6c652d39c9cef709bf22cbbb94d + depends: + - __osx >=11.0 + - blosc >=1.21.6,<2.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - geotiff >=1.7.3,<1.8.0a0 + - giflib >=5.2.2,<5.3.0a0 + - json-c >=0.18,<0.19.0a0 + - lerc >=4.0.0,<5.0a0 + - libarchive >=3.7.7,<3.8.0a0 + - libcurl >=8.12.1,<9.0a0 + - libcxx >=18 + - libdeflate >=1.23,<1.24.0a0 + - libexpat >=2.6.4,<3.0a0 + - libheif >=1.19.5,<1.20.0a0 + - libiconv >=1.17,<2.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libkml >=1.3.0,<1.4.0a0 + - liblzma >=5.6.4,<6.0a0 + - libpng >=1.6.46,<1.7.0a0 + - libspatialite >=5.1.0,<5.2.0a0 + - libsqlite >=3.48.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - openssl >=3.4.1,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - proj >=9.5.1,<9.6.0a0 + - xerces-c >=3.2.5,<3.3.0a0 + - zstd >=1.5.6,<1.6.0a0 + constrains: + - libgdal 3.10.2.* + license: MIT + license_family: MIT + purls: [] + size: 8463050 + timestamp: 1739626559515 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-core-3.10.2-h095903c_0.conda + sha256: e387998eee0468570dd87764d0c78d94f7d9d5846cdfa050f71f3fe01f8941b9 + md5: 91f3b8afc65762e8710b50bdda8116c7 + depends: + - blosc >=1.21.6,<2.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - geotiff >=1.7.3,<1.8.0a0 + - lerc >=4.0.0,<5.0a0 + - libarchive >=3.7.7,<3.8.0a0 + - libcurl >=8.12.1,<9.0a0 + - libdeflate >=1.23,<1.24.0a0 + - libexpat >=2.6.4,<3.0a0 + - libheif >=1.19.5,<1.20.0a0 + - libiconv >=1.17,<2.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libkml >=1.3.0,<1.4.0a0 + - liblzma >=5.6.4,<6.0a0 + - libpng >=1.6.46,<1.7.0a0 + - libspatialite >=5.1.0,<5.2.0a0 + - libsqlite >=3.48.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - lz4-c >=1.10.0,<1.11.0a0 + - openssl >=3.4.1,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - proj >=9.5.1,<9.6.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - xerces-c >=3.2.5,<3.3.0a0 + - zstd >=1.5.6,<1.6.0a0 + constrains: + - libgdal 3.10.2.* + license: MIT + license_family: MIT + purls: [] + size: 8392331 + timestamp: 1739628560888 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda + sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee + md5: 9063115da5bc35fdc3e1002e69b9ef6e + depends: + - libgfortran5 15.2.0 h68bc16d_18 + constrains: + - libgfortran-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27523 + timestamp: 1771378269450 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda + sha256: 63f89087c3f0c8621c5c89ecceec1e56e5e1c84f65fc9c5feca33a07c570a836 + md5: 26981599908ed2205366e8fc91b37fc6 + depends: + - libgfortran5 15.2.0 hdae7583_18 + constrains: + - libgfortran-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 138973 + timestamp: 1771379054939 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda + sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 + md5: 646855f357199a12f02a87382d429b75 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 2482475 + timestamp: 1771378241063 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda + sha256: 91033978ba25e6a60fb86843cf7e1f7dc8ad513f9689f991c9ddabfaf0361e7e + md5: c4a6f7989cffb0544bfd9207b6789971 + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 598634 + timestamp: 1771378886363 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + sha256: dc2752241fa3d9e40ce552c1942d0a4b5eeb93740c9723873f6fcf8d39ef8d2d + md5: 928b8be80851f5d8ffb016f9c81dae7a + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - libglx 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + purls: [] + size: 134712 + timestamp: 1731330998354 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + sha256: 18e354d30a60441b0bf5fcbb125b6b22fd0df179620ae834e2533d44d1598211 + md5: 0305434da649d4fb48a425e588b79ea6 + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.4.6,<3.5.0a0 + - libgcc >=13 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.44,<10.45.0a0 + constrains: + - glib 2.84.1 *_0 + license: LGPL-2.1-or-later + purls: [] + size: 3947789 + timestamp: 1743773764878 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.0-h7025463_0.conda + sha256: 0b4f9581e2dba58bc38cb00453e145140cf6230a56887ff1195e63e2b1e3f1c2 + md5: ea8df8a5c5c7adf4c03bf9e3db1637c3 + depends: + - libffi >=3.4,<4.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.44,<10.45.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - glib 2.84.0 *_0 + license: LGPL-2.1-or-later + purls: [] + size: 3842095 + timestamp: 1743039211561 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 + md5: 434ca7e50e40f4918ab701e3facd59a0 + depends: + - __glibc >=2.17,<3.0.a0 + license: LicenseRef-libglvnd + purls: [] + size: 132463 + timestamp: 1731330968309 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda + sha256: 2d35a679624a93ce5b3e9dd301fff92343db609b79f0363e6d0ceb3a6478bfa7 + md5: c8013e438185f33b13814c5c488acd5c + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - xorg-libx11 >=1.8.10,<2.0a0 + license: LicenseRef-libglvnd + purls: [] + size: 75504 + timestamp: 1731330988898 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 + md5: 239c5e9546c38a1e884d69effcf4c882 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 603262 + timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda + sha256: 94981bc2e42374c737750895c6fdcfc43b7126c4fc788cad0ecc7281745931da + md5: 939fb173e2a4d4e980ef689e99b35223 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 663864 + timestamp: 1771382118742 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda + sha256: ec9797d57088aeed7ca4905777d4f3e70a4dbe90853590eef7006b0ab337af3f + md5: 1db2693fa6a50bef58da2df97c5204cb + depends: + - __glibc >=2.17,<3.0.a0 + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - libavif16 >=1.2.0,<2.0a0 + - libde265 >=1.0.15,<1.0.16.0a0 + - libgcc >=13 + - libstdcxx >=13 + - x265 >=3.5,<3.6.0a0 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 596714 + timestamp: 1741306859216 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libheif-1.19.7-gpl_h79e6334_100.conda + sha256: 19384a0c0922cbded842e1fa14d8c40a344cb735d1d85598b11f67dc0cd1f4cc + md5: 4f5369442ff2de5983831d321f584eb4 + depends: + - __osx >=11.0 + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - libavif16 >=1.2.0,<2.0a0 + - libcxx >=18 + - libde265 >=1.0.15,<1.0.16.0a0 + - x265 >=3.5,<3.6.0a0 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 442619 + timestamp: 1741307000158 +- conda: https://conda.anaconda.org/conda-forge/win-64/libheif-1.19.7-gpl_h2684147_100.conda + sha256: 55965154b428c22cf0fcf1bd53844c1c4c59f0301ece36782b082a92a51e52af + md5: d7a6c3df36c3281b38164ce518d45528 + depends: + - aom >=3.9.1,<3.10.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - libavif16 >=1.2.0,<2.0a0 + - libde265 >=1.0.15,<1.0.16.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - x265 >=3.5,<3.6.0a0 + license: LGPL-3.0-or-later + license_family: LGPL + purls: [] + size: 391084 + timestamp: 1741307167944 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h88281d1_1000.conda + sha256: 2fb437b82912c74b4869b66c601d52c77bb3ee8cb4812eab346d379f1c823225 + md5: e6298294e7612eccf57376a0683ddc80 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - libxml2 >=2.13.8,<2.14.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 2412139 + timestamp: 1752762145331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f + md5: 915f5995e94f60e9a4826e0b0920ee88 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-only + purls: [] + size: 790176 + timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 + md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + depends: + - __osx >=11.0 + license: LGPL-2.1-only + purls: [] + size: 750379 + timestamp: 1754909073836 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 + md5: 64571d1dd6cdcfa25d0664a5950fdaa2 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only + purls: [] + size: 696926 + timestamp: 1754909290005 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + sha256: c7e4600f28bcada8ea81456a6530c2329312519efcf0c886030ada38976b0511 + md5: 2cf0cf76cc15d360dfa2f17fd6cf9772 + depends: + - libiconv >=1.17,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 95568 + timestamp: 1723629479451 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 + md5: 8397539e3a0bbd1695584fb4f927485a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 633710 + timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda + sha256: 6c061c56058bb10374daaef50e81b39cf43e8aee21f0037022c0c39c4f31872f + md5: f0695fbecf1006f27f4395d64bd0c4b8 + depends: + - __osx >=11.0 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 551197 + timestamp: 1762095054358 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + sha256: 795e2d4feb2f7fc4a2c6e921871575feb32b8082b5760726791f080d1e2c2597 + md5: 56a686f92ac0273c0f6af58858a3f013 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 841783 + timestamp: 1762094814336 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-haa4a5bd_1022.conda + sha256: aa55f5779d6bc7bf24dc8257f053d5a0708b5910b6bc6ea1396f15febf812c98 + md5: 00f0f4a9d2eb174015931b1a234d61ca + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.1,<3.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - uriparser >=0.9.8,<1.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 411495 + timestamp: 1761132836798 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-hc33e383_1022.conda + sha256: ef32d85c00aefa510e9f36f19609dddc93359c1abbe58c2a695a927d2537721f + md5: a91a7afac6eec20a07d9435bf1372bc1 + depends: + - __osx >=11.0 + - libcxx >=19 + - libexpat >=2.7.1,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - uriparser >=0.9.8,<1.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 284064 + timestamp: 1761133563691 +- conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-h68a222c_1022.conda + sha256: eacacca7d9b0bcfca16d44365af2437509d58ea6730efdd2a7468963edf849a1 + md5: 6800434a33b644e46c28ffa3ec18afb1 + depends: + - libexpat >=2.7.1,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - uriparser >=0.9.8,<1.0a0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1659205 + timestamp: 1761132867821 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda + build_number: 5 + sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 + md5: b38076eb5c8e40d0106beda6f95d7609 + depends: + - libblas 3.11.0 5_h4a7cf45_openblas + constrains: + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + - libcblas 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18200 + timestamp: 1765818857876 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda + build_number: 5 + sha256: 735a6e6f7d7da6f718b6690b7c0a8ae4815afb89138aa5793abe78128e951dbb + md5: ca9d752201b7fa1225bca036ee300f2b + depends: + - libblas 3.11.0 5_h51639a9_openblas + constrains: + - libcblas 3.11.0 5*_openblas + - blas 2.305 openblas + - liblapacke 3.11.0 5*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18551 + timestamp: 1765819121855 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda + build_number: 5 + sha256: a2d33f5cc2b8a9042f2af6981c6733ab1a661463823eaa56595a9c58c0ab77e1 + md5: e62c42a4196dee97d20400612afcb2b1 + depends: + - libblas 3.11.0 5_hf2e6a31_mkl + constrains: + - libcblas 3.11.0 5*_mkl + - blas 2.305 mkl + - liblapacke 3.11.0 5*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 80225 + timestamp: 1765819148014 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hecd9e04_0.conda + sha256: a6fddc510de09075f2b77735c64c7b9334cf5a26900da351779b275d9f9e55e1 + md5: 59a7b967b6ef5d63029b1712f8dcf661 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 >=2.13.8,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 43987020 + timestamp: 1752141980723 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda + sha256: d190f1bf322149321890908a534441ca2213a9a96c59819da6cabf2c5b474115 + md5: 9ad637a7ac380c442be142dfb0b1b955 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 >=2.13.8,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + purls: [] + size: 44363060 + timestamp: 1756291822911 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb + md5: c7c83eecbb72d88b940c249af56c8b17 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 113207 + timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e + md5: 009f0d956d7bfb00de86901d16e486c7 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 92242 + timestamp: 1768752982486 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c + md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.2.* + license: 0BSD + purls: [] + size: 106169 + timestamp: 1768752763559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda + sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 + md5: b499ce4b026493a13774bcf0f4c33849 + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.5,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 666600 + timestamp: 1756834976695 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda + sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d + md5: a4b4dd73c67df470d091312ab87bf6ae + depends: + - __osx >=11.0 + - c-ares >=1.34.5,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.2,<4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 575454 + timestamp: 1756835746393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda + sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 + md5: d864d34357c3b65a4b731f78c0801dc4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-only + license_family: GPL + purls: [] + size: 33731 + timestamp: 1750274110928 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda + sha256: 3b3f19ced060013c2dd99d9d46403be6d319d4601814c772a3472fe2955612b0 + md5: 7c7927b404672409d9917d49bff5f2d6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + purls: [] + size: 33418 + timestamp: 1734670021371 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda + sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 + md5: be43915efc66345cccb3c310b6ed0374 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + constrains: + - openblas >=0.3.30,<0.3.31.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5927939 + timestamp: 1763114673331 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda + sha256: ebbbc089b70bcde87c4121a083c724330f02a690fb9d7c6cd18c30f1b12504fa + md5: a6f6d3a31bb29e48d37ce65de54e2df0 + depends: + - __osx >=11.0 + - libgfortran + - libgfortran5 >=14.3.0 + - llvm-openmp >=19.1.7 + constrains: + - openblas >=0.3.30,<0.3.31.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 4284132 + timestamp: 1768547079205 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + sha256: 215086c108d80349e96051ad14131b751d17af3ed2cb5a34edd62fa89bfe8ead + md5: 7df50d44d4a14d6c31a2c54f2cd92157 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + purls: [] + size: 50757 + timestamp: 1731330993524 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda + sha256: 0bd91de9b447a2991e666f284ae8c722ffb1d84acb594dbd0c031bd656fa32b2 + md5: 70e3400cbbfa03e96dcde7fc13e38c7b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 28424 + timestamp: 1749901812541 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda + sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c + md5: 5f13ffc7d30ffec87864e678df9957b4 + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 317669 + timestamp: 1770691470744 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda + sha256: 7a4fd29a6ee2d7f7a6e610754dfdf7410ed08f40d8d8b488a27bc0f9981d5abb + md5: 871dc88b0192ac49b6a5509932c31377 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 288950 + timestamp: 1770691485950 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda + sha256: db23f281fa80597a0dc0445b18318346862602d7081ed76244df8cc4418d6d68 + md5: 43f47a9151b9b8fc100aeefcf350d1a0 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 383155 + timestamp: 1770691504832 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda + sha256: 06a8ace6cc5ee47b85a5e64fad621e5912a12a0202398f54f302eb4e8b9db1fd + md5: a4769024afeab4b32ac8167c2f92c7ac + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=14 + - openldap >=2.6.10,<2.7.0a0 + - openssl >=3.5.4,<4.0a0 + license: PostgreSQL + purls: [] + size: 2649881 + timestamp: 1763565297202 +- conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h97f6797_17.conda + sha256: 1fb8a71bdbc236b8e74f0475887786735d5fa6f5d76d9a4135021279c7ff54b8 + md5: e16e9b1333385c502bf915195f421934 + depends: + - __glibc >=2.17,<3.0.a0 + - geos >=3.13.0,<3.13.1.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 231770 + timestamp: 1727338518657 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-ha2cf0f4_17.conda + sha256: 9ff3162d035a1d9022f6145755a70d0c0ce6c9152792402bc42294354c871a17 + md5: ba729f000ea379b76ed2190119d21e13 + depends: + - __osx >=11.0 + - geos >=3.13.0,<3.13.1.0a0 + - libcxx >=17 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 191064 + timestamp: 1727265842691 +- conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-hd4c2148_17.conda + sha256: 0f4a1c8ed579f96ccb73245b4002d7152a2a8ecd05a01d49901c5d280561f766 + md5: 06ea16b8c60b4ce1970c06191f8639d4 + depends: + - geos >=3.13.0,<3.13.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 404515 + timestamp: 1727265928370 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda + sha256: 0105bd108f19ea8e6a78d2d994a6d4a8db16d19a41212070d2d1d48a63c34161 + md5: a587892d3c13b6621a6091be690dbca2 + depends: + - libgcc-ng >=12 + license: ISC + purls: [] + size: 205978 + timestamp: 1716828628198 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 + sha256: 1d95fe5e5e6a0700669aab454b2a32f97289c9ed8d1f7667c2ba98327a6f05bc + md5: 90859688dbca4735b74c02af14c4c793 + license: ISC + purls: [] + size: 324912 + timestamp: 1605135878892 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.20-hc70643c_0.conda + sha256: 7bcb3edccea30f711b6be9601e083ecf4f435b9407d70fc48fbcf9e5d69a0fc6 + md5: 198bb594f202b205c7d18b936fa4524f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: ISC + purls: [] + size: 202344 + timestamp: 1716828757533 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.1.0-he57a185_0.conda + sha256: 03963a7786b3f53eb36ca3ec10d7a5ddd5265a81e205e28902c53a536cdfd3ad + md5: 2df7aaf3f8a2944885372a62c6f33b20 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: MIT + license_family: MIT + purls: [] + size: 399212 + timestamp: 1734891697797 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.1.0-h57eeb1c_0.conda + sha256: c20c654bc4616c0a1b465adf3131143141aad6ce43c87794d2d5c616c67ff704 + md5: afa1759ccaaebb2c2f0d104b1bd11d06 + depends: + - __osx >=11.0 + - libcxx >=18 + license: MIT + license_family: MIT + purls: [] + size: 295552 + timestamp: 1734891755224 +- conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.1.0-h518811d_0.conda + sha256: c72149515f10219bb1c71c40865b8a73bcaa07e755f13200d278674a987fc097 + md5: 8ca34da29812354d8ea421a1b68897db + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 281126 + timestamp: 1734891956800 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h1b4f908_12.conda + sha256: a9274b30ecc8967fa87959c1978de3b2bfae081b1a8fea7c5a61588041de818f + md5: 641f91ac6f984a91a78ba2411fe4f106 + depends: + - __glibc >=2.17,<3.0.a0 + - freexl >=2 + - freexl >=2.0.0,<3.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - libgcc >=13 + - librttopo >=1.1.0,<1.2.0a0 + - libsqlite >=3.47.2,<4.0a0 + - libstdcxx >=13 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - sqlite + - zlib + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 4033736 + timestamp: 1734001047320 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-hf92fc0a_12.conda + sha256: b11e6169fdbef472c307129192fd46133eec543036e41ab2f957615713b03d19 + md5: f05759528e44f74888830119ab32fc81 + depends: + - __osx >=11.0 + - freexl >=2 + - freexl >=2.0.0,<3.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - libcxx >=18 + - libiconv >=1.17,<2.0a0 + - librttopo >=1.1.0,<1.2.0a0 + - libsqlite >=3.47.2,<4.0a0 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - sqlite + - zlib + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 2943606 + timestamp: 1734001158789 +- conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-h939089a_12.conda + sha256: fafedc5940e49b3dcce2cd6dfe3cabf64e7cc6b2a0ef7c8fefbf9d6d2c1afb77 + md5: 8b5bfc6caa7c652ec4ec755efb5b7b73 + depends: + - freexl >=2 + - freexl >=2.0.0,<3.0a0 + - geos >=3.13.0,<3.13.1.0a0 + - librttopo >=1.1.0,<1.2.0a0 + - libsqlite >=3.47.2,<4.0a0 + - libxml2 >=2.13.5,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - proj >=9.5.1,<9.6.0a0 + - sqlite + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zlib + license: MPL-1.1 + license_family: MOZILLA + purls: [] + size: 8715367 + timestamp: 1734001064515 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda + sha256: c1ff4589b48d32ca0a2628970d869fa9f7b2c2d00269a3761edc7e9e4c1ab7b8 + md5: f7d30045eccb83f2bb8053041f42db3c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: blessing + purls: [] + size: 939312 + timestamp: 1768147967568 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1b79a29_0.conda + sha256: f942afee5568a0bfba020e52c3f22b788e14017a8dc302652d2ca500756a8a5a + md5: faedef456ba5004af365d450eb38217d + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: blessing + purls: [] + size: 905482 + timestamp: 1768148270069 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda + sha256: 756478128e3e104bd7e7c3ce6c1b0efad7e08c7320c69fdc726e039323c63fbb + md5: 903979414b47d777d548e5f0165e6cd8 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1291616 + timestamp: 1768148278261 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 + md5: eecce068c7e4eddeb169591baac20ac4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 304790 + timestamp: 1745608545575 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a + md5: b68e8f66b94b44aaa8de4583d3d4cc40 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 279193 + timestamp: 1745608793272 +- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 + md5: 9dce2f112bfd3400f4f432b3d0ac07b2 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 292785 + timestamp: 1745608759342 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e + md5: 1b08cd684f34175e4514474793d44bcb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_18 + constrains: + - libstdcxx-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 5852330 + timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda + sha256: 3c902ffd673cb3c6ddde624cdb80f870b6c835f8bf28384b0016e7d444dd0145 + md5: 6235adb93d064ecdf3d44faee6f468de + depends: + - libstdcxx 15.2.0 h934c35e_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27575 + timestamp: 1771378314494 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda + sha256: 7480613af15795281bd338a4d3d2ca148f9c2ecafc967b9cc233e78ba2fe4a6d + md5: 6c1028898cf3a2032d9af46689e1b81a + depends: + - __glibc >=2.17,<3.0.a0 + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.23,<1.24.0a0 + - libgcc >=13 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=13 + - libwebp-base >=1.5.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + purls: [] + size: 429381 + timestamp: 1745372713285 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h551f018_4.conda + sha256: 5d3f7a71b70f0d88470eda8e7b6afe3095d66708a70fb912e79d56fc30b35429 + md5: 717e02c4cca2a760438384d48b7cd1b9 + depends: + - __osx >=11.0 + - lerc >=4.0.0,<5.0a0 + - libcxx >=18 + - libdeflate >=1.23,<1.24.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + purls: [] + size: 370898 + timestamp: 1745372834516 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda + sha256: 3456e2a6dfe6c00fd0cda316f0cbb47caddf77f83d3ed4040b6ad17ec1610d2a + md5: 7d938ca70c64c5516767b4eae0a56172 + depends: + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.23,<1.24.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + purls: [] + size: 980597 + timestamp: 1745373037447 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee + md5: db409b7c1720428638e7c0d509d3e1b5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 40311 + timestamp: 1766271528534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b + md5: aea31d2e5b1091feca96fcfe945c3cf9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 429011 + timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda + sha256: a4de3f371bb7ada325e1f27a4ef7bcc81b2b6a330e46fac9c2f78ac0755ea3dd + md5: e5e7d467f80da752be17796b87fe6385 + depends: + - __osx >=11.0 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 294974 + timestamp: 1752159906788 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + sha256: 7b6316abfea1007e100922760e9b8c820d6fc19df3f42fb5aca684cfacb31843 + md5: f9bbae5e2537e3b06e0f7310ba76c893 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 279176 + timestamp: 1752159543911 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0 + md5: 8a86073cf3b343b87d03f41790d8b4e5 + depends: + - ucrt + constrains: + - pthreads-win32 <0.0a0 + - msys2-conda-epoch <0.0a0 + license: MIT AND BSD-3-Clause-Clear + purls: [] + size: 36621 + timestamp: 1759768399557 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa + md5: 92ed62436b625154323d40d5f2f11dd7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - pthread-stubs + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + purls: [] + size: 395888 + timestamp: 1727278577118 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda + sha256: bd3816218924b1e43b275863e21a3e13a5db4a6da74cca8e60bc3c213eb62f71 + md5: af523aae2eca6dfa1c8eec693f5b9a79 + depends: + - __osx >=11.0 + - pthread-stubs + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + purls: [] + size: 323658 + timestamp: 1727278733917 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + sha256: 08dec73df0e161c96765468847298a420933a36bc4f09b50e062df8793290737 + md5: a69bbf778a462da324489976c84cfc8c + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - pthread-stubs + - ucrt >=10.0.20348.0 + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + purls: [] + size: 1208687 + timestamp: 1727279378819 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc + depends: + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda + sha256: 23f47e86cc1386e7f815fa9662ccedae151471862e971ea511c5c886aa723a54 + md5: 74e91c36d0eef3557915c68b6c2bef96 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxcb >=1.17.0,<2.0a0 + - libxml2 >=2.13.8,<2.14.0a0 + - xkeyboard-config + - xorg-libxau >=1.0.12,<2.0a0 + license: MIT/X11 Derivative + license_family: MIT + purls: [] + size: 791328 + timestamp: 1754703902365 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda + sha256: 5d12e993894cb8e9f209e2e6bef9c90fa2b7a339a1f2ab133014b71db81f5d88 + md5: 35eeb0a2add53b1e50218ed230fa6a02 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=75.1,<76.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 697033 + timestamp: 1761766011241 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.9-h4a9ca0c_0.conda + sha256: 7ab9b3033f29ac262cd3c846887e5b512f5916c3074d10f298627d67b7a32334 + md5: 763c7e76295bf142145d5821f251b884 + depends: + - __osx >=11.0 + - icu >=75.1,<76.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 581379 + timestamp: 1761766437117 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.9-h741aa76_0.conda + sha256: 28ac5bbed11644b9e06241ba1dfdac7e3a99e74b69915d45f646717ad9645ca5 + md5: 333d21ab129d5fa5742225bf1d7557a5 + depends: + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 1521446 + timestamp: 1761766307746 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda + sha256: 35ddfc0335a18677dd70995fa99b8f594da3beb05c11289c87b6de5b930b47a3 + md5: 31059dc620fa57d787e3899ed0421e6d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libxml2 >=2.13.8,<2.14.0a0 + license: MIT + license_family: MIT + purls: [] + size: 244399 + timestamp: 1753273455036 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h25c3957_0.conda + sha256: 20857f1adb91cc59826e146ee6cb1157c6abf2901a93d359b1106ba87c8e770b + md5: e84f36aa02735c140099d992d491968d + depends: + - libxml2 >=2.13.8,<2.14.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 416974 + timestamp: 1753273998632 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 + md5: edb0dca6bc32e4f4789199455a1dbeb8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + purls: [] + size: 60963 + timestamp: 1727963148474 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b + md5: 369964e85dc26bfe78f41399b366c435 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + purls: [] + size: 46438 + timestamp: 1727963202283 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402 + md5: 41fbfac52c601159df6c01f875de31b9 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - zlib 1.3.1 *_2 + license: Zlib + license_family: Other + purls: [] + size: 55476 + timestamp: 1727963768015 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda + sha256: 56bcd20a0a44ddd143b6ce605700fdf876bcf5c509adc50bf27e76673407a070 + md5: 206ad2df1b5550526e386087bef543c7 + depends: + - __osx >=11.0 + constrains: + - openmp 21.1.8|21.1.8.* + - intel-openmp <0.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 285974 + timestamp: 1765964756583 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.8-h4fa8253_0.conda + sha256: 145c4370abe870f10987efa9fc15a8383f1dab09abbc9ad4ff15a55d45658f7b + md5: 0d8b425ac862bcf17e4b28802c9351cb + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - intel-openmp <0.0a0 + - openmp 21.1.8|21.1.8.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 347566 + timestamp: 1765964942856 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda + sha256: 47326f811392a5fd3055f0f773036c392d26fdb32e4d8e7a8197eed951489346 + md5: 9de5350a85c4a20c685259b889aa6393 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 167055 + timestamp: 1733741040117 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda + sha256: 94d3e2a485dab8bdfdd4837880bde3dd0d701e2b97d6134b8806b7c8e69c8652 + md5: 01511afc6cc1909c5303cf31be17b44f + depends: + - __osx >=11.0 + - libcxx >=18 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 148824 + timestamp: 1733741047892 +- conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda + sha256: 632cf3bdaf7a7aeb846de310b6044d90917728c73c77f138f08aa9438fc4d6b5 + md5: 0b69331897a92fac3d8923549d48d092 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 139891 + timestamp: 1733741168264 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda + sha256: 5c6bbeec116e29f08e3dad3d0524e9bc5527098e12fc432c0e5ca53ea16337d4 + md5: 45161d96307e3a447cc3eb5896cf6f8c + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 191060 + timestamp: 1753889274283 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda + sha256: db40fd25c6306bfda469f84cddd8b5ebb9aa08d509cecb49dfd0bb8228466d0c + md5: e56eaa1beab0e7fed559ae9c0264dd88 + depends: + - __osx >=11.0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 152755 + timestamp: 1753889267953 +- conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda + sha256: 344f4f225c6dfb523fb477995545542224c37a5c86161f053a1a18fe547aa979 + md5: c5cb4159f0eea65663b31dd1e49bbb71 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 165589 + timestamp: 1753889311940 +- conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda + sha256: c498a016b233be5a7defee443733a82d5fe41b83016ca8a136876a64fd15564b + md5: c48bbb2bcc3f9f46741a7915d67e6839 + depends: + - networkx >=2.7 + - numpy >=1.23 + - pandas >=1.4,!=1.5.0 + - python >=3.9 + - scikit-learn >=1.0 + - scipy >=1.8 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/mapclassify?source=hash-mapping + size: 56772 + timestamp: 1733731193211 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py310h3406613_0.conda + sha256: b3894b37cab530d1adab5b9ce39a1b9f28040403cc0042b77e04a2f227a447de + md5: 8854df4fb4e37cc3ea0a024e48c9c180 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 23673 + timestamp: 1759055396627 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py310hf4fd40f_0.conda + sha256: fe90edbce0137081fb6f7c14ef56b9954628abb6f52882011f8cd5d44425fc37 + md5: cd0fbf3b6ffdda2958e4b720f03429ba + depends: + - __osx >=11.0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 23707 + timestamp: 1759055558733 +- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py310hdb0e946_0.conda + sha256: 87203ea8bbe265ebabb16673c9442d2097e1b405dc70df49d6920730e7be6e74 + md5: 1fdd2255424eaf0d5e707c205ace2c30 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jinja2 >=3.0.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/markupsafe?source=hash-mapping + size: 26586 + timestamp: 1759055463355 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py310hff52083_0.conda + sha256: 6d087ae3f42e5a53f648a874629b561e8ec34416f6a258837ca0af405550defe + md5: e78bcae4f58d0000f756c3b42da20f13 + depends: + - matplotlib-base >=3.10.8,<3.10.9.0a0 + - pyside6 >=6.7.2 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 17450 + timestamp: 1763055406857 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py310hb6292c7_0.conda + sha256: e19c56288ea1b729089d28614200e8613cdf5107367636736d0d0bf06c750e72 + md5: 33dca3f48bc5d4427238f4f214574f40 + depends: + - matplotlib-base >=3.10.8,<3.10.9.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 17596 + timestamp: 1763055909786 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py310h5588dad_0.conda + sha256: 277b0e73a023978311fff8976b6b92e529b13dc9d4487414e12695f5ee0d8555 + md5: 178a19a3e53ec4d213f1193c34e92500 + depends: + - matplotlib-base >=3.10.8,<3.10.9.0a0 + - pyside6 >=6.7.2 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + purls: [] + size: 17874 + timestamp: 1763055525619 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py310hfde16b3_0.conda + sha256: 809eaf93eb1901764c9b75803794c0359dd09366f578a13fdbbbe99824920d2c + md5: 093b60a14d2c0d8c10f17e14a73a60d3 + depends: + - __glibc >=2.17,<3.0.a0 + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libgcc >=14 + - libstdcxx >=14 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.10,<3.11.0a0 + - python-dateutil >=2.7 + - python_abi 3.10.* *_cp310 + - qhull >=2020.2,<2020.3.0a0 + - tk >=8.6.13,<8.7.0a0 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/matplotlib?source=hash-mapping + size: 7273307 + timestamp: 1763055380888 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py310h0181960_0.conda + sha256: 397a75557d684e4030fcbee1a2adc6669036dd0525d64d6e5c060a5dff7ba027 + md5: f7be8dab2ed23302da20d4c96345eb15 + depends: + - __osx >=11.0 + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libcxx >=19 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python-dateutil >=2.7 + - python_abi 3.10.* *_cp310 + - qhull >=2020.2,<2020.3.0a0 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/matplotlib?source=hash-mapping + size: 7123730 + timestamp: 1763055863073 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py310h0bdd906_0.conda + sha256: 97bf5dcb9c38031ff55fa8b92c872a49938e264b0670d1889118eaca72de4b9e + md5: 13072a2da6b67737ad24e22041f68ef5 + depends: + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.10,<3.11.0a0 + - python-dateutil >=2.7 + - python_abi 3.10.* *_cp310 + - qhull >=2020.2,<2020.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/matplotlib?source=hash-mapping + size: 7166182 + timestamp: 1763055495695 +- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda + sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 + md5: 00e120ce3e40bad7bfc78861ce3c4a25 + depends: + - python >=3.10 + - traitlets + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/matplotlib-inline?source=hash-mapping + size: 15175 + timestamp: 1761214578417 +- conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.10-h05a5f5f_0.conda + sha256: 0c3700d15377156937ddc89a856527ad77e7cf3fd73cb0dffc75fce8030ddd16 + md5: da01bb40572e689bd1535a5cee6b1d68 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=13 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Zlib + license_family: Other + purls: [] + size: 93471 + timestamp: 1746450475308 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.10-hff1a8ea_0.conda + sha256: b3503bd3da5d48d57b44835f423951f487574e08a999f13288c81464ac293840 + md5: 93def148863d840e500490d6d78722f9 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcxx >=18 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Zlib + license_family: Other + purls: [] + size: 78411 + timestamp: 1746450560057 +- conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.10-h9fa1bad_0.conda + sha256: feacd3657c60ef0758228fc93d46cedb45ac1b1d151cb09780a4d6c4b8b32543 + md5: 2ffdc180adc65f509e996d63513c04b7 + depends: + - bzip2 >=1.0.8,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.7,<1.6.0a0 + license: Zlib + license_family: Other + purls: [] + size: 86618 + timestamp: 1746450788037 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda + sha256: b2b4c84b95210760e4d12319416c60ab66e03674ccdcbd14aeb59f82ebb1318d + md5: fd05d1e894497b012d05a804232254ed + depends: + - llvm-openmp >=21.1.8 + - tbb >=2022.3.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + size: 100224829 + timestamp: 1767634557029 +- conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda + sha256: d09c47c2cf456de5c09fa66d2c3c5035aa1fa228a1983a433c47b876aa16ce90 + md5: 37293a85a0f4f77bbd9cf7aaefc62609 + depends: + - python >=3.9 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/munkres?source=hash-mapping + size: 15851 + timestamp: 1749895533014 +- pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl + name: nbformat + version: 5.10.4 + sha256: 3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b + requires_dist: + - fastjsonschema>=2.15 + - jsonschema>=2.6 + - jupyter-core>=4.12,!=5.0.* + - traitlets>=5.1 + - myst-parser ; extra == 'docs' + - pydata-sphinx-theme ; extra == 'docs' + - sphinx ; extra == 'docs' + - sphinxcontrib-github-alt ; extra == 'docs' + - sphinxcontrib-spelling ; extra == 'docs' + - pep440 ; extra == 'test' + - pre-commit ; extra == 'test' + - pytest ; extra == 'test' + - testpath ; extra == 'test' + requires_python: '>=3.8' +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 + md5: 47e340acb35de30501a76c7c799c41d7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: X11 AND BSD-3-Clause + purls: [] + size: 891641 + timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 + md5: 068d497125e4bf8a66bf707254fff5ae + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + purls: [] + size: 797030 + timestamp: 1738196177597 +- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda + sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 + md5: 598fd7d4d0de2455fb74f56063969a97 + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/nest-asyncio?source=hash-mapping + size: 11543 + timestamp: 1733325673691 +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda + sha256: 39625cd0c9747fa5c46a9a90683b8997d8b9649881b3dc88336b13b7bdd60117 + md5: fd40bf7f7f4bc4b647dc8512053d9873 + depends: + - python >=3.10 + - python + constrains: + - numpy >=1.24 + - scipy >=1.10,!=1.11.0,!=1.11.1 + - matplotlib >=3.7 + - pandas >=2.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/networkx?source=hash-mapping + size: 1265008 + timestamp: 1731521053408 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda + sha256: 0ba94a61f91d67413e60fa8daa85627a8f299b5054b0eff8f93d26da83ec755e + md5: b0cea2c364bf65cd19e023040eeab05d + depends: + - __glibc >=2.17,<3.0.a0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc >=13 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx >=13 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 7893263 + timestamp: 1747545075833 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.2.6-py310h4d83441_0.conda + sha256: 87704bcd5f4a4f88eaf2a97f07e9825803b58a8003a209b91e89669317523faf + md5: f4bd8ac423d04b3c444b96f2463d3519 + depends: + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=18 + - liblapack >=3.9.0,<4.0a0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 5841650 + timestamp: 1747545043441 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda + sha256: 6f628e51763b86a535a723664e3aa1e38cb7147a2697f80b75c1980c1ed52f3e + md5: d2596785ac2cf5bab04e2ee9e5d04041 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 6596153 + timestamp: 1747545352390 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda + sha256: 0b7396dacf988f0b859798711b26b6bc9c6161dca21bacfd778473da58730afa + md5: 01243c4aaf71bde0297966125aea4706 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpng >=1.6.50,<1.7.0a0 + - libstdcxx >=14 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 357828 + timestamp: 1754297886899 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda + sha256: 6013916893fcd9bc97c479279cfe4616de7735ec566bad0ee41bc729e14d31b2 + md5: ab581998c77c512d455a13befcddaac3 + depends: + - __osx >=11.0 + - libcxx >=19 + - libpng >=1.6.50,<1.7.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 320198 + timestamp: 1754297986425 +- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h24db6dd_1.conda + sha256: c29cb1641bc5cfc2197e9b7b436f34142be4766dd2430a937b48b7474935aa55 + md5: 25f45acb1a234ad1c9b9a20e1e6c559e + depends: + - libpng >=1.6.50,<1.7.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 245076 + timestamp: 1754298075628 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda + sha256: cb0b07db15e303e6f0a19646807715d28f1264c6350309a559702f4f34f37892 + md5: 2e5bf4f1da39c0b32778561c3c4e5878 + depends: + - __glibc >=2.17,<3.0.a0 + - cyrus-sasl >=2.1.27,<3.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - libstdcxx >=13 + - openssl >=3.5.0,<4.0a0 + license: OLDAP-2.8 + license_family: BSD + purls: [] + size: 780253 + timestamp: 1748010165522 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c + md5: f61eb8cd60ff9057122a3d338b99c00f + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3164551 + timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 + md5: f4f6ad63f98f64191c3e77c5f5f29d76 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3104268 + timestamp: 1769556384749 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 + md5: eb585509b815415bc964b2c7e11c7eb3 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 9343023 + timestamp: 1769557547888 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda + sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 + md5: b76541e68fea4d511b1ac46a28dcd2c6 + depends: + - python >=3.8 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/packaging?source=compressed-mapping + size: 72010 + timestamp: 1769093650580 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda + sha256: 43fd80e57ebc9e0c00d169aafce533c49359174dea327a7fa8ca7454628a56f7 + md5: 07697a584fab513ce895c4511f7a2403 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.10,<3.11.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.10.* *_cp310 + - pytz >=2020.1 + constrains: + - tabulate >=0.9.0 + - psycopg2 >=2.9.6 + - pyarrow >=10.0.1 + - numba >=0.56.4 + - xlsxwriter >=3.0.5 + - qtpy >=2.3.0 + - fastparquet >=2022.12.0 + - scipy >=1.10.0 + - sqlalchemy >=2.0.0 + - openpyxl >=3.1.0 + - html5lib >=1.1 + - s3fs >=2022.11.0 + - lxml >=4.9.2 + - odfpy >=1.4.1 + - pandas-gbq >=0.19.0 + - pytables >=3.8.0 + - fsspec >=2022.11.0 + - gcsfs >=2022.11.0 + - bottleneck >=1.3.6 + - zstandard >=0.19.0 + - pyxlsb >=1.0.10 + - xarray >=2022.12.0 + - pyreadstat >=1.2.0 + - python-calamine >=0.1.7 + - beautifulsoup4 >=4.11.2 + - xlrd >=2.0.1 + - tzdata >=2022.7 + - numexpr >=2.8.4 + - matplotlib >=3.6.3 + - blosc >=1.21.3 + - pyqt5 >=5.15.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 13029755 + timestamp: 1744430958318 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py310h5936506_3.conda + sha256: d6999d5bcebe1837b26d324b6a440b70a23f3e744e9a176fc9c00fc2408c95e7 + md5: ac8e350fb40fcc86b1554ec20af922d0 + depends: + - __osx >=11.0 + - libcxx >=18 + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.10.* *_cp310 + - pytz >=2020.1 + constrains: + - openpyxl >=3.1.0 + - tzdata >=2022.7 + - tabulate >=0.9.0 + - pyxlsb >=1.0.10 + - pyqt5 >=5.15.9 + - pyreadstat >=1.2.0 + - pandas-gbq >=0.19.0 + - qtpy >=2.3.0 + - scipy >=1.10.0 + - pytables >=3.8.0 + - lxml >=4.9.2 + - numba >=0.56.4 + - odfpy >=1.4.1 + - numexpr >=2.8.4 + - xlrd >=2.0.1 + - fsspec >=2022.11.0 + - html5lib >=1.1 + - xarray >=2022.12.0 + - pyarrow >=10.0.1 + - xlsxwriter >=3.0.5 + - s3fs >=2022.11.0 + - bottleneck >=1.3.6 + - beautifulsoup4 >=4.11.2 + - blosc >=1.21.3 + - matplotlib >=3.6.3 + - psycopg2 >=2.9.6 + - zstandard >=0.19.0 + - gcsfs >=2022.11.0 + - sqlalchemy >=2.0.0 + - fastparquet >=2022.12.0 + - python-calamine >=0.1.7 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 12046934 + timestamp: 1744430939366 +- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py310hb4db72f_3.conda + sha256: fa3986017273899fd21aa14a524469bedac3923e2ecfdfdba59a34769b56b9b8 + md5: 60c6ae5813eb1cbc4f7774fb69623db8 + depends: + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.10,<3.11.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.10.* *_cp310 + - pytz >=2020.1 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - scipy >=1.10.0 + - pyarrow >=10.0.1 + - python-calamine >=0.1.7 + - xlsxwriter >=3.0.5 + - openpyxl >=3.1.0 + - numexpr >=2.8.4 + - matplotlib >=3.6.3 + - fsspec >=2022.11.0 + - lxml >=4.9.2 + - html5lib >=1.1 + - s3fs >=2022.11.0 + - bottleneck >=1.3.6 + - blosc >=1.21.3 + - gcsfs >=2022.11.0 + - pyqt5 >=5.15.9 + - pyreadstat >=1.2.0 + - sqlalchemy >=2.0.0 + - qtpy >=2.3.0 + - odfpy >=1.4.1 + - tabulate >=0.9.0 + - pyxlsb >=1.0.10 + - tzdata >=2022.7 + - xarray >=2022.12.0 + - zstandard >=0.19.0 + - beautifulsoup4 >=4.11.2 + - xlrd >=2.0.1 + - pandas-gbq >=0.19.0 + - psycopg2 >=2.9.6 + - numba >=0.56.4 + - fastparquet >=2022.12.0 + - pytables >=3.8.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 11917543 + timestamp: 1744431481619 +- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda + sha256: 42b2d77ccea60752f3aa929a6413a7835aaacdbbde679f2f5870a744fa836b94 + md5: 97c1ce2fffa1209e7afb432810ec6e12 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/parso?source=compressed-mapping + size: 82287 + timestamp: 1770676243987 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda + sha256: 09717569649d89caafbf32f6cda1e65aef86e5a86c053d30e4ce77fca8d27b68 + md5: 31614c73d7b103ef76faa4d83d261d34 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 956207 + timestamp: 1745931215744 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.44-ha881caa_2.conda + sha256: 797411a2d748c11374b84329002f3c65db032cbf012b20d9b14dba9b6ac52d06 + md5: 1a3f7708de0b393e6665c9f7494b055e + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 621564 + timestamp: 1745931340774 +- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda + sha256: 15dffc9a2d6bb6b8ccaa7cbd26b229d24f1a0a1c4f5685b308a63929c56b381f + md5: a912b2c4ff0f03101c751aa79a331831 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 816653 + timestamp: 1745931851696 +- conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda + sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a + md5: d0d408b1f18883a944376da5cf8101ea + depends: + - ptyprocess >=0.5 + - python >=3.9 + license: ISC + purls: + - pkg:pypi/pexpect?source=hash-mapping + size: 53561 + timestamp: 1733302019362 +- conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda + sha256: e2ac3d66c367dada209fc6da43e645672364b9fd5f9d28b9f016e24b81af475b + md5: 11a9d1d09a3615fc07c3faf79bc0b943 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pickleshare?source=hash-mapping + size: 11748 + timestamp: 1733327448200 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.3.0-py310h6557065_3.conda + sha256: 7fe27fd1c5a3d85ea355a609d050e50469382223bbf5a07ca750e30b6aebdc25 + md5: e169733dc0c743687a852f1c6e989140 + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - python_abi 3.10.* *_cp310 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - lcms2 >=2.17,<3.0a0 + - tk >=8.6.13,<8.7.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - openjpeg >=2.5.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + license: HPND + purls: + - pkg:pypi/pillow?source=hash-mapping + size: 882171 + timestamp: 1758208668856 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-11.3.0-py310h5de80a5_3.conda + sha256: f81e77e125c7be7a368aa807784bdb8fe15f26c0b3944560e34a5a8c56acf8e0 + md5: 289f10aa08eeb9a44e62fdc5c9810a7a + depends: + - python + - python 3.10.* *_cpython + - __osx >=11.0 + - libwebp-base >=1.6.0,<2.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - lcms2 >=2.17,<3.0a0 + - openjpeg >=2.5.3,<3.0a0 + - python_abi 3.10.* *_cp310 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libjpeg-turbo >=3.1.0,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + license: HPND + purls: + - pkg:pypi/pillow?source=hash-mapping + size: 803755 + timestamp: 1758208741246 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.3.0-py310hb3a2f59_3.conda + sha256: d4825cfe13dc10bb90553c663b86128c8e53bb8c3eda768f7d0d29c3ad878a92 + md5: a12291a9a7acce46716c518c31ebb298 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - tk >=8.6.13,<8.7.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libzlib >=1.3.1,<2.0a0 + - openjpeg >=2.5.3,<3.0a0 + - libxcb >=1.17.0,<2.0a0 + - lcms2 >=2.17,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - python_abi 3.10.* *_cp310 + license: HPND + purls: + - pkg:pypi/pillow?source=hash-mapping + size: 786227 + timestamp: 1758208682963 +- conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda + sha256: 585940f09d87787f79f73ff5dff8eb2af8a67e5bec5eebf2f553cd26c840ba69 + md5: 79b5c1440aedc5010f687048d9103628 + depends: + - python >=3.9,<3.13.0a0 + - setuptools + - wheel + license: MIT + license_family: MIT + purls: + - pkg:pypi/pip?source=hash-mapping + size: 1256460 + timestamp: 1739142857253 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + sha256: 43d37bc9ca3b257c5dd7bf76a8426addbdec381f6786ff441dc90b1a49143b6a + md5: c01af13bdc553d1a8fbfff6e8db075f0 + depends: + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + purls: [] + size: 450960 + timestamp: 1754665235234 +- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda + sha256: 246fce4706b3f8b247a7d6142ba8d732c95263d3c96e212b9d63d6a4ab4aff35 + md5: 08c8fa3b419df480d985e304f7884d35 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 542795 + timestamp: 1754665193489 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda + sha256: 7f263219cecf0ba6d74c751efa60c4676ce823157ca90aa43ebba5ac615ca0fa + md5: 4fefefb892ce9cc1539405bec2f1a6cd + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/platformdirs?source=compressed-mapping + size: 25643 + timestamp: 1771233827084 +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda + sha256: d1bbf2d80105bfc8a7ed9817888f4a1686ed393d6435572921add09cc9347c1c + md5: 71ac632876630091c81c50a05ec5e030 + depends: + - packaging + - python >=3.9 + - tenacity >=6.2.0 + constrains: + - ipywidgets >=7.6 + license: MIT + license_family: MIT + purls: + - pkg:pypi/plotly?source=hash-mapping + size: 8022748 + timestamp: 1733733328161 +- conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.5.1-h0054346_0.conda + sha256: 835afb9c8198895ec1ce2916320503d47bb0c25b75c228d744c44e505f1f4e3b + md5: 398cabfd9bd75e90d0901db95224f25f + depends: + - __glibc >=2.17,<3.0.a0 + - libcurl >=8.10.1,<9.0a0 + - libgcc >=13 + - libsqlite >=3.47.0,<4.0a0 + - libstdcxx >=13 + - libtiff >=4.7.0,<4.8.0a0 + - sqlite + constrains: + - proj4 ==999999999999 + license: MIT + license_family: MIT + purls: [] + size: 3108751 + timestamp: 1733138115896 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.5.1-h1318a7e_0.conda + sha256: c6289d6f1a13f28ff3754ac0cb2553f7e7bc4a3102291115f62a04995d0421eb + md5: 5eb42e77ae79b46fabcb0f6f6d130763 + depends: + - __osx >=11.0 + - libcurl >=8.10.1,<9.0a0 + - libcxx >=18 + - libsqlite >=3.47.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - sqlite + constrains: + - proj4 ==999999999999 + license: MIT + license_family: MIT + purls: [] + size: 2673401 + timestamp: 1733138376056 +- conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.5.1-h4f671f6_0.conda + sha256: ddd0be6172e3903bc6602a93394e8051826235377c1ce8c6ba2435869794e726 + md5: 7303dac2aa92318f319508aedab6a127 + depends: + - libcurl >=8.10.1,<9.0a0 + - libsqlite >=3.47.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - sqlite + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - proj4 ==999999999999 + license: MIT + license_family: MIT + purls: [] + size: 2740461 + timestamp: 1733138695290 +- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda + sha256: 4817651a276016f3838957bfdf963386438c70761e9faec7749d411635979bae + md5: edb16f14d920fb3faf17f5ce582942d6 + depends: + - python >=3.10 + - wcwidth + constrains: + - prompt_toolkit 3.0.52 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/prompt-toolkit?source=hash-mapping + size: 273927 + timestamp: 1756321848365 +- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py310h139afa4_0.conda + sha256: 3a6d46033ebad3e69ded3f76852b9c378c2cff632f57421b5926c6add1bae475 + md5: d210342acdb8e3ca6434295497c10b7c + depends: + - python + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 179015 + timestamp: 1769678154886 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py310haea493c_0.conda + sha256: f2336814f97e23cec0c6b082afecc2e9ec5941fce19f08d453e8ea53221c82ef + md5: 8c73aa05dd807bb9b1cdc0e028ab4f13 + depends: + - python + - python 3.10.* *_cpython + - __osx >=11.0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 192483 + timestamp: 1769678341407 +- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py310h1637853_0.conda + sha256: 71b14cfddc05c0d8c22e2e15103a29ce404ea346e328c7bca5fd1ad682f7f274 + md5: 97d88bac43c17c12d0b266f523a37f61 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/psutil?source=hash-mapping + size: 196390 + timestamp: 1769678167722 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 + md5: b3c17d95b5a10c6e64a21fa17573e70e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 8252 + timestamp: 1726802366959 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda + sha256: 8ed65e17fbb0ca944bfb8093b60086e3f9dd678c3448b5de212017394c247ee3 + md5: 415816daf82e0b23a736a069a75e9da7 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 8381 + timestamp: 1726802424786 +- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + sha256: 7e446bafb4d692792310ed022fe284e848c6a868c861655a92435af7368bae7b + md5: 3c8f2573569bb816483e5cf57efbbe29 + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 9389 + timestamp: 1726802555076 +- conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda + sha256: a7713dfe30faf17508ec359e0bc7e0983f5d94682492469bd462cdaae9c64d83 + md5: 7d9daffbb8d8e0af0f769dbbcd173a54 + depends: + - python >=3.9 + license: ISC + purls: + - pkg:pypi/ptyprocess?source=hash-mapping + size: 19457 + timestamp: 1733302371990 +- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda + sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 + md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pure-eval?source=hash-mapping + size: 16668 + timestamp: 1733569518868 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda + sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a + md5: 6b6ece66ebcae2d5f326c77ef2c5a066 + depends: + - python >=3.9 + license: BSD-2-Clause + license_family: BSD + purls: + - pkg:pypi/pygments?source=hash-mapping + size: 889287 + timestamp: 1750615908735 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyogrio-0.10.0-py310h0aed7a2_1.conda + sha256: e7e66bac7ffbbd10a2abef7cea842bb7629adbf6d8b73dcc40079473d3aed77f + md5: 95459fb36d2c19b491361f0a2b6feaf1 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libgdal-core >=3.10.0,<3.11.0a0 + - libstdcxx >=13 + - numpy + - packaging + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyogrio?source=hash-mapping + size: 610091 + timestamp: 1732013579548 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyogrio-0.10.0-py310hd68230c_1.conda + sha256: 1cb31811cc2bb1c5abfe03ecfc1ac1e0b9a1cab6dc69e51f072d2dd22451b2fb + md5: f630c4fe976af207f90a03012114c479 + depends: + - __osx >=11.0 + - libcxx >=18 + - libgdal-core >=3.10.0,<3.11.0a0 + - numpy + - packaging + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyogrio?source=hash-mapping + size: 534901 + timestamp: 1732013619674 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyogrio-0.10.0-py310hf80745b_1.conda + sha256: da7913ee9f0d6843e5605aa779c5dc2ebc08eb69c817db7e9d3068a3a672bda9 + md5: a5c256a8a898c1f84dcd450a27887f8c + depends: + - libgdal-core >=3.10.0,<3.11.0a0 + - numpy + - packaging + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyogrio?source=hash-mapping + size: 780156 + timestamp: 1732013834 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda + sha256: 417fba4783e528ee732afa82999300859b065dc59927344b4859c64aae7182de + md5: 3687cc0b82a8b4c17e1f0eb7e47163d5 + depends: + - python >=3.10 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyparsing?source=compressed-mapping + size: 110893 + timestamp: 1769003998136 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.7.0-py310h2e9f774_0.conda + sha256: 16a69974015cdcacef2a82d3efcf30dcd556d2dbdf3deab7641495b78625c1af + md5: 42a3ea3c283d930ae6d156b97ffe4740 + depends: + - __glibc >=2.17,<3.0.a0 + - certifi + - libgcc >=13 + - proj >=9.5.0,<9.6.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyproj?source=hash-mapping + size: 536119 + timestamp: 1727795517990 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyproj-3.7.0-py310h861c57f_0.conda + sha256: bd81295fcc04c569fcfbf9d8cef744687ee9a5940716b06f363c7a331d73025e + md5: fcc2303072c38beb8dbdc6fc9211950e + depends: + - __osx >=11.0 + - certifi + - proj >=9.5.0,<9.6.0a0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyproj?source=hash-mapping + size: 474993 + timestamp: 1727795735537 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyproj-3.7.0-py310h19d4cff_0.conda + sha256: 3b9b1a447efa082f47633c6af6887979ebe68f880ec226f60952e199e47804f6 + md5: aec37353830fb374109d3d7e6347cbcd + depends: + - certifi + - proj >=9.5.0,<9.6.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyproj?source=hash-mapping + size: 733814 + timestamp: 1727795859575 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py310hfd10a26_0.conda + sha256: 545ee500ea1dcb8836934b3af0bad4b9f702f03e2f931f4d133d859380058722 + md5: 1610ccfe262ee519716bb69bd4395572 + depends: + - __glibc >=2.17,<3.0.a0 + - libclang13 >=20.1.2 + - libegl >=1.7.0,<2.0a0 + - libgcc >=13 + - libgl >=1.7.0,<2.0a0 + - libopengl >=1.7.0,<2.0a0 + - libstdcxx >=13 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + license: LGPL-3.0-only + license_family: LGPL + purls: + - pkg:pypi/pyside6?source=hash-mapping + - pkg:pypi/shiboken6?source=hash-mapping + size: 10032602 + timestamp: 1743760684455 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py310hc1b6536_0.conda + sha256: 5308c1032c681e3ad61b26c27d3c0f1f911ba52c2f63f2285b3c489d09cc53ed + md5: e90c8d8a817b5d63b7785d7d18c99ae0 + depends: + - libclang13 >=20.1.2 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 + license: LGPL-3.0-only + license_family: LGPL + purls: + - pkg:pypi/pyside6?source=hash-mapping + - pkg:pypi/shiboken6?source=hash-mapping + size: 8784423 + timestamp: 1743761558911 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda + sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca + md5: e2fd202833c4a981ce8a65974fe4abd1 + depends: + - __win + - python >=3.9 + - win_inet_pton + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21784 + timestamp: 1733217448189 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda + sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 + md5: 461219d1a5bd61342293efa2c0c90eac + depends: + - __unix + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pysocks?source=hash-mapping + size: 21085 + timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda + build_number: 3 + sha256: 2d8b5566d82c3872f057661e056d696f2f77a17ee5a36d9ae6ec43052c4d1c51 + md5: be48679ccfbc8710dea1d5970600fa04 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.4,<4.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libnsl >=2.0.1,<2.1.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libxcrypt >=4.4.36 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.4,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.10.* *_cp310 + license: Python-2.0 + purls: [] + size: 25358312 + timestamp: 1769471983988 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda + build_number: 3 + sha256: 7ce2adb0cc4d45178dc018b55148fa2d6ccae0c98291cef1b21dafcda2de2687 + md5: ac461265b59028847699c0606e17804b + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.4,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.4,<4.0a0 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + constrains: + - python_abi 3.10.* *_cp310 + license: Python-2.0 + purls: [] + size: 12507955 + timestamp: 1769472053757 +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.19-hc20f281_3_cpython.conda + build_number: 3 + sha256: 77cbf9ab8e6c9f67e645b00a3224f35c92333fd9a737f5e53ef7060d0604c4cb + md5: 7be098c303e842443528587a5b2297f1 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.4,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.4,<4.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - python_abi 3.10.* *_cp310 + license: Python-2.0 + purls: [] + size: 16076382 + timestamp: 1769471071119 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda + sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 + md5: 5b8d21249ff20967101ffa321cab24e8 + depends: + - python >=3.9 + - six >=1.5 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/python-dateutil?source=hash-mapping + size: 233310 + timestamp: 1751104122689 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda + sha256: 467134ef39f0af2dbb57d78cb3e4821f01003488d331a8dd7119334f4f47bfbd + md5: 7ead57407430ba33f681738905278d03 + depends: + - python >=3.10 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tzdata?source=compressed-mapping + size: 143542 + timestamp: 1765719982349 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda + build_number: 8 + sha256: 7ad76fa396e4bde336872350124c0819032a9e8a0a40590744ff9527b54351c1 + md5: 05e00f3b21e88bb3d658ac700b2ce58c + constrains: + - python 3.10.* *_cpython + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 6999 + timestamp: 1752805924192 +- conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + sha256: 8d2a8bf110cc1fc3df6904091dead158ba3e614d8402a83e51ed3a8aa93cdeb0 + md5: bc8e3267d44011051f2eb14d22fb0960 + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytz?source=hash-mapping + size: 189015 + timestamp: 1742920947249 +- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py310h282bd7d_1.conda + sha256: 2ce920e200699cc2a114106665451c05efcaf5cf0ca46685d9a7a5914616f7b5 + md5: 0289b272f8a22ad8fc29d6747383b503 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/pywin32?source=hash-mapping + size: 6293229 + timestamp: 1756487147910 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py310h89163eb_2.conda + sha256: 5fba7f5babcac872c72f6509c25331bcfac4f8f5031f0102530a41b41336fce6 + md5: fd343408e64cf1e273ab7c710da374db + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 182769 + timestamp: 1737454971552 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py310hc74094e_2.conda + sha256: 0c46719507e1664b1085f2142b8250250c6aae01ec367d18068688efeba445ec + md5: b8be3d77488c580d2fd81c9bb3cacdf1 + depends: + - __osx >=11.0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 166853 + timestamp: 1737454973579 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py310h38315fa_2.conda + sha256: 49dd492bdf2c479118ca9d61a59ce259594853d367a1a0548926f41a6e734724 + md5: 9986c3731bb820db0830dd0825c26cf9 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - yaml >=0.2.5,<0.3.0a0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 157941 + timestamp: 1737455030235 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py310hc4bea81_2.conda + sha256: 3de52f8218a822a1bbfdbeb5ae948c178dfa7622dc81621fe5c6ac0c74dffdf6 + md5: 0731121636c788d581db487531d53928 + depends: + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - zeromq >=4.3.5,<4.4.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 327211 + timestamp: 1771716952315 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py310hf0664f0_2.conda + sha256: 0ac9742b67c453cd6ba7986d0c9365da87ee6cc47fb89a98eb453895fe2f238a + md5: 56eb04048880c7c521f18cb90606e3ea + depends: + - python + - python 3.10.* *_cpython + - __osx >=11.0 + - libcxx >=19 + - zeromq >=4.3.5,<4.4.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=compressed-mapping + size: 305070 + timestamp: 1771717036757 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py310h78cba24_2.conda + sha256: 28ab660f491cc208a8f3f33c4d3adfe5eb51f9bfb117f3c68e71b49637e44dde + md5: 8cecf961521c3e4cf48df04f8cb259c8 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - python_abi 3.10.* *_cp310 + - zeromq >=4.3.5,<4.3.6.0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyzmq?source=hash-mapping + size: 305690 + timestamp: 1771716971893 +- conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda + sha256: 776363493bad83308ba30bcb88c2552632581b143e8ee25b1982c8c743e73abc + md5: 353823361b1d27eb3960efb076dfcaf6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: LicenseRef-Qhull + purls: [] + size: 552937 + timestamp: 1720813982144 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda + sha256: 873ac689484262a51fd79bc6103c1a1bedbf524924d7f0088fb80703042805e4 + md5: 6483b1f59526e05d7d894e466b5b6924 + depends: + - __osx >=11.0 + - libcxx >=16 + license: LicenseRef-Qhull + purls: [] + size: 516376 + timestamp: 1720814307311 +- conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + sha256: 887d53486a37bd870da62b8fa2ebe3993f912ad04bd755e7ed7c47ced97cbaa8 + md5: 854fbdff64b572b5c0b470f334d34c11 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LicenseRef-Qhull + purls: [] + size: 1377020 + timestamp: 1720814433486 +- conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda + sha256: d52a7d4a26f5cb3d335067a1d4140f7f2b0b53ad8d78b2c766e88906863c33aa + md5: ac0eb548e24a2cb3c2c8ba060aef7db2 + depends: + - __glibc >=2.17,<3.0.a0 + - alsa-lib >=1.2.14,<1.3.0a0 + - dbus >=1.13.6,<2.0a0 + - double-conversion >=3.3.1,<3.4.0a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - harfbuzz >=11.0.1 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libclang-cpp20.1 >=20.1.4,<20.2.0a0 + - libclang13 >=20.1.4 + - libcups >=2.3.3,<2.4.0a0 + - libdrm >=2.4.124,<2.5.0a0 + - libegl >=1.7.0,<2.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libgl >=1.7.0,<2.0a0 + - libglib >=2.84.1,<3.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libllvm20 >=20.1.4,<20.2.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libpq >=17.4,<18.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libstdcxx >=13 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libxkbcommon >=1.9.2,<2.0a0 + - libxml2 >=2.13.7,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - wayland >=1.23.1,<2.0a0 + - xcb-util >=0.4.1,<0.5.0a0 + - xcb-util-cursor >=0.1.5,<0.2.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-keysyms >=0.4.1,<0.5.0a0 + - xcb-util-renderutil >=0.3.10,<0.4.0a0 + - xcb-util-wm >=0.4.2,<0.5.0a0 + - xorg-libice >=1.1.2,<2.0a0 + - xorg-libsm >=1.2.6,<2.0a0 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxcomposite >=0.4.6,<1.0a0 + - xorg-libxcursor >=1.2.3,<2.0a0 + - xorg-libxdamage >=1.1.6,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrandr >=1.5.4,<2.0a0 + - xorg-libxtst >=1.2.5,<2.0a0 + - xorg-libxxf86vm >=1.1.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - qt 6.9.0 + license: LGPL-3.0-only + license_family: LGPL + purls: [] + size: 51745422 + timestamp: 1746636875150 +- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h83cda92_0.conda + sha256: 84ff37de3c72a612dfbf9b317d5501231a87582f2edf4959ff706b84b4aa9246 + md5: d92e5a0de3263315551d54d5574f5193 + depends: + - double-conversion >=3.3.1,<3.4.0a0 + - harfbuzz >=11.0.0,<12.0a0 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libclang13 >=20.1.1 + - libglib >=2.84.0,<3.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.4.1,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - qt 6.9.0 + license: LGPL-3.0-only + license_family: LGPL + purls: [] + size: 94992566 + timestamp: 1743635306726 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda + sha256: 6e5e704c1c21f820d760e56082b276deaf2b53cf9b751772761c3088a365f6f4 + md5: 2c42649888aac645608191ffdc80d13a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + constrains: + - __glibc >=2.17 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 5176669 + timestamp: 1746622023242 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rav1e-0.7.1-h0716509_3.conda + sha256: 65f862b2b31ef2b557990a82015cbd41e5a66041c2f79b4451dd14b4595d4c04 + md5: 7b37f30516100b86ea522350c8cab44c + depends: + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 856271 + timestamp: 1746622200646 +- conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.7.1-ha073cba_3.conda + sha256: d19a58b882a0387c7c8efbfce4e67a0df4b19d8da6cf6cec3011b6079e5bc743 + md5: 3bd3626822633688691ed41d661c2b2e + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 4122383 + timestamp: 1746622805379 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 + depends: + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 313930 + timestamp: 1765813902568 +- pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl + name: referencing + version: 0.37.0 + sha256: 381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 + requires_dist: + - attrs>=22.2.0 + - rpds-py>=0.7.0 + - typing-extensions>=4.4.0 ; python_full_version < '3.13' + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda + sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 + md5: c65df89a0b2e321045a9e01d1337b182 + depends: + - python >=3.10 + - certifi >=2017.4.17 + - charset-normalizer >=2,<4 + - idna >=2.5,<4 + - urllib3 >=1.21.1,<3 + - python + constrains: + - chardet >=3.0.2,<6 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/requests?source=compressed-mapping + size: 63602 + timestamp: 1766926974520 +- pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl + name: rpds-py + version: 0.30.0 + sha256: 4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: rpds-py + version: 0.30.0 + sha256: 0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl + name: rpds-py + version: 0.30.0 + sha256: 1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.3.0-py310hfd4b839_3.conda + sha256: 0fa05f5698eca0fe401d1d740c6836d2674389dd8d2c39d43bd2411ae53ae8a0 + md5: 9633c2a1e6cd2accc27e5b93ebf58d0b + depends: + - libspatialindex >=2.1.0,<2.1.1.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rtree?source=hash-mapping + size: 57967 + timestamp: 1734967774693 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.3.0-py310h78b29c1_3.conda + sha256: 49150c8af86af4e5cd10965957f5e12bd6f0cd21e868b25bcddc810cf96ae02f + md5: b1a98514f83f96139df2030d871b689b + depends: + - libspatialindex >=2.1.0,<2.1.1.0a0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rtree?source=hash-mapping + size: 58882 + timestamp: 1734967887770 +- conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.3.0-py310hdd37b41_3.conda + sha256: 7e527a1d7fd61a94d842490aa36cd283cb864fe97fb08b329a03925e327a2c25 + md5: 9bc10b479d71bfe1922c82087e2b1ab5 + depends: + - libspatialindex >=2.1.0,<2.1.1.0a0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: MIT + license_family: MIT + purls: + - pkg:pypi/rtree?source=hash-mapping + size: 58495 + timestamp: 1734967816955 +- conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.2-py310h228f341_0.conda + sha256: 8af2a49b75b9697653a0bf55717c8153732c4fc53f58d4aa0ed692ae348c49f6 + md5: 0f3e3324506bd3e67934eda9895f37a7 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + - joblib >=1.2.0 + - libgcc >=14 + - libstdcxx >=14 + - numpy >=1.21,<3 + - numpy >=1.22.0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - scipy >=1.8.0 + - threadpoolctl >=3.1.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scikit-learn?source=hash-mapping + size: 8415134 + timestamp: 1757406407327 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.2-py310h660f142_0.conda + sha256: f7960d72c7d36e1830d985d70587bc85e571d4bdcdea3cfea6e81602e2a222ea + md5: 26f940c6a467ed3fe2b4fbab43ab312e + depends: + - __osx >=11.0 + - joblib >=1.2.0 + - libcxx >=19 + - llvm-openmp >=19.1.7 + - numpy >=1.21,<3 + - numpy >=1.22.0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + - scipy >=1.8.0 + - threadpoolctl >=3.1.0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scikit-learn?source=hash-mapping + size: 7749690 + timestamp: 1757407202358 +- conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.7.2-py310h21054b0_0.conda + sha256: 8515607e6b0e97edd93120368a9e788f3149fdc0855252a9d112e32ad522ba4a + md5: 2b93662be724f88f5196549133adbfe1 + depends: + - joblib >=1.2.0 + - numpy >=1.21,<3 + - numpy >=1.22.0 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - scipy >=1.8.0 + - threadpoolctl >=3.1.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scikit-learn?source=hash-mapping + size: 7675668 + timestamp: 1757433583495 +- conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda + sha256: 4cb98641f870666d365594013701d5691205a0fe81ac3ba7778a23b1cc2caa8e + md5: 8c29cd33b64b2eb78597fa28b5595c8d + depends: + - __glibc >=2.17,<3.0.a0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc >=13 + - libgfortran + - libgfortran5 >=13.3.0 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx >=13 + - numpy <2.5 + - numpy >=1.19,<3 + - numpy >=1.23.5 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scipy?source=hash-mapping + size: 16417101 + timestamp: 1739791865060 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.15.2-py310h32ab4ed_0.conda + sha256: f6ff2c1ba4775300199e8bc0331d2e2ccb5906f58f3835c5426ddc591c9ad7bf + md5: a389f540c808b22b3c696d7aea791a41 + depends: + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=18 + - libgfortran >=5 + - libgfortran5 >=13.2.0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.5 + - numpy >=1.19,<3 + - numpy >=1.23.5 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scipy?source=hash-mapping + size: 13507343 + timestamp: 1739792089317 +- conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py310h15c175c_0.conda + sha256: f19350c2061b1cdc3151a33c3dd4f71a1a481f9b10ac186674f957814bc839bc + md5: 81798168111d1021e3d815217c444418 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.5 + - numpy >=1.19,<3 + - numpy >=1.23.5 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scipy?source=hash-mapping + size: 14352068 + timestamp: 1739793156239 +- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda + sha256: fd7201e38e38bf7f25818d624ca8da97b8998957ca9ae3fb7fdc9c17e6b25fcd + md5: 1d00d46c634177fc8ede8b99d6089239 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/setuptools?source=compressed-mapping + size: 637506 + timestamp: 1770634745653 +- conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.6-py310had3dfd6_2.conda + sha256: f39309969c028b3b53831b4b7982d68d7de1bfdc2bf25d3330b8e4aea1494350 + md5: a4166b41e54d22e794859641b7cae2d0 + depends: + - __glibc >=2.17,<3.0.a0 + - geos >=3.13.0,<3.13.1.0a0 + - libgcc >=13 + - numpy >=1.19,<3 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/shapely?source=hash-mapping + size: 486930 + timestamp: 1727273539386 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.6-py310h6b3522b_2.conda + sha256: 34812447c29faca0b5e0682bec0eaeca5f70f89ced370d9175a8e8504bf118fb + md5: f4fd6f92dc2cb99a198e216a54dfc7cc + depends: + - __osx >=11.0 + - geos >=3.13.0,<3.13.1.0a0 + - numpy >=1.19,<3 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/shapely?source=hash-mapping + size: 449516 + timestamp: 1727273686755 +- conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.6-py310hde62f2e_2.conda + sha256: d147abfc8d8acfa460e5f8094a7271277255d6fb73075b38c808938f59408838 + md5: 3793f088ec82fd4194f2712643150132 + depends: + - geos >=3.13.0,<3.13.1.0a0 + - numpy >=1.19,<3 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/shapely?source=hash-mapping + size: 453430 + timestamp: 1727274008606 +- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda + sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d + md5: 3339e3b65d58accf4ca4fb8748ab16b3 + depends: + - python >=3.9 + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/six?source=hash-mapping + size: 18455 + timestamp: 1753199211006 +- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda + sha256: 48f3f6a76c34b2cfe80de9ce7f2283ecb55d5ed47367ba91e8bb8104e12b8f11 + md5: 98b6c9dc80eb87b2519b97bcf7e578dd + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 45829 + timestamp: 1762948049098 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.2.2-hada39a4_1.conda + sha256: cb9305ede19584115f43baecdf09a3866bfcd5bcca0d9e527bd76d9a1dbe2d8d + md5: fca4a2222994acd7f691e57f94b750c5 + depends: + - libcxx >=19 + - __osx >=11.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 38883 + timestamp: 1762948066818 +- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda + sha256: d2deda1350abf8c05978b73cf7fe9147dd5c7f2f9b312692d1b98e52efad53c3 + md5: 3075846de68f942150069d4289aaad63 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 67417 + timestamp: 1762948090450 +- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.51.2-hbc0de68_0.conda + sha256: 65436099fd33e4471348d614c1de9235fdd4e5b7d86a5a12472922e6b6628951 + md5: a6adeaa8efb007e2e1ab3e45768ea987 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libsqlite 3.51.2 h0c1763c_0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - readline >=8.3,<9.0a0 + license: blessing + purls: [] + size: 183835 + timestamp: 1768147980363 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.51.2-h85ec8f2_0.conda + sha256: 63c2bbb58e5ca58232cbe61754b85d0a080e5360291cebd52653e000bb0ae8fd + md5: 7821b42fed75ef394d401f59f70e0732 + depends: + - __osx >=11.0 + - libsqlite 3.51.2 h1b79a29_0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - readline >=8.3,<9.0a0 + license: blessing + purls: [] + size: 165822 + timestamp: 1768148297178 +- conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.51.2-hdb435a2_0.conda + sha256: 8194c1326f052852dd827f5277ba381228a968e841d410eb18c622cf851b11ba + md5: bc9265bd9f30f9ded263cb762a4fc847 + depends: + - libsqlite 3.51.2 hf5d6505_0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 400812 + timestamp: 1768148302390 +- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 + md5: b1b505328da7a6b246787df4b5a49fbc + depends: + - asttokens + - executing + - pure_eval + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/stack-data?source=hash-mapping + size: 26988 + timestamp: 1733569565672 +- conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda + sha256: e5e036728ef71606569232cc94a0480722e14ed69da3dd1e363f3d5191d83c01 + md5: 9a6117aee038999ffefe6082ff1e9a81 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 2620937 + timestamp: 1769280649780 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-4.0.0-h0cb729a_0.conda + sha256: f7fc5a18f4a6cf61fa4b6697c6aa28426b07a3df2b53a96b25dda28641991532 + md5: 3dc1d4f4c9829c82c7f6660878abcd32 + depends: + - __osx >=11.0 + - libcxx >=19 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 1455052 + timestamp: 1769280806030 +- conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.0-hac47afa_0.conda + sha256: ab0ed5b654892750005c3a5aa57994ec8191b6cbee58511199d2a322026426d9 + md5: b050c2a626cda95910f1660f570a7ba4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 1809227 + timestamp: 1769280679130 +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda + sha256: c31cac57913a699745d124cdc016a63e31c5749f16f60b3202414d071fc50573 + md5: 17c38aaf14c640b85c4617ccb59c1146 + depends: + - libhwloc >=2.12.1,<2.12.2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 155714 + timestamp: 1762510341121 +- conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda + sha256: 32e75900d6a094ffe4290a8c9f1fa15744d9da8ff617aba4acaa0f057a065c34 + md5: 043f0599dc8aa023369deacdb5ac24eb + depends: + - python >=3.10 + - python + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tenacity?source=hash-mapping + size: 31404 + timestamp: 1770510172846 +- conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda + sha256: 6016672e0e72c4cf23c0cf7b1986283bd86a9c17e8d319212d78d8e9ae42fdfd + md5: 9d64911b31d57ca443e9f1e36b04385f + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/threadpoolctl?source=hash-mapping + size: 23869 + timestamp: 1741878358548 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + constrains: + - xorg-libx11 >=1.8.12,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 + md5: 0481bfd9814bf525bd4b3ee4b51494c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: TCL + license_family: BSD + purls: [] + size: 3526350 + timestamp: 1769460339384 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py310h7c4b9e2_0.conda + sha256: c27c28d19f8ba8ef6efd35dc47951c985db8a828db38444e1fad3f93f8cedb8d + md5: 30b9d5c1bc99ffbc45a63ab8d1725b93 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 663313 + timestamp: 1765458854459 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py310hfe3a0ae_0.conda + sha256: b04eb945081bef51b7fec81b8cfab1711c7f8ff1dd122ca217b99fdbbea6d0be + md5: 57010dd2f9319b8f6efba3a7b8e48e81 + depends: + - __osx >=11.0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 665175 + timestamp: 1765836991989 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py310h29418f3_0.conda + sha256: fa9d807ba6b2c33ab061586292709fedeb3113f5462829d1357ac18193c8fd44 + md5: 5f19583828bd8325b001fe471776ead8 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/tornado?source=hash-mapping + size: 665930 + timestamp: 1765836632159 +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda + sha256: 11e2c85468ae9902d24a27137b6b39b4a78099806e551d390e394a8c34b48e40 + md5: 9efbfdc37242619130ea42b1cc4ed861 + depends: + - colorama + - python >=3.9 + license: MPL-2.0 or MIT + purls: + - pkg:pypi/tqdm?source=hash-mapping + size: 89498 + timestamp: 1735661472632 +- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda + sha256: f39a5620c6e8e9e98357507262a7869de2ae8cc07da8b7f84e517c9fd6c2b959 + md5: 019a7385be9af33791c989871317e1ed + depends: + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/traitlets?source=hash-mapping + size: 110051 + timestamp: 1733367480074 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 + md5: 0caa1af407ecff61170c9437a808404d + depends: + - python >=3.10 + - python + license: PSF-2.0 + license_family: PSF + purls: + - pkg:pypi/typing-extensions?source=hash-mapping + size: 51692 + timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain + purls: [] + size: 119135 + timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + purls: [] + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py310h7c4b9e2_0.conda + sha256: 44ecba51c98c3fb2ce3d00295d423d3bb254cde1790eff9818ed328aa608ab28 + md5: 234e9858dd691d3f597147e22cbf16cf + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/unicodedata2?source=hash-mapping + size: 410408 + timestamp: 1770909105501 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py310h72544b6_0.conda + sha256: 48e56c2068cce4b2d09cceca65ca1c877ebf550e3ad67af3ed30db162bc89e0b + md5: a35cf23aa03fb8d3a95158253918ed00 + depends: + - __osx >=11.0 + - python >=3.10,<3.11.0a0 + - python >=3.10,<3.11.0a0 *_cpython + - python_abi 3.10.* *_cp310 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/unicodedata2?source=hash-mapping + size: 416056 + timestamp: 1770910020955 +- conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py310h29418f3_0.conda + sha256: 0ce3386d49564a30da221cdee59edf113ef27e1ea784dd33f5f39411b7faeccb + md5: 8c34b3ebcfd8d6e4989ae1a2f2a63d03 + depends: + - python >=3.10,<3.11.0a0 + - python_abi 3.10.* *_cp310 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/unicodedata2?source=hash-mapping + size: 406410 + timestamp: 1770909213469 +- conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda + sha256: 2aad2aeff7c69a2d7eecd7b662eef756b27d6a6b96f3e2c2a7071340ce14543e + md5: d71d3a66528853c0a1ac2c02d79a0284 + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 48270 + timestamp: 1715010035325 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda + sha256: fa0bcbfb20a508ca9bf482236fe799581cbd0eab016e47a865e9fa44dbe3c512 + md5: e8ff9e11babbc8cd77af5a4258dc2802 + depends: + - __osx >=11.0 + - libcxx >=16 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 40625 + timestamp: 1715010029254 +- conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda + sha256: ed0eed8ed0343d29cdbfaeb1bfd141f090af696547d69f91c18f46350299f00d + md5: 28b4cf9065681f43cc567410edf8243d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 49181 + timestamp: 1715010467661 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda + sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a + md5: 9272daa869e03efe68833e3dc7a02130 + depends: + - backports.zstd >=1.0.0 + - brotli-python >=1.2.0 + - h2 >=4,<5 + - pysocks >=1.5.6,<2.0,!=1.5.7 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/urllib3?source=hash-mapping + size: 103172 + timestamp: 1767817860341 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f + depends: + - vc14_runtime >=14.44.35208 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_34 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 115235 + timestamp: 1767320173250 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_34.conda + sha256: 63ff4ec6e5833f768d402f5e95e03497ce211ded5b6f492e660e2bfc726ad24d + md5: f276d1de4553e8fca1dfb6988551ebb4 + depends: + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 19347 + timestamp: 1767320221943 +- conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda + sha256: ba673427dcd480cfa9bbc262fd04a9b1ad2ed59a159bd8f7e750d4c52282f34c + md5: 0f2ca7906bf166247d1d760c3422cb8a + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: MIT + license_family: MIT + purls: [] + size: 330474 + timestamp: 1751817998141 +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda + sha256: e298b508b2473c4227206800dfb14c39e4b14fd79d4636132e9e1e4244cdf4aa + md5: c3197f8c0d5b955c904616b716aca093 + depends: + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/wcwidth?source=compressed-mapping + size: 71550 + timestamp: 1770634638503 +- conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda + sha256: d6cf2f0ebd5e09120c28ecba450556ce553752652d91795442f0e70f837126ae + md5: bdbd7385b4a67025ac2dba4ef8cb6a8f + depends: + - packaging >=24.0 + - python >=3.10 + license: MIT + license_family: MIT + purls: + - pkg:pypi/wheel?source=hash-mapping + size: 31858 + timestamp: 1769139207397 +- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f + md5: 46e441ba871f524e2b067929da3051c2 + depends: + - __win + - python >=3.9 + license: LicenseRef-Public-Domain + purls: + - pkg:pypi/win-inet-pton?source=hash-mapping + size: 9555 + timestamp: 1733130678956 +- conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 + sha256: 76c7405bcf2af639971150f342550484efac18219c0203c5ee2e38b8956fe2a0 + md5: e7f6ed84d4623d52ee581325c1587a6b + depends: + - libgcc-ng >=10.3.0 + - libstdcxx-ng >=10.3.0 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 3357188 + timestamp: 1646609687141 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 + sha256: 2fed6987dba7dee07bd9adc1a6f8e6c699efb851431bcb6ebad7de196e87841d + md5: b1f7f2780feffe310b068c021e8ff9b2 + depends: + - libcxx >=12.0.1 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 1832744 + timestamp: 1646609481185 +- conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 + sha256: 02b9874049112f2b7335c9a3e880ac05d99a08d9a98160c5a98898b2b3ac42b2 + md5: ca7129a334198f08347fb19ac98a2de9 + depends: + - vc >=14.1,<15 + - vs2015_runtime >=14.16.27033 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 5517425 + timestamp: 1646611941216 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda + sha256: ad8cab7e07e2af268449c2ce855cbb51f43f4664936eff679b1f3862e6e4b01d + md5: fdc27cb255a7a2cc73b7919a968b48f0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libxcb >=1.17.0,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 20772 + timestamp: 1750436796633 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda + sha256: c2be9cae786fdb2df7c2387d2db31b285cf90ab3bfabda8fa75a596c3d20fc67 + md5: 4d1fc190b99912ed557a8236e958c559 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libxcb >=1.13 + - libxcb >=1.17.0,<2.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-renderutil >=0.3.10,<0.4.0a0 + license: MIT + license_family: MIT + purls: [] + size: 20829 + timestamp: 1763366954390 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + sha256: 94b12ff8b30260d9de4fd7a28cca12e028e572cbc504fd42aa2646ec4a5bded7 + md5: a0901183f08b6c7107aab109733a3c91 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + - xcb-util >=0.4.1,<0.5.0a0 + license: MIT + license_family: MIT + purls: [] + size: 24551 + timestamp: 1718880534789 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + sha256: 546e3ee01e95a4c884b6401284bb22da449a2f4daf508d038fdfa0712fe4cc69 + md5: ad748ccca349aec3e91743e08b5e2b50 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + purls: [] + size: 14314 + timestamp: 1718846569232 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + sha256: 2d401dadc43855971ce008344a4b5bd804aca9487d8ebd83328592217daca3df + md5: 0e0cbe0564d03a99afd5fd7b362feecd + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + purls: [] + size: 16978 + timestamp: 1718848865819 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + sha256: 31d44f297ad87a1e6510895740325a635dd204556aa7e079194a0034cdd7e66a + md5: 608e0ef8256b81d04456e8d211eee3e8 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + purls: [] + size: 51689 + timestamp: 1718844051451 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-h988505b_2.conda + sha256: 339ab0ff05170a295e59133cd0fa9a9c4ba32b6941c8a2a73484cc13f81e248a + md5: 9dda9667feba914e0e80b95b82f7402b + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=75.1,<76.0a0 + - libgcc >=13 + - libnsl >=2.0.1,<2.1.0a0 + - libstdcxx >=13 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1648243 + timestamp: 1727733890754 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-h92fc2f4_2.conda + sha256: 863a7c2a991a4399d362d42c285ebc20748a4ea417647ebd3a171e2220c7457d + md5: 50b7325437ef0901fe25dc5c9e743b88 + depends: + - __osx >=11.0 + - icu >=75.1,<76.0a0 + - libcxx >=17 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1277884 + timestamp: 1727733870250 +- conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-he0c23c2_2.conda + sha256: 759ae22a0a221dc1c0ba39684b0dcf696aab4132478e17e56a0366ded519e54e + md5: 82b6eac3c198271e98b48d52d79726d8 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3574017 + timestamp: 1727734520239 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda + sha256: aa03b49f402959751ccc6e21932d69db96a65a67343765672f7862332aa32834 + md5: 71ae752a748962161b4740eaff510258 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 396975 + timestamp: 1759543819846 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + sha256: c12396aabb21244c212e488bbdc4abcdef0b7404b15761d9329f5a4a39113c4b + md5: fb901ff28063514abb6046c9ec2c4a45 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + purls: [] + size: 58628 + timestamp: 1734227592886 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + sha256: 277841c43a39f738927145930ff963c5ce4c4dacf66637a3d95d802a64173250 + md5: 1c74ff8c35dcadf952a16f752ca5aa49 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libuuid >=2.38.1,<3.0a0 + - xorg-libice >=1.1.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 27590 + timestamp: 1741896361728 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda + sha256: 516d4060139dbb4de49a4dcdc6317a9353fb39ebd47789c14e6fe52de0deee42 + md5: 861fb6ccbc677bb9a9fb2468430b9c6a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libxcb >=1.17.0,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 839652 + timestamp: 1770819209719 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b + md5: b2895afaf55bf96a8c8282a2e47a5de0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 15321 + timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda + sha256: adae11db0f66f86156569415ed79cda75b2dbf4bea48d1577831db701438164f + md5: 78b548eed8227a689f93775d5d23ae09 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 14105 + timestamp: 1762976976084 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + sha256: 156a583fa43609507146de1c4926172286d92458c307bb90871579601f6bc568 + md5: 8436cab9a76015dfe7208d3c9f97c156 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 109246 + timestamp: 1762977105140 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda + sha256: 048c103000af9541c919deef03ae7c5e9c570ffb4024b42ecb58dbde402e373a + md5: f2ba4192d38b6cef2bb2c25029071d90 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + license: MIT + license_family: MIT + purls: [] + size: 14415 + timestamp: 1770044404696 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + sha256: 832f538ade441b1eee863c8c91af9e69b356cd3e9e1350fff4fe36cc573fc91a + md5: 2ccd714aa2242315acaf0a67faea780b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + - xorg-libxrender >=0.9.11,<0.10.0a0 + license: MIT + license_family: MIT + purls: [] + size: 32533 + timestamp: 1730908305254 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + sha256: 43b9772fd6582bf401846642c4635c47a9b0e36ca08116b3ec3df36ab96e0ec0 + md5: b5fcc7172d22516e1f965490e65e33a4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + purls: [] + size: 13217 + timestamp: 1727891438799 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 + md5: 1dafce8548e38671bea82e3f5c6ce22f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 20591 + timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda + sha256: f7fa0de519d8da589995a1fe78ef74556bb8bc4172079ae3a8d20c3c81354906 + md5: 9d1299ace1924aa8f4e0bc8e71dd0cf7 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 19156 + timestamp: 1762977035194 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + sha256: 366b8ae202c3b48958f0b8784bbfdc37243d3ee1b1cd4b8e76c10abe41fa258b + md5: a7c03e38aa9c0e84d41881b9236eacfb + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 70691 + timestamp: 1762977015220 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda + sha256: 79c60fc6acfd3d713d6340d3b4e296836a0f8c51602327b32794625826bd052f + md5: 34e54f03dfea3e7a2dcf1453a85f1085 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 50326 + timestamp: 1769445253162 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + sha256: 83c4c99d60b8784a611351220452a0a85b080668188dce5dfa394b723d7b64f4 + md5: ba231da7fccf9ea1e768caf5c7099b84 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 20071 + timestamp: 1759282564045 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + sha256: 1a724b47d98d7880f26da40e45f01728e7638e6ec69f35a3e11f92acd05f9e7a + md5: 17dcc85db3c7886650b8908b183d6876 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + purls: [] + size: 47179 + timestamp: 1727799254088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda + sha256: 80ed047a5cb30632c3dc5804c7716131d767089f65877813d4ae855ee5c9d343 + md5: e192019153591938acf7322b6459d36e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: MIT + license_family: MIT + purls: [] + size: 30456 + timestamp: 1769445263457 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + sha256: 044c7b3153c224c6cedd4484dd91b389d2d7fd9c776ad0f4a34f099b3389f4a1 + md5: 96d57aba173e878a2089d5638016dc5e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 33005 + timestamp: 1734229037766 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + sha256: 752fdaac5d58ed863bbf685bb6f98092fe1a488ea8ebb7ed7b606ccfce08637a + md5: 7bbe9a0cc0df0ac5f5a8ad6d6a11af2f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxi >=1.7.10,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 32808 + timestamp: 1727964811275 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda + sha256: 64db17baaf36fa03ed8fae105e2e671a7383e22df4077486646f7dbf12842c9f + md5: 665d152b9c6e78da404086088077c844 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 18701 + timestamp: 1769434732453 +- conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda + sha256: b194a1fbc38f29c563b102ece9d006f7a165bf9074cdfe50563d3bce8cae9f84 + md5: 16933322051fa260285f1a44aae91dd6 + depends: + - python >=3.8 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/xyzservices?source=hash-mapping + size: 51128 + timestamp: 1763813786075 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda + sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad + md5: a77f85f77be52ff59391544bfe73390a + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + purls: [] + size: 85189 + timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda + sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac + md5: 78a0fe9e9c50d2c381e8ee47e3ea437d + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: [] + size: 83386 + timestamp: 1753484079473 +- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda + sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 + md5: 433699cba6602098ae8957a323da2664 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: [] + size: 63944 + timestamp: 1753484092156 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda + sha256: 47cfe31255b91b4a6fa0e9dbaf26baa60ac97e033402dbc8b90ba5fee5ffe184 + md5: 8035e5b54c08429354d5d64027041cad + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libsodium >=1.0.20,<1.0.21.0a0 + - krb5 >=1.21.3,<1.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 310648 + timestamp: 1757370847287 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-hebf3989_1.conda + sha256: caf6df12d793600faec21b7e6025e2e8fb8de26672cce499f9471b99b6776eb1 + md5: 19cff1c627ff58429701113bf35300c8 + depends: + - libcxx >=16 + - libsodium >=1.0.18,<1.0.19.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 288572 + timestamp: 1709135728486 +- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda + sha256: 690cf749692c8ea556646d1a47b5824ad41b2f6dfd949e4cdb6c44a352fcb1aa + md5: a6c8f8ee856f7c3c1576e14b86cd8038 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libsodium >=1.0.20,<1.0.21.0a0 + - krb5 >=1.21.3,<1.22.0a0 + license: MPL-2.0 + license_family: MOZILLA + purls: [] + size: 265212 + timestamp: 1757370864284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda + sha256: 5d7c0e5f0005f74112a34a7425179f4eb6e73c92f5d109e6af4ddeca407c92ab + md5: c9f075ab2f33b3bbee9e62d4ad0a6cd8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib 1.3.1 hb9d3cd8_2 + license: Zlib + license_family: Other + purls: [] + size: 92286 + timestamp: 1727963153079 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda + sha256: 58f8860756680a4831c1bf4f294e2354d187f2e999791d53b1941834c4b37430 + md5: e3170d898ca6cb48f1bb567afb92f775 + depends: + - __osx >=11.0 + - libzlib 1.3.1 h8359307_2 + license: Zlib + license_family: Other + purls: [] + size: 77606 + timestamp: 1727963209370 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_2.conda + sha256: 8c688797ba23b9ab50cef404eca4d004a948941b6ee533ead0ff3bf52012528c + md5: be60c4e8efa55fddc17b4131aa47acbd + depends: + - libzlib 1.3.1 h2466b09_2 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Zlib + license_family: Other + purls: [] + size: 107439 + timestamp: 1727963788936 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 388453 + timestamp: 1764777142545 diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 00000000..0cac156f --- /dev/null +++ b/pixi.toml @@ -0,0 +1,34 @@ +[workspace] +authors = ["Chenhao Ding "] +channels = ["conda-forge", "main", "r", "msys2", "gurobi"] +name = "fleetpy" +platforms = ["osx-arm64", "linux-64", "win-64"] +version = "0.1.0" + +[tasks] +run_examples = "python run_examples.py" + +[dependencies] +pip = "25.0.*" +numpy = "2.2.*" +plotly = "5.24.*" +python = "3.10.*" +scipy = "1.15.*" +fiona = "==1.10.1" +geopandas = "==1.0.1" +pandas = "==2.2.3" +pyogrio = "==0.10.0" +pyproj = "==3.7.0" +pyyaml = "==6.0.2" +rtree = "==1.3.0" +shapely = "==2.0.6" +tqdm = "==4.67.1" +matplotlib = "*" +requests = "*" +ipykernel = "*" +gurobi = ">=13.0.1,<14" + +[pypi-dependencies] +cython = "==3.0.11" +dill = "==0.3.9" +nbformat = ">=4.2.0" From 395ae2842c32a0ab209f7473d81a118740d5a228 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 23 Feb 2026 15:16:08 +0100 Subject: [PATCH 30/31] remove pixi support --- .gitattributes | 2 - .gitignore | 4 - pixi.lock | 7620 ------------------------------------------------ pixi.toml | 34 - 4 files changed, 7660 deletions(-) delete mode 100644 .gitattributes delete mode 100644 pixi.lock delete mode 100644 pixi.toml diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 997504b4..00000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# SCM syntax highlighting & preventing 3-way merges -pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff diff --git a/.gitignore b/.gitignore index 2f276d51..364453be 100644 --- a/.gitignore +++ b/.gitignore @@ -197,7 +197,3 @@ dmypy.json # GTFS preprocessing file !src/preprocessing/pt/PTRouterGTFSPreperation.ipynb - -# pixi environments -.pixi/* -!.pixi/config.toml diff --git a/pixi.lock b/pixi.lock deleted file mode 100644 index 60444d48..00000000 --- a/pixi.lock +++ /dev/null @@ -1,7620 +0,0 @@ -version: 6 -environments: - default: - channels: - - url: https://conda.anaconda.org/conda-forge/ - - url: https://conda.anaconda.org/main/ - - url: https://conda.anaconda.org/r/ - - url: https://conda.anaconda.org/msys2/ - - url: https://conda.anaconda.org/gurobi/ - indexes: - - https://pypi.org/simple - options: - pypi-prerelease-mode: if-necessary-or-explicit - packages: - linux-64: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py310h3788b33_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py310h25320af_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.10.1-py310h0aed7a2_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py310h3406613_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h9dce30a_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/geos-3.13.0-h5888daf_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.4-h3551947_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda - - conda: https://conda.anaconda.org/gurobi/linux-64/gurobi-13.0.1-py310_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py310haaf941d_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.7-h75ea233_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_8.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libde265-1.0.15-h00ab1b0_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-core-3.10.2-h3359108_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-haa4a5bd_1022.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hecd9e04_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h97f6797_17.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.1.0-he57a185_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h1b4f908_12.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py310h3406613_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py310hff52083_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py310hfde16b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.10-h05a5f5f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.3.0-py310h6557065_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.5.1-h0054346_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py310h139afa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyogrio-0.10.0-py310h0aed7a2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.7.0-py310h2e9f774_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py310hfd10a26_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py310h89163eb_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py310hc4bea81_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.3.0-py310hfd4b839_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.2-py310h228f341_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.6-py310had3dfd6_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.51.2-hbc0de68_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py310h7c4b9e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py310h7c4b9e2_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-h988505b_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - pypi: https://files.pythonhosted.org/packages/f0/89/b1ae45689abecca777f95462781a76e67ff46b55495a481ec5a73a739994/Cython-3.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - osx-arm64: - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.1-h7bae524_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.3.0-py310h2d60bed_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/blosc-1.21.6-h7dd00d9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py310h6123dab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.2-py310h7f4e7e6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/dav1d-1.2.1-hb547adb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py310h19b6747_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.10.1-py310hd68230c_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py310hf4fd40f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-h3ab3353_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/geos-3.13.0-hf9b8971_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/geotiff-1.7.4-hbef4fa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda - - conda: https://conda.anaconda.org/gurobi/osx-arm64/gurobi-13.0.1-py310_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py310h563d721_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.7-h3c2f2b0_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libavif16-1.3.0-hde9513d_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-hd5a2499_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libde265-1.0.15-h2ffa867_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.23-h5773f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-core-3.10.2-h9ef0d2d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libheif-1.19.7-gpl_h79e6334_100.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-hc33e383_1022.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-ha2cf0f4_17.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.1.0-h57eeb1c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-hf92fc0a_12.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1b79a29_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h551f018_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.9-h4a9ca0c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py310hf4fd40f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py310hb6292c7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py310h0181960_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.10-hff1a8ea_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.2.6-py310h4d83441_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py310h5936506_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.44-ha881caa_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-11.3.0-py310h5de80a5_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.5.1-h1318a7e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py310haea493c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyogrio-0.10.0-py310hd68230c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyproj-3.7.0-py310h861c57f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py310hc74094e_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py310hf0664f0_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rav1e-0.7.1-h0716509_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.3.0-py310h78b29c1_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.2-py310h660f142_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.15.2-py310h32ab4ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.6-py310h6b3522b_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.2.2-hada39a4_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.51.2-h85ec8f2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-4.0.0-h0cb729a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py310hfe3a0ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py310h72544b6_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-h92fc2f4_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-hebf3989_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - pypi: https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl - win-64: - - conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.3.0-h57928b3_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.1-he0c23c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/blosc-1.21.6-hfd34d9b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyha7b4d00_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py310hc19bc0b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py310h699e580_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.10.1-py310hf80745b_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py310hdb0e946_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-hf297d47_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.13.0-h5a68840_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.4-h887f4e7_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda - - conda: https://conda.anaconda.org/gurobi/win-64/gurobi-13.0.1-py310_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.0.0-h9e37d49_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyha7b4d00_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py310h1e1005b_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.7-h5343c79_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.3.0-ha08a409_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.18.0-h43ecb02_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libde265-1.0.15-h91493d7_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-core-3.10.2-h095903c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.0-h7025463_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libheif-1.19.7-gpl_h2684147_100.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h88281d1_1000.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-h68a222c_1022.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-hd4c2148_17.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.20-hc70643c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.1.0-h518811d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-h939089a_12.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.9-h741aa76_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h25c3957_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.8-h4fa8253_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py310hdb0e946_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py310h5588dad_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py310h0bdd906_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.10-h9fa1bad_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h24db6dd_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py310hb4db72f_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.3.0-py310hb3a2f59_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.5.1-h4f671f6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py310h1637853_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyogrio-0.10.0-py310hf80745b_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyproj-3.7.0-py310h19d4cff_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py310hc1b6536_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.19-hc20f281_3_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py310h282bd7d_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py310h38315fa_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py310h78cba24_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h83cda92_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.7.1-ha073cba_3.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.3.0-py310hdd37b41_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.7.2-py310h21054b0_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py310h15c175c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.6-py310hde62f2e_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.51.2-hdb435a2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.0-hac47afa_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py310h29418f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py310h29418f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_34.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-he0c23c2_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - - pypi: https://files.pythonhosted.org/packages/f9/de/19fdd1c7a52e0534bf5f544e0346c15d71d20338dbd013117f763b94613f/Cython-3.0.11-cp310-cp310-win_amd64.whl - - pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl -packages: -- conda: https://conda.anaconda.org/conda-forge/win-64/_libavif_api-1.3.0-h57928b3_3.conda - sha256: fd43fe0a83a3c42dc2a7244ad8419c47a56916dcf177f7ad0ce2de95f118e159 - md5: 77af412511d5b8e7d9ca63d12cf93672 - purls: [] - size: 10600 - timestamp: 1769477066547 -- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - build_number: 20 - sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 - md5: a9f577daf3de00bca7c3c76c0ecbd1de - depends: - - __glibc >=2.17,<3.0.a0 - - libgomp >=7.5.0 - constrains: - - openmp_impl <0.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 28948 - timestamp: 1770939786096 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda - build_number: 7 - sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd - md5: a44032f282e7d2acdeb1c240308052dd - depends: - - llvm-openmp >=9.0.1 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 8325 - timestamp: 1764092507920 -- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda - build_number: 20 - sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 - md5: 1626967b574d1784b578b52eaeb071e7 - depends: - - libgomp >=7.5.0 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - openmp_impl <0.0a0 - - msys2-conda-epoch <0.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 52252 - timestamp: 1770943776666 -- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda - sha256: d88aa7ae766cf584e180996e92fef2aa7d8e0a0a5ab1d4d49c32390c1b5fff31 - md5: dcdc58c15961dbf17a0621312b01f5cb - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: LGPL-2.1-or-later - license_family: GPL - purls: [] - size: 584660 - timestamp: 1768327524772 -- conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda - sha256: b08ef033817b5f9f76ce62dfcac7694e7b6b4006420372de22494503decac855 - md5: 346722a0be40f6edc53f12640d301338 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 2706396 - timestamp: 1718551242397 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.1-h7bae524_0.conda - sha256: ec238f18ce8140485645252351a0eca9ef4f7a1c568a420f240a585229bc12ef - md5: 7adba36492a1bb22d98ffffe4f6fc6de - depends: - - __osx >=11.0 - - libcxx >=16 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 2235747 - timestamp: 1718551382432 -- conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.1-he0c23c2_0.conda - sha256: 0524d0c0b61dacd0c22ac7a8067f977b1d52380210933b04141f5099c5b6fec7 - md5: 3d7c14285d3eb3239a76ff79063f27a5 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 1958151 - timestamp: 1718551737234 -- conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda - sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf - md5: 54898d0f524c9dee622d44bbb081a8ab - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/appnope?source=hash-mapping - size: 10076 - timestamp: 1733332433806 -- conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - sha256: ee4da0f3fe9d59439798ee399ef3e482791e48784873d546e706d0935f9ff010 - md5: 9673a61a297b00016442e022d689faa6 - depends: - - python >=3.10 - constrains: - - astroid >=2,<5 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/asttokens?source=hash-mapping - size: 28797 - timestamp: 1763410017955 -- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda - sha256: c13d5e42d187b1d0255f591b7ce91201d4ed8a5370f0d986707a802c20c9d32f - md5: 537296d57ea995666c68c821b00e360b - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/attrs?source=compressed-mapping - size: 64759 - timestamp: 1764875182184 -- conda: https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py310h69bd2ac_0.conda - sha256: 6660be15a45175c98f750b8bbc3fd07e0da36043624b376de49769bd14a0a16f - md5: 276a3ddf300498921601822e3b407088 - depends: - - python - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - zstd >=1.5.7,<1.6.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=hash-mapping - size: 191286 - timestamp: 1767044984395 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/backports.zstd-1.3.0-py310h2d60bed_0.conda - sha256: e1be6c8ed4fc517e56628f1646fb44d9634e7273e87d1bba961163dd3b727caa - md5: 330de33b56b85ac0be5531c0304006f3 - depends: - - python - - python 3.10.* *_cpython - - __osx >=11.0 - - zstd >=1.5.7,<1.6.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=hash-mapping - size: 193486 - timestamp: 1767045052533 -- conda: https://conda.anaconda.org/conda-forge/win-64/backports.zstd-1.3.0-py310h458dff3_0.conda - sha256: ceb8b49b9bf0246b606089ce95e5afe0c4fd39ada3c8c381a3d03fd9beafba88 - md5: 9f9e5cd3aa06ea10681a65355f5dca09 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-3-Clause AND MIT AND EPL-2.0 - purls: - - pkg:pypi/backports-zstd?source=hash-mapping - size: 190164 - timestamp: 1767045016166 -- conda: https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda - sha256: e7af5d1183b06a206192ff440e08db1c4e8b2ca1f8376ee45fb2f3a85d4ee45d - md5: 2c2fae981fd2afd00812c92ac47d023d - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 - - zstd >=1.5.6,<1.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 48427 - timestamp: 1733513201413 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/blosc-1.21.6-h7dd00d9_1.conda - sha256: c3fe902114b9a3ac837e1a32408cc2142c147ec054c1038d37aec6814343f48a - md5: 925acfb50a750aa178f7a0aced77f351 - depends: - - __osx >=11.0 - - libcxx >=18 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 - - zstd >=1.5.6,<1.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 33602 - timestamp: 1733513285902 -- conda: https://conda.anaconda.org/conda-forge/win-64/blosc-1.21.6-hfd34d9b_1.conda - sha256: 9303a7a0e03cf118eab3691013f6d6cbd1cbac66efbc70d89b20f5d0145257c0 - md5: 357d7be4146d5fec543bfaa96a8a40de - depends: - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - snappy >=1.2.1,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.6,<1.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 49840 - timestamp: 1733513605730 -- conda: https://conda.anaconda.org/conda-forge/noarch/branca-0.8.2-pyhd8ed1ab_0.conda - sha256: 1acf87c77d920edd098ddc91fa785efc10de871465dee0f463815b176e019e8b - md5: 1fcdf88e7a8c296d3df8409bf0690db4 - depends: - - jinja2 >=3 - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/branca?source=hash-mapping - size: 30176 - timestamp: 1759755695447 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda - sha256: e511644d691f05eb12ebe1e971fd6dc3ae55a4df5c253b4e1788b789bdf2dfa6 - md5: 8ccf913aaba749a5496c17629d859ed1 - depends: - - __glibc >=2.17,<3.0.a0 - - brotli-bin 1.2.0 hb03c661_1 - - libbrotlidec 1.2.0 hb03c661_1 - - libbrotlienc 1.2.0 hb03c661_1 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 20103 - timestamp: 1764017231353 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda - sha256: 422ac5c91f8ef07017c594d9135b7ae068157393d2a119b1908c7e350938579d - md5: 48ece20aa479be6ac9a284772827d00c - depends: - - __osx >=11.0 - - brotli-bin 1.2.0 hc919400_1 - - libbrotlidec 1.2.0 hc919400_1 - - libbrotlienc 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: [] - size: 20237 - timestamp: 1764018058424 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda - sha256: a4fffdf1c9b9d3d0d787e20c724cff3a284dfa3773f9ce609c93b1cfd0ce8933 - md5: bc58fdbced45bb096364de0fba1637af - depends: - - brotli-bin 1.2.0 hfd05255_1 - - libbrotlidec 1.2.0 hfd05255_1 - - libbrotlienc 1.2.0 hfd05255_1 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 20342 - timestamp: 1764017988883 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda - sha256: 64b137f30b83b1dd61db6c946ae7511657eead59fdf74e84ef0ded219605aa94 - md5: af39b9a8711d4a8d437b52c1d78eb6a1 - depends: - - __glibc >=2.17,<3.0.a0 - - libbrotlidec 1.2.0 hb03c661_1 - - libbrotlienc 1.2.0 hb03c661_1 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 21021 - timestamp: 1764017221344 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda - sha256: e2d142052a83ff2e8eab3fe68b9079cad80d109696dc063a3f92275802341640 - md5: 377d015c103ad7f3371be1777f8b584c - depends: - - __osx >=11.0 - - libbrotlidec 1.2.0 hc919400_1 - - libbrotlienc 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: [] - size: 18628 - timestamp: 1764018033635 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda - sha256: e76966232ef9612de33c2087e3c92c2dc42ea5f300050735a3c646f33bce0429 - md5: 6abd7089eb3f0c790235fe469558d190 - depends: - - libbrotlidec 1.2.0 hfd05255_1 - - libbrotlienc 1.2.0 hfd05255_1 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 22714 - timestamp: 1764017952449 -- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py310hba01987_1.conda - sha256: f036fe554d902549f86689a9650a0996901d5c9242b0a1e3fbfe6dbccd2ae011 - md5: 393fca4557fbd2c4d995dcb89f569048 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - constrains: - - libbrotlicommon 1.2.0 hb03c661_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 367099 - timestamp: 1764017439384 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.2.0-py310h6123dab_1.conda - sha256: 317f9b0ab95739a6739e577dee1d4fe2d07fbbe1a97109d145f0de3204cfc7d6 - md5: d9359ff9677b23fb89005e3b8dbe8139 - depends: - - __osx >=11.0 - - libcxx >=19 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - constrains: - - libbrotlicommon 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 359599 - timestamp: 1764018669488 -- conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.2.0-py310hfff998d_1.conda - sha256: fd250a4f92c2176f23dd4e07de1faf76741dabcc8fa00b182748db4d9578ff7e - md5: 0caf12fa6690b7f64883b2239853dda0 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libbrotlicommon 1.2.0 hfd05255_1 - license: MIT - license_family: MIT - purls: - - pkg:pypi/brotli?source=hash-mapping - size: 335476 - timestamp: 1764018212429 -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 - md5: d2ffd7602c02f2b316fd921d39876885 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 260182 - timestamp: 1771350215188 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df - md5: 620b85a3f45526a8bc4d23fd78fc22f0 - depends: - - __osx >=11.0 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 124834 - timestamp: 1771350416561 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda - sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 - md5: 4cb8e6b48f67de0b018719cdf1136306 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: bzip2-1.0.6 - license_family: BSD - purls: [] - size: 56115 - timestamp: 1771350256444 -- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e - md5: 920bb03579f15389b9e512095ad995b7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 207882 - timestamp: 1765214722852 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda - sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 - md5: bcb3cba70cf1eec964a03b4ba7775f01 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 180327 - timestamp: 1765215064054 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda - sha256: 4ddcb01be03f85d3db9d881407fb13a673372f1b9fac9c836ea441893390e049 - md5: 84d389c9eee640dda3d26fc5335c67d8 - depends: - - __win - license: ISC - purls: [] - size: 147139 - timestamp: 1767500904211 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda - sha256: b5974ec9b50e3c514a382335efa81ed02b05906849827a34061c496f4defa0b2 - md5: bddacf101bb4dd0e51811cb69c7790e2 - depends: - - __unix - license: ISC - purls: [] - size: 146519 - timestamp: 1767500828366 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - sha256: 3bd6a391ad60e471de76c0e9db34986c4b5058587fbf2efa5a7f54645e28c2c7 - md5: 09262e66b19567aff4f592fb53b28760 - depends: - - __glibc >=2.17,<3.0.a0 - - fontconfig >=2.15.0,<3.0a0 - - fonts-conda-ecosystem - - freetype >=2.12.1,<3.0a0 - - icu >=75.1,<76.0a0 - - libexpat >=2.6.4,<3.0a0 - - libgcc >=13 - - libglib >=2.82.2,<3.0a0 - - libpng >=1.6.47,<1.7.0a0 - - libstdcxx >=13 - - libxcb >=1.17.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - pixman >=0.44.2,<1.0a0 - - xorg-libice >=1.1.2,<2.0a0 - - xorg-libsm >=1.2.5,<2.0a0 - - xorg-libx11 >=1.8.11,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxrender >=0.9.12,<0.10.0a0 - license: LGPL-2.1-only or MPL-1.1 - purls: [] - size: 978114 - timestamp: 1741554591855 -- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda - sha256: b9f577bddb033dba4533e851853924bfe7b7c1623d0697df382eef177308a917 - md5: 20e32ced54300292aff690a69c5e7b97 - depends: - - fontconfig >=2.15.0,<3.0a0 - - fonts-conda-ecosystem - - freetype >=2.12.1,<3.0a0 - - icu >=75.1,<76.0a0 - - libexpat >=2.6.4,<3.0a0 - - libglib >=2.82.2,<3.0a0 - - libpng >=1.6.47,<1.7.0a0 - - libzlib >=1.3.1,<2.0a0 - - pixman >=0.44.2,<1.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LGPL-2.1-only or MPL-1.1 - purls: [] - size: 1524254 - timestamp: 1741555212198 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda - sha256: 110338066d194a715947808611b763857c15458f8b3b97197387356844af9450 - md5: eacc711330cd46939f66cd401ff9c44b - depends: - - python >=3.10 - license: ISC - purls: - - pkg:pypi/certifi?source=compressed-mapping - size: 150969 - timestamp: 1767500900768 -- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - sha256: b32f8362e885f1b8417bac2b3da4db7323faa12d5db62b7fd6691c02d60d6f59 - md5: a22d1fd9bf98827e280a02875d9a007a - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/charset-normalizer?source=hash-mapping - size: 50965 - timestamp: 1760437331772 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda - sha256: 38cfe1ee75b21a8361c8824f5544c3866f303af1762693a178266d7f198e8715 - md5: ea8a6c3256897cc31263de9f455e25d9 - depends: - - python >=3.10 - - __unix - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=hash-mapping - size: 97676 - timestamp: 1764518652276 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyha7b4d00_1.conda - sha256: c3bc9a49930fa1c3383a1485948b914823290efac859a2587ca57a270a652e08 - md5: 6cd3ccc98bacfcc92b2bd7f236f01a7e - depends: - - python >=3.10 - - colorama - - __win - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=hash-mapping - size: 96620 - timestamp: 1764518654675 -- conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1.2-pyhd8ed1ab_0.conda - sha256: ba1ee6e2b2be3da41d70d0d51d1159010de900aa3f33fceaea8c52e9bd30a26e - md5: e9b05deb91c013e5224672a4ba9cf8d1 - depends: - - click >=4.0 - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click-plugins?source=hash-mapping - size: 12683 - timestamp: 1750848314962 -- conda: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_2.conda - sha256: 1a52ae1febfcfb8f56211d1483a1ac4419b0028b7c3e9e61960a298978a42396 - md5: 55c7804f428719241a90b152016085a1 - depends: - - click >=4.0 - - python >=3.9,<4.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cligj?source=hash-mapping - size: 12521 - timestamp: 1733750069604 -- conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 - md5: 962b9857ee8e7018c22f2776ffa0b2d7 - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/colorama?source=hash-mapping - size: 27011 - timestamp: 1733218222191 -- conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - sha256: 576a44729314ad9e4e5ebe055fbf48beb8116b60e58f9070278985b2b634f212 - md5: 2da13f2b299d8e1995bafbbe9689a2f7 - depends: - - python >=3.9 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/comm?source=hash-mapping - size: 14690 - timestamp: 1753453984907 -- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py310h3788b33_0.conda - sha256: 5231c1b68e01a9bc9debabc077a6fb48c4395206d59f40a4598d1d5e353e11d8 - md5: b6420d29123c7c823de168f49ccdfe6a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.23 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 261280 - timestamp: 1744743236964 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.2-py310h7f4e7e6_0.conda - sha256: 758a7a858d8a5dca265e0754c73659690a99226e7e8d530666fece3b38e44558 - md5: 18ad60675af8d74a6e49bf40055419d0 - depends: - - __osx >=11.0 - - libcxx >=18 - - numpy >=1.23 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 231970 - timestamp: 1744743542215 -- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py310hc19bc0b_0.conda - sha256: 096a7cf6bf77faf3e093936d831118151781ddbd2ab514355ee2f0104b490b1e - md5: 039416813b5290e7d100a05bb4326110 - depends: - - numpy >=1.23 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/contourpy?source=hash-mapping - size: 201075 - timestamp: 1744743764641 -- conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda - sha256: bb47aec5338695ff8efbddbc669064a3b10fe34ad881fb8ad5d64fbfa6910ed1 - md5: 4c2a8fef270f6c69591889b93f9f55c1 - depends: - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/cycler?source=hash-mapping - size: 14778 - timestamp: 1764466758386 -- conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda - sha256: ee09ad7610c12c7008262d713416d0b58bf365bc38584dce48950025850bdf3f - md5: cae723309a49399d2949362f4ab5c9e4 - depends: - - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libntlm >=1.8,<2.0a0 - - libstdcxx >=13 - - libxcrypt >=4.4.36 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause-Attribution - license_family: BSD - purls: [] - size: 209774 - timestamp: 1750239039316 -- pypi: https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl - name: cython - version: 3.0.11 - sha256: 0e25f6425ad4a700d7f77cd468da9161e63658837d1bc34861a9861a4ef6346d - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/f0/89/b1ae45689abecca777f95462781a76e67ff46b55495a481ec5a73a739994/Cython-3.0.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: cython - version: 3.0.11 - sha256: d89a82937ce4037f092e9848a7bbcc65bc8e9fc9aef2bb74f5c15e7d21a73080 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- pypi: https://files.pythonhosted.org/packages/f9/de/19fdd1c7a52e0534bf5f544e0346c15d71d20338dbd013117f763b94613f/Cython-3.0.11-cp310-cp310-win_amd64.whl - name: cython - version: 3.0.11 - sha256: d02f4ebe15aac7cdacce1a628e556c1983f26d140fd2e0ac5e0a090e605a2d38 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*' -- conda: https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda - sha256: 22053a5842ca8ee1cf8e1a817138cdb5e647eb2c46979f84153f6ad7bde73020 - md5: 418c6ca5929a611cbd69204907a83995 - depends: - - libgcc-ng >=12 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 760229 - timestamp: 1685695754230 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/dav1d-1.2.1-hb547adb_0.conda - sha256: 93e077b880a85baec8227e8c72199220c7f87849ad32d02c14fb3807368260b8 - md5: 5a74cdee497e6b65173e10d94582fae6 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 316394 - timestamp: 1685695959391 -- conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda - sha256: 2aa2083c9c186da7d6f975ccfbef654ed54fff27f4bc321dbcd12cee932ec2c4 - md5: ed2c27bda330e3f0ab41577cf8b9b585 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 618643 - timestamp: 1685696352968 -- conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - sha256: 8f5f995699a2d9dbdd62c61385bfeeb57c82a681a7c8c5313c395aa0ccab68a5 - md5: ecfff944ba3960ecb334b9a2663d708d - depends: - - expat >=2.4.2,<3.0a0 - - libgcc-ng >=9.4.0 - - libglib >=2.70.2,<3.0a0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 618596 - timestamp: 1640112124844 -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py310h25320af_0.conda - sha256: 129b1c9a2a2ed1fc3cdb2005d0af8bd1e4d12486c9d27fd5b154d39b4c2373a7 - md5: 6ae8cc92dfb0b063519b9203445506af - depends: - - python - - libgcc >=14 - - libstdcxx >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2234314 - timestamp: 1769744974941 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.20-py310h19b6747_0.conda - sha256: 2ab1ec63052db574f7114ce3baa51905f1bc7a45eb546a549f72bcbbede8ff8a - md5: 0ea5aa84f85cb3d7be64bdab143a6b95 - depends: - - python - - __osx >=11.0 - - libcxx >=19 - - python 3.10.* *_cpython - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 2223547 - timestamp: 1769744999621 -- conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.20-py310h699e580_0.conda - sha256: 54fe3d0c32dca060666828e216d92a68c59de9a154c8e21d9800714cd3ba32c3 - md5: b2593f2b78589063833a245823e830ed - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/debugpy?source=hash-mapping - size: 3481569 - timestamp: 1769745019386 -- conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - sha256: c17c6b9937c08ad63cb20a26f403a3234088e57d4455600974a0ce865cb14017 - md5: 9ce473d1d1be1cc3810856a48b3fab32 - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/decorator?source=hash-mapping - size: 14129 - timestamp: 1740385067843 -- pypi: https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl - name: dill - version: 0.3.9 - sha256: 468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a - requires_dist: - - objgraph>=1.7.2 ; extra == 'graph' - - gprof2dot>=2022.7.29 ; extra == 'profile' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda - sha256: 1bcc132fbcc13f9ad69da7aa87f60ea41de7ed4d09f3a00ff6e0e70e1c690bc2 - md5: bfd56492d8346d669010eccafe0ba058 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 69544 - timestamp: 1739569648873 -- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda - sha256: b1fee32ef36a98159f0a2a96c4e734dfc9adff73acd444940831b22c1fb6d5c0 - md5: e9a1402439c18a4e3c7a52e4246e9e1c - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 71355 - timestamp: 1739570178995 -- conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda - sha256: ee6cf346d017d954255bbcbdb424cddea4d14e4ed7e9813e429db1d795d01144 - md5: 8e662bd460bda79b1ea39194e3c4c9ab - depends: - - python >=3.10 - - typing_extensions >=4.6.0 - license: MIT and PSF-2.0 - purls: - - pkg:pypi/exceptiongroup?source=hash-mapping - size: 21333 - timestamp: 1763918099466 -- conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda - sha256: 210c8165a58fdbf16e626aac93cc4c14dbd551a01d1516be5ecad795d2422cad - md5: ff9efb7f7469aed3c4a8106ffa29593c - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/executing?source=hash-mapping - size: 30753 - timestamp: 1756729456476 -- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.4-hecca717_0.conda - sha256: 0cc345e4dead417996ce9a1f088b28d858f03d113d43c1963d29194366dcce27 - md5: a0535741a4934b3e386051065c58761a - depends: - - __glibc >=2.17,<3.0.a0 - - libexpat 2.7.4 hecca717_0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 145274 - timestamp: 1771259434699 -- pypi: https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl - name: fastjsonschema - version: 2.21.2 - sha256: 1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 - requires_dist: - - colorama ; extra == 'devel' - - jsonschema ; extra == 'devel' - - json-spec ; extra == 'devel' - - pylint ; extra == 'devel' - - pytest ; extra == 'devel' - - pytest-benchmark ; extra == 'devel' - - pytest-cache ; extra == 'devel' - - validictory ; extra == 'devel' -- conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.10.1-py310h0aed7a2_3.conda - sha256: 69d5f613a3002859784ba82259aa67a930bfe00de70551ba47e28c846ba610ec - md5: 159a16dee358df063730c205f7428993 - depends: - - __glibc >=2.17,<3.0.a0 - - attrs >=19.2.0 - - click >=8.0,<9.dev0 - - click-plugins >=1.0 - - cligj >=0.5 - - libgcc >=13 - - libgdal-core >=3.10.0,<3.11.0a0 - - libstdcxx >=13 - - pyparsing - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - shapely - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/fiona?source=hash-mapping - size: 1140688 - timestamp: 1733507676726 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.10.1-py310hd68230c_3.conda - sha256: 2ded6e797861878f87ce5c25c403221f075d10a009c0b6c4ebec8aa81391a159 - md5: e8fc7492c6e613d0d337624031ea404b - depends: - - __osx >=11.0 - - attrs >=19.2.0 - - click >=8.0,<9.dev0 - - click-plugins >=1.0 - - cligj >=0.5 - - libcxx >=18 - - libgdal-core >=3.10.0,<3.11.0a0 - - pyparsing - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - - shapely - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/fiona?source=hash-mapping - size: 1002256 - timestamp: 1733507830986 -- conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.10.1-py310hf80745b_3.conda - sha256: 89f54fad0277aacdda7b29ec8aae3cf323174eeb1ec0b0bb3dd6f8fc12682620 - md5: aebf566da9c4b92954a60f6765ac40de - depends: - - attrs >=19.2.0 - - click >=8.0,<9.dev0 - - click-plugins >=1.0 - - cligj >=0.5 - - libgdal-core >=3.10.0,<3.11.0a0 - - pyparsing - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - shapely - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/fiona?source=hash-mapping - size: 957762 - timestamp: 1733507936027 -- conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.20.0-pyhd8ed1ab_0.conda - sha256: 782fa186d7677fd3bc1ff7adb4cc3585f7d2c7177c30bcbce21f8c177135c520 - md5: a6997a7dcd6673c0692c61dfeaea14ab - depends: - - branca >=0.6.0 - - jinja2 >=2.9 - - numpy - - python >=3.9 - - requests - - xyzservices - license: MIT - license_family: MIT - purls: - - pkg:pypi/folium?source=hash-mapping - size: 82665 - timestamp: 1750113928159 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b - md5: 0c96522c6bdaed4b1566d11387caaf45 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 397370 - timestamp: 1566932522327 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c - md5: 34893075a5c9e55cdafac56607368fc6 - license: OFL-1.1 - license_family: Other - purls: [] - size: 96530 - timestamp: 1620479909603 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 - md5: 4d59c254e01d9cde7957100457e2d5fb - license: OFL-1.1 - license_family: Other - purls: [] - size: 700814 - timestamp: 1620479612257 -- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 - md5: 49023d73832ef61042f6a237cb2687e7 - license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 - license_family: Other - purls: [] - size: 1620504 - timestamp: 1727511233259 -- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda - sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c - md5: 867127763fbe935bab59815b6e0b7b5c - depends: - - __glibc >=2.17,<3.0.a0 - - libexpat >=2.7.4,<3.0a0 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - libgcc >=14 - - libuuid >=2.41.3,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 270705 - timestamp: 1771382710863 -- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda - sha256: ff2db9d305711854de430f946dc59bd40167940a1de38db29c5a78659f219d9c - md5: a0b1b87e871011ca3b783bbf410bc39f - depends: - - libexpat >=2.7.4,<3.0a0 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - libiconv >=1.18,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 195332 - timestamp: 1771382820659 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 - md5: fee5683a3f04bd15cbd8318b096a27ab - depends: - - fonts-conda-forge - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 3667 - timestamp: 1566974674465 -- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 - md5: a7970cd949a077b7cb9696379d338681 - depends: - - font-ttf-ubuntu - - font-ttf-inconsolata - - font-ttf-dejavu-sans-mono - - font-ttf-source-code-pro - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 4059 - timestamp: 1762351264405 -- conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py310h3406613_0.conda - sha256: 6dccba7a293b6dbab029da4d921d2d94227c9541152489fc7d7db4ec3c68dff3 - md5: 24fa891e40acdb1c7f51efd0c5f97084 - depends: - - __glibc >=2.17,<3.0.a0 - - brotli - - libgcc >=14 - - munkres - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - unicodedata2 >=15.1.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/fonttools?source=hash-mapping - size: 2446291 - timestamp: 1765632899119 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py310hf4fd40f_0.conda - sha256: 67518a55dc2295409791319e0276fc8ec25e29fe9452867579da45d08cf8aa9c - md5: a85ff44569675422773962490c80dd0b - depends: - - __osx >=11.0 - - brotli - - munkres - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - - unicodedata2 >=15.1.0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/fonttools?source=hash-mapping - size: 2353815 - timestamp: 1765633031708 -- conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py310hdb0e946_0.conda - sha256: 433be2ca71f302bb9fa6bde0b842417f2ab9b203fae8547ce95a3def9edfc9e3 - md5: c2b488b68301c02d503e5cc9ee7bafc8 - depends: - - brotli - - munkres - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - unicodedata2 >=15.1.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: - - pkg:pypi/fonttools?source=hash-mapping - size: 2011123 - timestamp: 1765632908321 -- conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda - sha256: bf8e4dffe46f7d25dc06f31038cacb01672c47b9f45201f065b0f4d00ab0a83e - md5: 4afc585cd97ba8a23809406cd8a9eda8 - depends: - - libfreetype 2.14.1 ha770c72_0 - - libfreetype6 2.14.1 h73754d4_0 - license: GPL-2.0-only OR FTL - purls: [] - size: 173114 - timestamp: 1757945422243 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda - sha256: 14427aecd72e973a73d5f9dfd0e40b6bc3791d253de09b7bf233f6a9a190fd17 - md5: 1ec9a1ee7a2c9339774ad9bb6fe6caec - depends: - - libfreetype 2.14.1 hce30654_0 - - libfreetype6 2.14.1 h6da58f4_0 - license: GPL-2.0-only OR FTL - purls: [] - size: 173399 - timestamp: 1757947175403 -- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda - sha256: a9b3313edea0bf14ea6147ea43a1059d0bf78771a1336d2c8282891efc57709a - md5: d69c21967f35eb2ce7f1f85d6b6022d3 - depends: - - libfreetype 2.14.1 h57928b3_0 - - libfreetype6 2.14.1 hdbac1cb_0 - license: GPL-2.0-only OR FTL - purls: [] - size: 184553 - timestamp: 1757946164012 -- conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h9dce30a_2.conda - sha256: c8960e00a6db69b85c16c693ce05484facf20f1a80430552145f652a880e0d2a - md5: ecb5d11305b8ba1801543002e69d2f2f - depends: - - __glibc >=2.17,<3.0.a0 - - libexpat >=2.6.4,<3.0a0 - - libgcc >=13 - - libiconv >=1.17,<2.0a0 - - minizip >=4.0.7,<5.0a0 - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 59299 - timestamp: 1734014884486 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-h3ab3353_2.conda - sha256: b4146ac9ba1676494e3d812ca39664dd7dd454e4d0984f3665fd6feec318c71c - md5: dd655a29b40fe0d1bf95c64cf3cb348d - depends: - - __osx >=11.0 - - libexpat >=2.6.4,<3.0a0 - - libiconv >=1.17,<2.0a0 - - minizip >=4.0.7,<5.0a0 - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 53378 - timestamp: 1734014980768 -- conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-hf297d47_2.conda - sha256: 1e62cbc6daa74656034dc4a6e58faa2d50291719c1cba53cc0b1946f0d2b9404 - md5: d6a8059de245e53478b581742b53f71d - depends: - - libexpat >=2.6.4,<3.0a0 - - libiconv >=1.17,<2.0a0 - - minizip >=4.0.7,<5.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 77528 - timestamp: 1734015193826 -- conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-1.0.1-pyhd8ed1ab_3.conda - sha256: 04f7e616ebbf6352ff852b53c57901e43f14e2b3c92411f99b5547f106bc192e - md5: 1baca589eb35814a392eaad6d152447e - depends: - - folium - - geopandas-base 1.0.1 pyha770c72_3 - - mapclassify >=2.4.0 - - matplotlib-base - - pyogrio >=0.7.2 - - pyproj >=3.3.0 - - python >=3.9 - - xyzservices - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 7583 - timestamp: 1734346218849 -- conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-1.0.1-pyha770c72_3.conda - sha256: 2d031871b57c6d4e5e2d6cc23bd6d4e0084bb52ebca5c1b20bf06d03749e0f24 - md5: e8343d1b635bf09dafdd362d7357f395 - depends: - - numpy >=1.22 - - packaging - - pandas >=1.4.0 - - python >=3.9 - - shapely >=2.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/geopandas?source=hash-mapping - size: 239261 - timestamp: 1734346217454 -- conda: https://conda.anaconda.org/conda-forge/linux-64/geos-3.13.0-h5888daf_0.conda - sha256: 5c70d6d16e044859edca85feb9d4f1c3c6062aaf88d650826f5ccdf8c44336de - md5: 40b4ab956c90390e407bb177f8a58bab - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - license: LGPL-2.1-only - purls: [] - size: 1869233 - timestamp: 1725676083126 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/geos-3.13.0-hf9b8971_0.conda - sha256: 273381020b72bde1597d4e07e855ed50ffac083512e61ccbdd99d93f03c6cbf2 - md5: 45b2e9adb9663644b1eefa5300b9eef3 - depends: - - __osx >=11.0 - - libcxx >=17 - license: LGPL-2.1-only - purls: [] - size: 1481430 - timestamp: 1725676193541 -- conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.13.0-h5a68840_0.conda - sha256: 2b46d6f304f70dfca304169299908b558bd1e83992acb5077766eefa3d3fe35f - md5: 08a30fe29a645fc5c768c0968db116d3 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LGPL-2.1-only - purls: [] - size: 1665961 - timestamp: 1725676536384 -- conda: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.4-h3551947_0.conda - sha256: a5c6bf5654cf7e96d44aaac68b4b654a9e148b811e5b0f36ba7d70db87416fff - md5: 5998212641e3feb3660295eacc717139 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libstdcxx >=13 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - zlib - license: MIT - license_family: MIT - purls: [] - size: 129359 - timestamp: 1739974781272 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/geotiff-1.7.4-hbef4fa4_0.conda - sha256: e0d914bab03a578ace37cb45446249f8e23a36d80cf866e37c582e7f9d6eca0e - md5: c01fde51346f834d3f80affab45f0740 - depends: - - __osx >=11.0 - - libcxx >=18 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - zlib - license: MIT - license_family: MIT - purls: [] - size: 112457 - timestamp: 1739974826028 -- conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.4-h887f4e7_0.conda - sha256: f0435dd63c97ad9e8d35a2c1d55c823c50dac82a8dffd8d41c79c0305fa0cc2b - md5: d5edee34ab83553450b1225cf0a14273 - depends: - - libjpeg-turbo >=3.0.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zlib - license: MIT - license_family: MIT - purls: [] - size: 123341 - timestamp: 1739975151946 -- conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda - sha256: aac402a8298f0c0cc528664249170372ef6b37ac39fdc92b40601a6aed1e32ff - md5: 3bf7b9fd5a7136126e0234db4b87c8b6 - depends: - - libgcc-ng >=12 - license: MIT - license_family: MIT - purls: [] - size: 77248 - timestamp: 1712692454246 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda - sha256: 843b3f364ff844137e37d5c0a181f11f6d51adcedd216f019d074e5aa5d7e09c - md5: 95fa1486c77505330c20f7202492b913 - license: MIT - license_family: MIT - purls: [] - size: 71613 - timestamp: 1712692611426 -- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda - sha256: 25ba37da5c39697a77fce2c9a15e48cf0a84f1464ad2aafbe53d8357a9f6cc8c - md5: 2cd94587f3a401ae05e03a6caf09539d - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 99596 - timestamp: 1755102025473 -- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda - sha256: 5f1714b07252f885a62521b625898326ade6ca25fbc20727cfe9a88f68a54bfd - md5: b785694dd3ec77a011ccf0c24725382b - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LGPL-2.0-or-later - license_family: LGPL - purls: [] - size: 96336 - timestamp: 1755102441729 -- conda: https://conda.anaconda.org/gurobi/linux-64/gurobi-13.0.1-py310_0.conda - sha256: b42f58d198d7616ac7aec050598c7515bb0de9670eb9fdec147e76fd0afe8601 - md5: 65c0ff34413231cc42e2c5f519981ffd - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: PROPRIETARY - size: 48151839 - timestamp: 1768424392860 -- conda: https://conda.anaconda.org/gurobi/osx-arm64/gurobi-13.0.1-py310_0.conda - sha256: 04430764767d96724ce1f1b053c657c7d30905bd3c5d49a4a68e4ccb208010ee - md5: 93bedecb20f0fe58107ea3553b9c403e - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: PROPRIETARY - size: 44146772 - timestamp: 1768422175898 -- conda: https://conda.anaconda.org/gurobi/win-64/gurobi-13.0.1-py310_0.conda - sha256: ec49cd6abec06877774b53ca1c24e699ac3e162690856b2f5058cc065c28fd15 - md5: 0db05bb47f7fc6975eb24964788f6765 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: PROPRIETARY - size: 44075259 - timestamp: 1768418153345 -- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 - md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 - depends: - - python >=3.10 - - hyperframe >=6.1,<7 - - hpack >=4.1,<5 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/h2?source=hash-mapping - size: 95967 - timestamp: 1756364871835 -- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda - sha256: 5bd0f3674808862838d6e2efc0b3075e561c34309c5c2f4c976f7f1f57c91112 - md5: 0e6e192d4b3d95708ad192d957cf3163 - depends: - - __glibc >=2.17,<3.0.a0 - - cairo >=1.18.4,<2.0a0 - - freetype - - graphite2 - - icu >=75.1,<76.0a0 - - libexpat >=2.7.0,<3.0a0 - - libfreetype >=2.13.3 - - libfreetype6 >=2.13.3 - - libgcc >=13 - - libglib >=2.84.1,<3.0a0 - - libstdcxx >=13 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 1730226 - timestamp: 1747091044218 -- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.0.0-h9e37d49_0.conda - sha256: f1ab5960a52a11186f528249bec5ce5e43bb4c44c87ffa24334255f07c3fd4b8 - md5: b7648427f5b6797ae3904ad76e4c7f19 - depends: - - cairo >=1.18.4,<2.0a0 - - freetype >=2.13.3,<3.0a0 - - graphite2 - - icu >=75.1,<76.0a0 - - libexpat >=2.6.4,<3.0a0 - - libglib >=2.84.0,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 1125019 - timestamp: 1743083466989 -- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba - md5: 0a802cb9888dd14eeefc611f05c40b6e - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/hpack?source=hash-mapping - size: 30731 - timestamp: 1737618390337 -- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 - md5: 8e6923fc12f1fe8f8c4e5c9f343256ac - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/hyperframe?source=hash-mapping - size: 17397 - timestamp: 1737618427549 -- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e - md5: 8b189310083baabfb622af68fd9d3ae3 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: MIT - license_family: MIT - purls: [] - size: 12129203 - timestamp: 1720853576813 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 - md5: 5eb22c1d7b3fc4abb50d92d621583137 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 11857802 - timestamp: 1720853997952 -- conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - sha256: 1d04369a1860a1e9e371b9fc82dd0092b616adcf057d6c88371856669280e920 - md5: 8579b6bb8d18be7c0b27fb08adeeeb40 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 14544252 - timestamp: 1720853966338 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 - md5: 53abe63df7e10a6ba605dc5f9f961d36 - depends: - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/idna?source=hash-mapping - size: 50721 - timestamp: 1760286526795 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh5552912_1.conda - sha256: 5c1f3e874adaf603449f2b135d48f168c5d510088c78c229bda0431268b43b27 - md5: 4b53d436f3fbc02ce3eeaf8ae9bebe01 - depends: - - appnope - - __osx - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipykernel?source=compressed-mapping - size: 132260 - timestamp: 1770566135697 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda - sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 - md5: b3a7d5842f857414d9ae831a799444dd - depends: - - __win - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipykernel?source=compressed-mapping - size: 132382 - timestamp: 1770566174387 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyha191276_1.conda - sha256: b77ed58eb235e5ad80e742b03caeed4bbc2a2ef064cb9a2deee3b75dfae91b2a - md5: 8b267f517b81c13594ed68d646fd5dcb - depends: - - __linux - - comm >=0.1.1 - - debugpy >=1.6.5 - - ipython >=7.23.1 - - jupyter_client >=8.8.0 - - jupyter_core >=5.1,!=6.0.* - - matplotlib-inline >=0.1 - - nest-asyncio >=1.4 - - packaging >=22 - - psutil >=5.7 - - python >=3.10 - - pyzmq >=25 - - tornado >=6.4.1 - - traitlets >=5.4.0 - - python - constrains: - - appnope >=0.1.2 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipykernel?source=compressed-mapping - size: 133644 - timestamp: 1770566133040 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyh8f84b5b_0.conda - sha256: e43fa762183b49c3c3b811d41259e94bb14b7bff4a239b747ef4e1c6bbe2702d - md5: 177cfa19fe3d74c87a8889286dc64090 - depends: - - __unix - - pexpect >4.3 - - decorator - - exceptiongroup - - jedi >=0.16 - - matplotlib-inline - - pickleshare - - prompt-toolkit >=3.0.41,<3.1.0 - - pygments >=2.4.0 - - python >=3.10 - - stack_data - - traitlets >=5.13.0 - - typing_extensions >=4.6 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython?source=hash-mapping - size: 639160 - timestamp: 1748711175284 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.37.0-pyha7b4d00_0.conda - sha256: 4812e69a1c9d6d43746fa7e8efaf9127d257508249e7192e68cd163511a751ee - md5: 2ffea44095ca39b38b67599e8091bca3 - depends: - - __win - - colorama - - decorator - - exceptiongroup - - jedi >=0.16 - - matplotlib-inline - - pickleshare - - prompt-toolkit >=3.0.41,<3.1.0 - - pygments >=2.4.0 - - python >=3.10 - - stack_data - - traitlets >=5.13.0 - - typing_extensions >=4.6 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/ipython?source=hash-mapping - size: 638940 - timestamp: 1748711254071 -- conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda - sha256: 92c4d217e2dc68983f724aa983cca5464dcb929c566627b26a2511159667dba8 - md5: a4f4c5dc9b80bc50e0d3dc4e6e8f1bd9 - depends: - - parso >=0.8.3,<0.9.0 - - python >=3.9 - license: Apache-2.0 AND MIT - purls: - - pkg:pypi/jedi?source=hash-mapping - size: 843646 - timestamp: 1733300981994 -- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda - sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b - md5: 04558c96691bed63104678757beb4f8d - depends: - - markupsafe >=2.0 - - python >=3.10 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jinja2?source=compressed-mapping - size: 120685 - timestamp: 1764517220861 -- conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda - sha256: 301539229d7be6420c084490b8145583291123f0ce6b92f56be5948a2c83a379 - md5: 615de2a4d97af50c350e5cf160149e77 - depends: - - python >=3.10 - - setuptools - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/joblib?source=hash-mapping - size: 226448 - timestamp: 1765794135253 -- conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.18-h6688a6e_0.conda - sha256: 09e706cb388d3ea977fabcee8e28384bdaad8ce1fc49340df5f868a2bd95a7da - md5: 38f5dbc9ac808e31c00650f7be1db93f - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 82709 - timestamp: 1726487116178 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.18-he4178ee_0.conda - sha256: 73179a1cd0b45c09d4f631cb359d9e755e6e573c5d908df42006728e0bf8297c - md5: 94f14ef6157687c30feb44e1abecd577 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 73715 - timestamp: 1726487214495 -- pypi: https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl - name: jsonschema - version: 4.26.0 - sha256: d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce - requires_dist: - - attrs>=22.2.0 - - jsonschema-specifications>=2023.3.6 - - referencing>=0.28.4 - - rpds-py>=0.25.0 - - fqdn ; extra == 'format' - - idna ; extra == 'format' - - isoduration ; extra == 'format' - - jsonpointer>1.13 ; extra == 'format' - - rfc3339-validator ; extra == 'format' - - rfc3987 ; extra == 'format' - - uri-template ; extra == 'format' - - webcolors>=1.11 ; extra == 'format' - - fqdn ; extra == 'format-nongpl' - - idna ; extra == 'format-nongpl' - - isoduration ; extra == 'format-nongpl' - - jsonpointer>1.13 ; extra == 'format-nongpl' - - rfc3339-validator ; extra == 'format-nongpl' - - rfc3986-validator>0.1.0 ; extra == 'format-nongpl' - - rfc3987-syntax>=1.1.0 ; extra == 'format-nongpl' - - uri-template ; extra == 'format-nongpl' - - webcolors>=24.6.0 ; extra == 'format-nongpl' - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl - name: jsonschema-specifications - version: 2025.9.1 - sha256: 98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe - requires_dist: - - referencing>=0.31.0 - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda - sha256: e402bd119720862a33229624ec23645916a7d47f30e1711a4af9e005162b84f3 - md5: 8a3d6d0523f66cf004e563a50d9392b3 - depends: - - jupyter_core >=5.1 - - python >=3.10 - - python-dateutil >=2.8.2 - - pyzmq >=25.0 - - tornado >=6.4.1 - - traitlets >=5.3 - - python - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-client?source=compressed-mapping - size: 112785 - timestamp: 1767954655912 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyh6dadd2b_0.conda - sha256: ed709a6c25b731e01563521ef338b93986cd14b5bc17f35e9382000864872ccc - md5: a8db462b01221e9f5135be466faeb3e0 - depends: - - __win - - pywin32 - - platformdirs >=2.5 - - python >=3.10 - - traitlets >=5.3 - - python - constrains: - - pywin32 >=300 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-core?source=hash-mapping - size: 64679 - timestamp: 1760643889625 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - sha256: 1d34b80e5bfcd5323f104dbf99a2aafc0e5d823019d626d0dce5d3d356a2a52a - md5: b38fe4e78ee75def7e599843ef4c1ab0 - depends: - - __unix - - python - - platformdirs >=2.5 - - python >=3.10 - - traitlets >=5.3 - - python - constrains: - - pywin32 >=300 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/jupyter-core?source=hash-mapping - size: 65503 - timestamp: 1760643864586 -- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 - md5: b38117a3c920364aff79f870c984b4a3 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-or-later - purls: [] - size: 134088 - timestamp: 1754905959823 -- conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py310haaf941d_2.conda - sha256: 5ef8337c7a89719427d25b0cdc776b34116fe988efc9bf56f5a2831d74b1584e - md5: 7426d76535fc6347f1b74f85fb17d6eb - depends: - - python - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/kiwisolver?source=hash-mapping - size: 78299 - timestamp: 1762488741951 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py310h563d721_2.conda - sha256: 38d427a3d24ca94b4c424bcb0fdacde5a3a196c1be1aee84cf60edca98d6167a - md5: 1c29ffa84e75a6f8be4a8d8ddce17545 - depends: - - python - - python 3.10.* *_cpython - - __osx >=11.0 - - libcxx >=19 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/kiwisolver?source=hash-mapping - size: 65984 - timestamp: 1762488860157 -- conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py310h1e1005b_2.conda - sha256: dbca5656a0e07dbc998d4d5e51497782d2e0d9c097a1072a9d4df5e2ef797dce - md5: 6b165d2b50fce619244bec7495bbbbc2 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/kiwisolver?source=hash-mapping - size: 73319 - timestamp: 1762488749759 -- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 - md5: 3f43953b7d3fb3aaa1d0d0723d91e368 - depends: - - keyutils >=1.6.1,<2.0a0 - - libedit >=3.1.20191231,<3.2.0a0 - - libedit >=3.1.20191231,<4.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - openssl >=3.3.1,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 1370023 - timestamp: 1719463201255 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed - md5: e446e1822f4da8e5080a9de93474184d - depends: - - __osx >=11.0 - - libcxx >=19 - - libedit >=3.1.20250104,<3.2.0a0 - - libedit >=3.1.20250104,<4.0a0 - - openssl >=3.5.5,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 1160828 - timestamp: 1769770119811 -- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda - sha256: 18e8b3430d7d232dad132f574268f56b3eb1a19431d6d5de8c53c29e6c18fa81 - md5: 31aec030344e962fbd7dbbbbd68e60a9 - depends: - - openssl >=3.3.1,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 712034 - timestamp: 1719463874284 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - sha256: d6a61830a354da022eae93fa896d0991385a875c6bba53c82263a289deda9db8 - md5: 000e85703f0fd9594c81710dd5066471 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - license: MIT - license_family: MIT - purls: [] - size: 248046 - timestamp: 1739160907615 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda - sha256: 310a62c2f074ebd5aa43b3cd4b00d46385ce680fa2132ecee255a200e2d2f15f - md5: 92a61fd30b19ebd5c1621a5bfe6d8b5f - depends: - - __osx >=11.0 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - license: MIT - license_family: MIT - purls: [] - size: 212125 - timestamp: 1739161108467 -- conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda - sha256: 7712eab5f1a35ca3ea6db48ead49e0d6ac7f96f8560da8023e61b3dbe4f3b25d - md5: 3538827f77b82a837fa681a4579e37a1 - depends: - - libjpeg-turbo >=3.0.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 510641 - timestamp: 1739161381270 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda - sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 - md5: 12bd9a3f089ee6c9266a37dab82afabd - depends: - - __glibc >=2.17,<3.0.a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - binutils_impl_linux-64 2.45.1 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 725507 - timestamp: 1770267139900 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - sha256: 412381a43d5ff9bbed82cd52a0bbca5b90623f62e41007c9c42d3870c60945ff - md5: 9344155d33912347b37f0ae6c410a835 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 264243 - timestamp: 1745264221534 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda - sha256: 12361697f8ffc9968907d1a7b5830e34c670e4a59b638117a2cdfed8f63a38f8 - md5: a74332d9b60b62905e3d30709df08bf1 - depends: - - __osx >=11.0 - - libcxx >=18 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 188306 - timestamp: 1745264362794 -- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda - sha256: 868a3dff758cc676fa1286d3f36c3e0101cca56730f7be531ab84dc91ec58e9d - md5: c1b81da6d29a14b542da14a36c9fbf3f - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 164701 - timestamp: 1745264384716 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.7-h75ea233_4.conda - sha256: d49b2a3617b689763d1377a5d1fbfc3c914ee0afa26b3c1858e1c4329329c6df - md5: b80309616f188ac77c4740acba40f796 - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - libgcc >=13 - - liblzma >=5.8.1,<6.0a0 - - libxml2 >=2.13.7,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - lzo >=2.10,<3.0a0 - - openssl >=3.5.0,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 866358 - timestamp: 1745335292389 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.7-h3c2f2b0_4.conda - sha256: b7f862cfa4522dd4774c61376a95b1b3aea80ff0d42dd5ebf6c9a07d32eb6f18 - md5: 4b12c69a3c3ca02ceac535ae6168f3af - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2 >=2.13.7,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - lzo >=2.10,<3.0a0 - - openssl >=3.5.0,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 774033 - timestamp: 1745335663024 -- conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.7-h5343c79_4.conda - sha256: fd947dfdcf70b56dad679ec4053cc76cc69b208fb1220072d543482640f56c57 - md5: 3bb78f661ec0ac3cdbae48c880545f41 - depends: - - bzip2 >=1.0.8,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libxml2 >=2.13.7,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - lzo >=2.10,<3.0a0 - - openssl >=3.5.0,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.7,<1.6.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 1085438 - timestamp: 1745336188302 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda - sha256: f5ab201b8b4e1f776ced0340c59f87e441fd6763d3face527b5cf3f2280502c9 - md5: 22d5cc5fb45aab8ed3c00cde2938b825 - depends: - - __glibc >=2.17,<3.0.a0 - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - libgcc >=14 - - rav1e >=0.7.1,<0.8.0a0 - - svt-av1 >=4.0.0,<4.0.1.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 140323 - timestamp: 1769476997956 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libavif16-1.3.0-hde9513d_3.conda - sha256: 92eb3f8134586972145378b21ac789a65ee232d7c1ef01ce5bfc9e850d0e0e60 - md5: 6e9bcb90cfd20178a52f355030aba237 - depends: - - __osx >=11.0 - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - rav1e >=0.7.1,<0.8.0a0 - - svt-av1 >=4.0.0,<4.0.1.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 111474 - timestamp: 1769477399074 -- conda: https://conda.anaconda.org/conda-forge/win-64/libavif16-1.3.0-ha08a409_3.conda - sha256: 489379a872874af8939f9efeccf3c6ff6461d221fefae00c4c54b2eb3731b093 - md5: b1c835a63bee00ff1aaf94468fa18140 - depends: - - _libavif_api >=1.3.0,<1.3.1.0a0 - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - rav1e >=0.7.1,<0.8.0a0 - - svt-av1 >=4.0.0,<4.0.1.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 117410 - timestamp: 1769477171156 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda - build_number: 5 - sha256: 18c72545080b86739352482ba14ba2c4815e19e26a7417ca21a95b76ec8da24c - md5: c160954f7418d7b6e87eaf05a8913fa9 - depends: - - libopenblas >=0.3.30,<0.3.31.0a0 - - libopenblas >=0.3.30,<1.0a0 - constrains: - - mkl <2026 - - liblapack 3.11.0 5*_openblas - - libcblas 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18213 - timestamp: 1765818813880 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h51639a9_openblas.conda - build_number: 5 - sha256: 620a6278f194dcabc7962277da6835b1e968e46ad0c8e757736255f5ddbfca8d - md5: bcc025e2bbaf8a92982d20863fe1fb69 - depends: - - libopenblas >=0.3.30,<0.3.31.0a0 - - libopenblas >=0.3.30,<1.0a0 - constrains: - - libcblas 3.11.0 5*_openblas - - liblapack 3.11.0 5*_openblas - - liblapacke 3.11.0 5*_openblas - - blas 2.305 openblas - - mkl <2026 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18546 - timestamp: 1765819094137 -- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda - build_number: 5 - sha256: f0cb7b2697461a306341f7ff32d5b361bb84f3e94478464c1e27ee01fc8f276b - md5: f9decf88743af85c9c9e05556a4c47c0 - depends: - - mkl >=2025.3.0,<2026.0a0 - constrains: - - liblapack 3.11.0 5*_mkl - - libcblas 3.11.0 5*_mkl - - blas 2.305 mkl - - liblapacke 3.11.0 5*_mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 67438 - timestamp: 1765819100043 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda - sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e - md5: 72c8fd1af66bd67bf580645b426513ed - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 79965 - timestamp: 1764017188531 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda - sha256: a7cb9e660531cf6fbd4148cff608c85738d0b76f0975c5fc3e7d5e92840b7229 - md5: 006e7ddd8a110771134fcc4e1e3a6ffa - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 79443 - timestamp: 1764017945924 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda - sha256: 5097303c2fc8ebf9f9ea9731520aa5ce4847d0be41764edd7f6dee2100b82986 - md5: 444b0a45bbd1cb24f82eedb56721b9c4 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 82042 - timestamp: 1764017799966 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda - sha256: 12fff21d38f98bc446d82baa890e01fd82e3b750378fedc720ff93522ffb752b - md5: 366b40a69f0ad6072561c1d09301c886 - depends: - - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.2.0 hb03c661_1 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 34632 - timestamp: 1764017199083 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda - sha256: 2eae444039826db0454b19b52a3390f63bfe24f6b3e63089778dd5a5bf48b6bf - md5: 079e88933963f3f149054eec2c487bc2 - depends: - - __osx >=11.0 - - libbrotlicommon 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: [] - size: 29452 - timestamp: 1764017979099 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda - sha256: 3239ce545cf1c32af6fffb7fc7c75cb1ef5b6ea8221c66c85416bb2d46f5cccb - md5: 450e3ae947fc46b60f1d8f8f318b40d4 - depends: - - libbrotlicommon 1.2.0 hfd05255_1 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 34449 - timestamp: 1764017851337 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - sha256: a0c15c79997820bbd3fbc8ecf146f4fe0eca36cc60b62b63ac6cf78857f1dd0d - md5: 4ffbb341c8b616aa2494b6afb26a0c5f - depends: - - __glibc >=2.17,<3.0.a0 - - libbrotlicommon 1.2.0 hb03c661_1 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 298378 - timestamp: 1764017210931 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda - sha256: 01436c32bb41f9cb4bcf07dda647ce4e5deb8307abfc3abdc8da5317db8189d1 - md5: b2b7c8288ca1a2d71ff97a8e6a1e8883 - depends: - - __osx >=11.0 - - libbrotlicommon 1.2.0 hc919400_1 - license: MIT - license_family: MIT - purls: [] - size: 290754 - timestamp: 1764018009077 -- conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda - sha256: 3226df6b7df98734440739f75527d585d42ca2bfe912fbe8d1954c512f75341a - md5: ccd93cfa8e54fd9df4e83dbe55ff6e8c - depends: - - libbrotlicommon 1.2.0 hfd05255_1 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 252903 - timestamp: 1764017901735 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda - build_number: 5 - sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 - md5: 6636a2b6f1a87572df2970d3ebc87cc0 - depends: - - libblas 3.11.0 5_h4a7cf45_openblas - constrains: - - liblapacke 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapack 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18194 - timestamp: 1765818837135 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_hb0561ab_openblas.conda - build_number: 5 - sha256: 38809c361bbd165ecf83f7f05fae9b791e1baa11e4447367f38ae1327f402fc0 - md5: efd8bd15ca56e9d01748a3beab8404eb - depends: - - libblas 3.11.0 5_h51639a9_openblas - constrains: - - liblapacke 3.11.0 5*_openblas - - liblapack 3.11.0 5*_openblas - - blas 2.305 openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18548 - timestamp: 1765819108956 -- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda - build_number: 5 - sha256: 49dc59d8e58360920314b8d276dd80da7866a1484a9abae4ee2760bc68f3e68d - md5: b3fa8e8b55310ba8ef0060103afb02b5 - depends: - - libblas 3.11.0 5_hf2e6a31_mkl - constrains: - - liblapack 3.11.0 5*_mkl - - liblapacke 3.11.0 5*_mkl - - blas 2.305 mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 68079 - timestamp: 1765819124349 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.8-default_h99862b1_8.conda - sha256: e4dfc9b820a5f7bcc5862f0d275a2c85e838a2de9c6d1d10b048ab7570f8a968 - md5: 0071e5b9af13b5bcf39e371f3100ce3f - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libllvm20 >=20.1.8,<20.2.0a0 - - libstdcxx >=14 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 21291311 - timestamp: 1768845917554 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda - sha256: e6c0123b888d6abf03c66c52ed89f9de1798dde930c5fd558774f26e994afbc6 - md5: 327c78a8ce710782425a89df851392f7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libllvm21 >=21.1.0,<21.2.0a0 - - libstdcxx >=14 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 12358102 - timestamp: 1757383373129 -- conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda - sha256: 77ac3fa55fdc5ba0e3709c5830a99dd1abd8f13fd96845768f72ea64ff1baf14 - md5: 06e385238457018ad1071179b67e39d1 - depends: - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - zstd >=1.5.7,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 28993850 - timestamp: 1770197403573 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda - sha256: cb83980c57e311783ee831832eb2c20ecb41e7dee6e86e8b70b8cef0e43eab55 - md5: d4a250da4737ee127fb1fa6452a9002e - depends: - - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libstdcxx >=13 - - libzlib >=1.3.1,<2.0a0 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 4523621 - timestamp: 1749905341688 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda - sha256: 5454709d9fb6e9c3dd6423bc284fa7835a7823bfa8323f6e8786cdd555101fab - md5: 0a5563efed19ca4461cf927419b6eb73 - depends: - - __glibc >=2.17,<3.0.a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=14 - - libnghttp2 >=1.67.0,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: curl - license_family: MIT - purls: [] - size: 462942 - timestamp: 1767821743793 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.18.0-hd5a2499_1.conda - sha256: dbc34552fc6f040bbcd52b4246ec068ce8d82be0e76bfe45c6984097758d37c2 - md5: 2742a933ef07e91f38e3d33ad6fe937c - depends: - - __osx >=11.0 - - krb5 >=1.22.2,<1.23.0a0 - - libnghttp2 >=1.67.0,<2.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.5,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: curl - license_family: MIT - purls: [] - size: 402616 - timestamp: 1770893178846 -- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.18.0-h43ecb02_0.conda - sha256: 86258e30845571ea13855e8a0605275905781476f3edf8ae5df90a06fcada93a - md5: 2688214a9bee5d5650cd4f5f6af5c8f2 - depends: - - krb5 >=1.21.3,<1.22.0a0 - - libssh2 >=1.11.1,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: curl - license_family: MIT - purls: [] - size: 383261 - timestamp: 1767821977053 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda - sha256: 5fbeb2fc2673f0455af6079abf93faaf27f11a92574ad51565fa1ecac9a4e2aa - md5: 4cb5878bdb9ebfa65b7cdff5445087c5 - depends: - - __osx >=11.0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 570068 - timestamp: 1770238262922 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libde265-1.0.15-h00ab1b0_0.conda - sha256: 7cf7e294e1a7c8219065885e186d8f52002fb900bf384d815f159b5874204e3d - md5: 407fee7a5d7ab2dca12c9ca7f62310ad - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 411814 - timestamp: 1703088639063 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libde265-1.0.15-h2ffa867_0.conda - sha256: 13747fa634f7f16d7f222b7d3869e3c1aab9d3a2791edeb2fc632a87663950e0 - md5: 7c718ee6d8497702145612fa0898a12d - depends: - - libcxx >=15 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 277861 - timestamp: 1703089176970 -- conda: https://conda.anaconda.org/conda-forge/win-64/libde265-1.0.15-h91493d7_0.conda - sha256: f52c603151743486d2faec37e161c60731001d9c955e0f12ac9ad334c1119116 - md5: 9dc3c1fbc1c7bc6204e8a603f45e156b - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 252968 - timestamp: 1703089151021 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda - sha256: 4db2f70a1441317d964e84c268e388110ad9cf75ca98994d1336d670e62e6f07 - md5: 27fe770decaf469a53f3e3a6d593067f - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 72783 - timestamp: 1745260463421 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.23-h5773f1b_0.conda - sha256: ebc06154e9a2085e8c9edf81f8f5196b73a1698e18ac6386c9b43fb426103327 - md5: 4dc332b504166d7f89e4b3b18ab5e6ea - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 54685 - timestamp: 1745260666631 -- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda - sha256: 881244050587dc658078ee45dfc792ecb458bbb1fdc861da67948d747b117dc2 - md5: 34f03138e46543944d4d7f8538048842 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 155548 - timestamp: 1745260818985 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda - sha256: c076a213bd3676cc1ef22eeff91588826273513ccc6040d9bea68bccdc849501 - md5: 9314bc5a1fe7d1044dc9dfd3ef400535 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libpciaccess >=0.18,<0.19.0a0 - license: MIT - license_family: MIT - purls: [] - size: 310785 - timestamp: 1757212153962 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 - md5: c277e0a4d549b03ac1e9d6cbbe3d017b - depends: - - ncurses - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 134676 - timestamp: 1738479519902 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 - md5: 44083d2d2c2025afca315c7a172eab2b - depends: - - ncurses - - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 107691 - timestamp: 1738479560845 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - sha256: 7fd5408d359d05a969133e47af580183fbf38e2235b562193d427bb9dad79723 - md5: c151d5eb730e9b7480e6d48c0fc44048 - depends: - - __glibc >=2.17,<3.0.a0 - - libglvnd 1.7.0 ha4b6fd6_2 - license: LicenseRef-libglvnd - purls: [] - size: 44840 - timestamp: 1731330973553 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 - md5: 172bf1cd1ff8629f2b1179945ed45055 - depends: - - libgcc-ng >=12 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 112766 - timestamp: 1702146165126 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f - md5: 36d33e440c31857372a72137f78bacf5 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 107458 - timestamp: 1702146414478 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda - sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 - md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - expat 2.7.4.* - license: MIT - license_family: MIT - purls: [] - size: 76798 - timestamp: 1771259418166 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda - sha256: 03887d8080d6a8fe02d75b80929271b39697ecca7628f0657d7afaea87761edf - md5: a92e310ae8dfc206ff449f362fc4217f - depends: - - __osx >=11.0 - constrains: - - expat 2.7.4.* - license: MIT - license_family: MIT - purls: [] - size: 68199 - timestamp: 1771260020767 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda - sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d - md5: 1c1ced969021592407f16ada4573586d - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - expat 2.7.4.* - license: MIT - license_family: MIT - purls: [] - size: 70323 - timestamp: 1771259521393 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 57433 - timestamp: 1743434498161 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 - md5: 43c04d9cb46ef176bb2a4c77e324d599 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 40979 - timestamp: 1769456747661 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda - sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 - md5: 720b39f5ec0610457b725eb3f396219a - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 45831 - timestamp: 1769456418774 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda - sha256: 4641d37faeb97cf8a121efafd6afd040904d4bca8c46798122f417c31d5dfbec - md5: f4084e4e6577797150f9b04a4560ceb0 - depends: - - libfreetype6 >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 7664 - timestamp: 1757945417134 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda - sha256: 9de25a86066f078822d8dd95a83048d7dc2897d5d655c0e04a8a54fca13ef1ef - md5: f35fb38e89e2776994131fbf961fa44b - depends: - - libfreetype6 >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 7810 - timestamp: 1757947168537 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda - sha256: 2029702ec55e968ce18ec38cc8cf29f4c8c4989a0d51797164dab4f794349a64 - md5: 3235024fe48d4087721797ebd6c9d28c - depends: - - libfreetype6 >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 8109 - timestamp: 1757946135015 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda - sha256: 4a7af818a3179fafb6c91111752954e29d3a2a950259c14a2fc7ba40a8b03652 - md5: 8e7251989bca326a28f4a5ffbd74557a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libpng >=1.6.50,<1.7.0a0 - - libzlib >=1.3.1,<2.0a0 - constrains: - - freetype >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 386739 - timestamp: 1757945416744 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda - sha256: cc4aec4c490123c0f248c1acd1aeab592afb6a44b1536734e20937cda748f7cd - md5: 6d4ede03e2a8e20eb51f7f681d2a2550 - depends: - - __osx >=11.0 - - libpng >=1.6.50,<1.7.0a0 - - libzlib >=1.3.1,<2.0a0 - constrains: - - freetype >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 346703 - timestamp: 1757947166116 -- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda - sha256: 223710600b1a5567163f7d66545817f2f144e4ef8f84e99e90f6b8a4e19cb7ad - md5: 6e7c5c5ab485057b5d07fd8188ba5c28 - depends: - - libpng >=1.6.50,<1.7.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - freetype >=2.14.1 - license: GPL-2.0-only OR FTL - purls: [] - size: 340264 - timestamp: 1757946133889 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda - sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 - md5: 0aa00f03f9e39fb9876085dee11a85d4 - depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - constrains: - - libgcc-ng ==15.2.0=*_18 - - libgomp 15.2.0 he0feb66_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 1041788 - timestamp: 1771378212382 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda - sha256: 1d9c4f35586adb71bcd23e31b68b7f3e4c4ab89914c26bed5f2859290be5560e - md5: 92df6107310b1fff92c4cc84f0de247b - depends: - - _openmp_mutex - constrains: - - libgcc-ng ==15.2.0=*_18 - - libgomp 15.2.0 18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 401974 - timestamp: 1771378877463 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda - sha256: da2c96563c76b8c601746f03e03ac75d2b4640fa2ee017cb23d6c9fc31f1b2c6 - md5: b085746891cca3bd2704a450a7b4b5ce - depends: - - _openmp_mutex >=4.5 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - libgcc-ng ==15.2.0=*_18 - - msys2-conda-epoch <0.0a0 - - libgomp 15.2.0 h8ee18e1_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 820022 - timestamp: 1771382190160 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda - sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 - md5: d5e96b1ed75ca01906b3d2469b4ce493 - depends: - - libgcc 15.2.0 he0feb66_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 27526 - timestamp: 1771378224552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-core-3.10.2-h3359108_0.conda - sha256: a3b549ab4a096561ce4046955505c2806bab721948d35c57dcc4cf2a64a19691 - md5: f460a299f5a2f34a8049071f47a81949 - depends: - - __glibc >=2.17,<3.0.a0 - - blosc >=1.21.6,<2.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - geotiff >=1.7.3,<1.8.0a0 - - giflib >=5.2.2,<5.3.0a0 - - json-c >=0.18,<0.19.0a0 - - lerc >=4.0.0,<5.0a0 - - libarchive >=3.7.7,<3.8.0a0 - - libcurl >=8.12.1,<9.0a0 - - libdeflate >=1.23,<1.24.0a0 - - libexpat >=2.6.4,<3.0a0 - - libgcc >=13 - - libheif >=1.19.5,<1.20.0a0 - - libiconv >=1.17,<2.0a0 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libkml >=1.3.0,<1.4.0a0 - - liblzma >=5.6.4,<6.0a0 - - libpng >=1.6.46,<1.7.0a0 - - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.48.0,<4.0a0 - - libstdcxx >=13 - - libtiff >=4.7.0,<4.8.0a0 - - libuuid >=2.38.1,<3.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - openssl >=3.4.1,<4.0a0 - - pcre2 >=10.44,<10.45.0a0 - - proj >=9.5.1,<9.6.0a0 - - xerces-c >=3.2.5,<3.3.0a0 - - zstd >=1.5.6,<1.6.0a0 - constrains: - - libgdal 3.10.2.* - license: MIT - license_family: MIT - purls: [] - size: 10801211 - timestamp: 1739626046005 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-core-3.10.2-h9ef0d2d_0.conda - sha256: bb72a3c879eddcb0e7e01e662245ec3f9fe07c53cf287217a200e52a39115014 - md5: 5982d6c652d39c9cef709bf22cbbb94d - depends: - - __osx >=11.0 - - blosc >=1.21.6,<2.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - geotiff >=1.7.3,<1.8.0a0 - - giflib >=5.2.2,<5.3.0a0 - - json-c >=0.18,<0.19.0a0 - - lerc >=4.0.0,<5.0a0 - - libarchive >=3.7.7,<3.8.0a0 - - libcurl >=8.12.1,<9.0a0 - - libcxx >=18 - - libdeflate >=1.23,<1.24.0a0 - - libexpat >=2.6.4,<3.0a0 - - libheif >=1.19.5,<1.20.0a0 - - libiconv >=1.17,<2.0a0 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libkml >=1.3.0,<1.4.0a0 - - liblzma >=5.6.4,<6.0a0 - - libpng >=1.6.46,<1.7.0a0 - - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.48.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - openssl >=3.4.1,<4.0a0 - - pcre2 >=10.44,<10.45.0a0 - - proj >=9.5.1,<9.6.0a0 - - xerces-c >=3.2.5,<3.3.0a0 - - zstd >=1.5.6,<1.6.0a0 - constrains: - - libgdal 3.10.2.* - license: MIT - license_family: MIT - purls: [] - size: 8463050 - timestamp: 1739626559515 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-core-3.10.2-h095903c_0.conda - sha256: e387998eee0468570dd87764d0c78d94f7d9d5846cdfa050f71f3fe01f8941b9 - md5: 91f3b8afc65762e8710b50bdda8116c7 - depends: - - blosc >=1.21.6,<2.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - geotiff >=1.7.3,<1.8.0a0 - - lerc >=4.0.0,<5.0a0 - - libarchive >=3.7.7,<3.8.0a0 - - libcurl >=8.12.1,<9.0a0 - - libdeflate >=1.23,<1.24.0a0 - - libexpat >=2.6.4,<3.0a0 - - libheif >=1.19.5,<1.20.0a0 - - libiconv >=1.17,<2.0a0 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libkml >=1.3.0,<1.4.0a0 - - liblzma >=5.6.4,<6.0a0 - - libpng >=1.6.46,<1.7.0a0 - - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.48.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - lz4-c >=1.10.0,<1.11.0a0 - - openssl >=3.4.1,<4.0a0 - - pcre2 >=10.44,<10.45.0a0 - - proj >=9.5.1,<9.6.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - xerces-c >=3.2.5,<3.3.0a0 - - zstd >=1.5.6,<1.6.0a0 - constrains: - - libgdal 3.10.2.* - license: MIT - license_family: MIT - purls: [] - size: 8392331 - timestamp: 1739628560888 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda - sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee - md5: 9063115da5bc35fdc3e1002e69b9ef6e - depends: - - libgfortran5 15.2.0 h68bc16d_18 - constrains: - - libgfortran-ng ==15.2.0=*_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 27523 - timestamp: 1771378269450 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda - sha256: 63f89087c3f0c8621c5c89ecceec1e56e5e1c84f65fc9c5feca33a07c570a836 - md5: 26981599908ed2205366e8fc91b37fc6 - depends: - - libgfortran5 15.2.0 hdae7583_18 - constrains: - - libgfortran-ng ==15.2.0=*_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 138973 - timestamp: 1771379054939 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda - sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 - md5: 646855f357199a12f02a87382d429b75 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=15.2.0 - constrains: - - libgfortran 15.2.0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 2482475 - timestamp: 1771378241063 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda - sha256: 91033978ba25e6a60fb86843cf7e1f7dc8ad513f9689f991c9ddabfaf0361e7e - md5: c4a6f7989cffb0544bfd9207b6789971 - depends: - - libgcc >=15.2.0 - constrains: - - libgfortran 15.2.0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 598634 - timestamp: 1771378886363 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda - sha256: dc2752241fa3d9e40ce552c1942d0a4b5eeb93740c9723873f6fcf8d39ef8d2d - md5: 928b8be80851f5d8ffb016f9c81dae7a - depends: - - __glibc >=2.17,<3.0.a0 - - libglvnd 1.7.0 ha4b6fd6_2 - - libglx 1.7.0 ha4b6fd6_2 - license: LicenseRef-libglvnd - purls: [] - size: 134712 - timestamp: 1731330998354 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda - sha256: 18e354d30a60441b0bf5fcbb125b6b22fd0df179620ae834e2533d44d1598211 - md5: 0305434da649d4fb48a425e588b79ea6 - depends: - - __glibc >=2.17,<3.0.a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 - - libiconv >=1.18,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.44,<10.45.0a0 - constrains: - - glib 2.84.1 *_0 - license: LGPL-2.1-or-later - purls: [] - size: 3947789 - timestamp: 1743773764878 -- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.0-h7025463_0.conda - sha256: 0b4f9581e2dba58bc38cb00453e145140cf6230a56887ff1195e63e2b1e3f1c2 - md5: ea8df8a5c5c7adf4c03bf9e3db1637c3 - depends: - - libffi >=3.4,<4.0a0 - - libiconv >=1.18,<2.0a0 - - libintl >=0.22.5,<1.0a0 - - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.44,<10.45.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - glib 2.84.0 *_0 - license: LGPL-2.1-or-later - purls: [] - size: 3842095 - timestamp: 1743039211561 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda - sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 - md5: 434ca7e50e40f4918ab701e3facd59a0 - depends: - - __glibc >=2.17,<3.0.a0 - license: LicenseRef-libglvnd - purls: [] - size: 132463 - timestamp: 1731330968309 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - sha256: 2d35a679624a93ce5b3e9dd301fff92343db609b79f0363e6d0ceb3a6478bfa7 - md5: c8013e438185f33b13814c5c488acd5c - depends: - - __glibc >=2.17,<3.0.a0 - - libglvnd 1.7.0 ha4b6fd6_2 - - xorg-libx11 >=1.8.10,<2.0a0 - license: LicenseRef-libglvnd - purls: [] - size: 75504 - timestamp: 1731330988898 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda - sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 - md5: 239c5e9546c38a1e884d69effcf4c882 - depends: - - __glibc >=2.17,<3.0.a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 603262 - timestamp: 1771378117851 -- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda - sha256: 94981bc2e42374c737750895c6fdcfc43b7126c4fc788cad0ecc7281745931da - md5: 939fb173e2a4d4e980ef689e99b35223 - depends: - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - constrains: - - msys2-conda-epoch <0.0a0 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 663864 - timestamp: 1771382118742 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda - sha256: ec9797d57088aeed7ca4905777d4f3e70a4dbe90853590eef7006b0ab337af3f - md5: 1db2693fa6a50bef58da2df97c5204cb - depends: - - __glibc >=2.17,<3.0.a0 - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - libavif16 >=1.2.0,<2.0a0 - - libde265 >=1.0.15,<1.0.16.0a0 - - libgcc >=13 - - libstdcxx >=13 - - x265 >=3.5,<3.6.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 596714 - timestamp: 1741306859216 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libheif-1.19.7-gpl_h79e6334_100.conda - sha256: 19384a0c0922cbded842e1fa14d8c40a344cb735d1d85598b11f67dc0cd1f4cc - md5: 4f5369442ff2de5983831d321f584eb4 - depends: - - __osx >=11.0 - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - libavif16 >=1.2.0,<2.0a0 - - libcxx >=18 - - libde265 >=1.0.15,<1.0.16.0a0 - - x265 >=3.5,<3.6.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 442619 - timestamp: 1741307000158 -- conda: https://conda.anaconda.org/conda-forge/win-64/libheif-1.19.7-gpl_h2684147_100.conda - sha256: 55965154b428c22cf0fcf1bd53844c1c4c59f0301ece36782b082a92a51e52af - md5: d7a6c3df36c3281b38164ce518d45528 - depends: - - aom >=3.9.1,<3.10.0a0 - - dav1d >=1.2.1,<1.2.2.0a0 - - libavif16 >=1.2.0,<2.0a0 - - libde265 >=1.0.15,<1.0.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - x265 >=3.5,<3.6.0a0 - license: LGPL-3.0-or-later - license_family: LGPL - purls: [] - size: 391084 - timestamp: 1741307167944 -- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.1-default_h88281d1_1000.conda - sha256: 2fb437b82912c74b4869b66c601d52c77bb3ee8cb4812eab346d379f1c823225 - md5: e6298294e7612eccf57376a0683ddc80 - depends: - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - libxml2 >=2.13.8,<2.14.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 2412139 - timestamp: 1752762145331 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f - md5: 915f5995e94f60e9a4826e0b0920ee88 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: LGPL-2.1-only - purls: [] - size: 790176 - timestamp: 1754908768807 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 - md5: 4d5a7445f0b25b6a3ddbb56e790f5251 - depends: - - __osx >=11.0 - license: LGPL-2.1-only - purls: [] - size: 750379 - timestamp: 1754909073836 -- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda - sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 - md5: 64571d1dd6cdcfa25d0664a5950fdaa2 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LGPL-2.1-only - purls: [] - size: 696926 - timestamp: 1754909290005 -- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda - sha256: c7e4600f28bcada8ea81456a6530c2329312519efcf0c886030ada38976b0511 - md5: 2cf0cf76cc15d360dfa2f17fd6cf9772 - depends: - - libiconv >=1.17,<2.0a0 - license: LGPL-2.1-or-later - purls: [] - size: 95568 - timestamp: 1723629479451 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda - sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 - md5: 8397539e3a0bbd1695584fb4f927485a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - jpeg <0.0.0a - license: IJG AND BSD-3-Clause AND Zlib - purls: [] - size: 633710 - timestamp: 1762094827865 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda - sha256: 6c061c56058bb10374daaef50e81b39cf43e8aee21f0037022c0c39c4f31872f - md5: f0695fbecf1006f27f4395d64bd0c4b8 - depends: - - __osx >=11.0 - constrains: - - jpeg <0.0.0a - license: IJG AND BSD-3-Clause AND Zlib - purls: [] - size: 551197 - timestamp: 1762095054358 -- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda - sha256: 795e2d4feb2f7fc4a2c6e921871575feb32b8082b5760726791f080d1e2c2597 - md5: 56a686f92ac0273c0f6af58858a3f013 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - jpeg <0.0.0a - license: IJG AND BSD-3-Clause AND Zlib - purls: [] - size: 841783 - timestamp: 1762094814336 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-haa4a5bd_1022.conda - sha256: aa55f5779d6bc7bf24dc8257f053d5a0708b5910b6bc6ea1396f15febf812c98 - md5: 00f0f4a9d2eb174015931b1a234d61ca - depends: - - __glibc >=2.17,<3.0.a0 - - libexpat >=2.7.1,<3.0a0 - - libgcc >=14 - - libstdcxx >=14 - - libzlib >=1.3.1,<2.0a0 - - uriparser >=0.9.8,<1.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 411495 - timestamp: 1761132836798 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-hc33e383_1022.conda - sha256: ef32d85c00aefa510e9f36f19609dddc93359c1abbe58c2a695a927d2537721f - md5: a91a7afac6eec20a07d9435bf1372bc1 - depends: - - __osx >=11.0 - - libcxx >=19 - - libexpat >=2.7.1,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - - uriparser >=0.9.8,<1.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 284064 - timestamp: 1761133563691 -- conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-h68a222c_1022.conda - sha256: eacacca7d9b0bcfca16d44365af2437509d58ea6730efdd2a7468963edf849a1 - md5: 6800434a33b644e46c28ffa3ec18afb1 - depends: - - libexpat >=2.7.1,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - uriparser >=0.9.8,<1.0a0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 1659205 - timestamp: 1761132867821 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda - build_number: 5 - sha256: c723b6599fcd4c6c75dee728359ef418307280fa3e2ee376e14e85e5bbdda053 - md5: b38076eb5c8e40d0106beda6f95d7609 - depends: - - libblas 3.11.0 5_h4a7cf45_openblas - constrains: - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - - libcblas 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18200 - timestamp: 1765818857876 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hd9741b5_openblas.conda - build_number: 5 - sha256: 735a6e6f7d7da6f718b6690b7c0a8ae4815afb89138aa5793abe78128e951dbb - md5: ca9d752201b7fa1225bca036ee300f2b - depends: - - libblas 3.11.0 5_h51639a9_openblas - constrains: - - libcblas 3.11.0 5*_openblas - - blas 2.305 openblas - - liblapacke 3.11.0 5*_openblas - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 18551 - timestamp: 1765819121855 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda - build_number: 5 - sha256: a2d33f5cc2b8a9042f2af6981c6733ab1a661463823eaa56595a9c58c0ab77e1 - md5: e62c42a4196dee97d20400612afcb2b1 - depends: - - libblas 3.11.0 5_hf2e6a31_mkl - constrains: - - libcblas 3.11.0 5*_mkl - - blas 2.305 mkl - - liblapacke 3.11.0 5*_mkl - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 80225 - timestamp: 1765819148014 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.8-hecd9e04_0.conda - sha256: a6fddc510de09075f2b77735c64c7b9334cf5a26900da351779b275d9f9e55e1 - md5: 59a7b967b6ef5d63029b1712f8dcf661 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libxml2 >=2.13.8,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 43987020 - timestamp: 1752141980723 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda - sha256: d190f1bf322149321890908a534441ca2213a9a96c59819da6cabf2c5b474115 - md5: 9ad637a7ac380c442be142dfb0b1b955 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libxml2 >=2.13.8,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - purls: [] - size: 44363060 - timestamp: 1756291822911 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda - sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb - md5: c7c83eecbb72d88b940c249af56c8b17 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - xz 5.8.2.* - license: 0BSD - purls: [] - size: 113207 - timestamp: 1768752626120 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda - sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e - md5: 009f0d956d7bfb00de86901d16e486c7 - depends: - - __osx >=11.0 - constrains: - - xz 5.8.2.* - license: 0BSD - purls: [] - size: 92242 - timestamp: 1768752982486 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda - sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c - md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - xz 5.8.2.* - license: 0BSD - purls: [] - size: 106169 - timestamp: 1768752763559 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda - sha256: a4a7dab8db4dc81c736e9a9b42bdfd97b087816e029e221380511960ac46c690 - md5: b499ce4b026493a13774bcf0f4c33849 - depends: - - __glibc >=2.17,<3.0.a0 - - c-ares >=1.34.5,<2.0a0 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libgcc >=14 - - libstdcxx >=14 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.2,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 666600 - timestamp: 1756834976695 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.67.0-hc438710_0.conda - sha256: a07cb53b5ffa2d5a18afc6fd5a526a5a53dd9523fbc022148bd2f9395697c46d - md5: a4b4dd73c67df470d091312ab87bf6ae - depends: - - __osx >=11.0 - - c-ares >=1.34.5,<2.0a0 - - libcxx >=19 - - libev >=4.33,<4.34.0a0 - - libev >=4.33,<5.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.2,<4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 575454 - timestamp: 1756835746393 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda - sha256: 927fe72b054277cde6cb82597d0fcf6baf127dcbce2e0a9d8925a68f1265eef5 - md5: d864d34357c3b65a4b731f78c0801dc4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-only - license_family: GPL - purls: [] - size: 33731 - timestamp: 1750274110928 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda - sha256: 3b3f19ced060013c2dd99d9d46403be6d319d4601814c772a3472fe2955612b0 - md5: 7c7927b404672409d9917d49bff5f2d6 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: LGPL-2.1-or-later - purls: [] - size: 33418 - timestamp: 1734670021371 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda - sha256: 199d79c237afb0d4780ccd2fbf829cea80743df60df4705202558675e07dd2c5 - md5: be43915efc66345cccb3c310b6ed0374 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libgfortran - - libgfortran5 >=14.3.0 - constrains: - - openblas >=0.3.30,<0.3.31.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 5927939 - timestamp: 1763114673331 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.30-openmp_ha158390_4.conda - sha256: ebbbc089b70bcde87c4121a083c724330f02a690fb9d7c6cd18c30f1b12504fa - md5: a6f6d3a31bb29e48d37ce65de54e2df0 - depends: - - __osx >=11.0 - - libgfortran - - libgfortran5 >=14.3.0 - - llvm-openmp >=19.1.7 - constrains: - - openblas >=0.3.30,<0.3.31.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 4284132 - timestamp: 1768547079205 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda - sha256: 215086c108d80349e96051ad14131b751d17af3ed2cb5a34edd62fa89bfe8ead - md5: 7df50d44d4a14d6c31a2c54f2cd92157 - depends: - - __glibc >=2.17,<3.0.a0 - - libglvnd 1.7.0 ha4b6fd6_2 - license: LicenseRef-libglvnd - purls: [] - size: 50757 - timestamp: 1731330993524 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda - sha256: 0bd91de9b447a2991e666f284ae8c722ffb1d84acb594dbd0c031bd656fa32b2 - md5: 70e3400cbbfa03e96dcde7fc13e38c7b - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 28424 - timestamp: 1749901812541 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda - sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c - md5: 5f13ffc7d30ffec87864e678df9957b4 - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libzlib >=1.3.1,<2.0a0 - license: zlib-acknowledgement - purls: [] - size: 317669 - timestamp: 1770691470744 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda - sha256: 7a4fd29a6ee2d7f7a6e610754dfdf7410ed08f40d8d8b488a27bc0f9981d5abb - md5: 871dc88b0192ac49b6a5509932c31377 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: zlib-acknowledgement - purls: [] - size: 288950 - timestamp: 1770691485950 -- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda - sha256: db23f281fa80597a0dc0445b18318346862602d7081ed76244df8cc4418d6d68 - md5: 43f47a9151b9b8fc100aeefcf350d1a0 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libzlib >=1.3.1,<2.0a0 - license: zlib-acknowledgement - purls: [] - size: 383155 - timestamp: 1770691504832 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda - sha256: 06a8ace6cc5ee47b85a5e64fad621e5912a12a0202398f54f302eb4e8b9db1fd - md5: a4769024afeab4b32ac8167c2f92c7ac - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=14 - - openldap >=2.6.10,<2.7.0a0 - - openssl >=3.5.4,<4.0a0 - license: PostgreSQL - purls: [] - size: 2649881 - timestamp: 1763565297202 -- conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h97f6797_17.conda - sha256: 1fb8a71bdbc236b8e74f0475887786735d5fa6f5d76d9a4135021279c7ff54b8 - md5: e16e9b1333385c502bf915195f421934 - depends: - - __glibc >=2.17,<3.0.a0 - - geos >=3.13.0,<3.13.1.0a0 - - libgcc >=13 - - libstdcxx >=13 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 231770 - timestamp: 1727338518657 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-ha2cf0f4_17.conda - sha256: 9ff3162d035a1d9022f6145755a70d0c0ce6c9152792402bc42294354c871a17 - md5: ba729f000ea379b76ed2190119d21e13 - depends: - - __osx >=11.0 - - geos >=3.13.0,<3.13.1.0a0 - - libcxx >=17 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 191064 - timestamp: 1727265842691 -- conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-hd4c2148_17.conda - sha256: 0f4a1c8ed579f96ccb73245b4002d7152a2a8ecd05a01d49901c5d280561f766 - md5: 06ea16b8c60b4ce1970c06191f8639d4 - depends: - - geos >=3.13.0,<3.13.1.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 404515 - timestamp: 1727265928370 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda - sha256: 0105bd108f19ea8e6a78d2d994a6d4a8db16d19a41212070d2d1d48a63c34161 - md5: a587892d3c13b6621a6091be690dbca2 - depends: - - libgcc-ng >=12 - license: ISC - purls: [] - size: 205978 - timestamp: 1716828628198 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 - sha256: 1d95fe5e5e6a0700669aab454b2a32f97289c9ed8d1f7667c2ba98327a6f05bc - md5: 90859688dbca4735b74c02af14c4c793 - license: ISC - purls: [] - size: 324912 - timestamp: 1605135878892 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.20-hc70643c_0.conda - sha256: 7bcb3edccea30f711b6be9601e083ecf4f435b9407d70fc48fbcf9e5d69a0fc6 - md5: 198bb594f202b205c7d18b936fa4524f - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: ISC - purls: [] - size: 202344 - timestamp: 1716828757533 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.1.0-he57a185_0.conda - sha256: 03963a7786b3f53eb36ca3ec10d7a5ddd5265a81e205e28902c53a536cdfd3ad - md5: 2df7aaf3f8a2944885372a62c6f33b20 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - license: MIT - license_family: MIT - purls: [] - size: 399212 - timestamp: 1734891697797 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.1.0-h57eeb1c_0.conda - sha256: c20c654bc4616c0a1b465adf3131143141aad6ce43c87794d2d5c616c67ff704 - md5: afa1759ccaaebb2c2f0d104b1bd11d06 - depends: - - __osx >=11.0 - - libcxx >=18 - license: MIT - license_family: MIT - purls: [] - size: 295552 - timestamp: 1734891755224 -- conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.1.0-h518811d_0.conda - sha256: c72149515f10219bb1c71c40865b8a73bcaa07e755f13200d278674a987fc097 - md5: 8ca34da29812354d8ea421a1b68897db - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 281126 - timestamp: 1734891956800 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h1b4f908_12.conda - sha256: a9274b30ecc8967fa87959c1978de3b2bfae081b1a8fea7c5a61588041de818f - md5: 641f91ac6f984a91a78ba2411fe4f106 - depends: - - __glibc >=2.17,<3.0.a0 - - freexl >=2 - - freexl >=2.0.0,<3.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - libgcc >=13 - - librttopo >=1.1.0,<1.2.0a0 - - libsqlite >=3.47.2,<4.0a0 - - libstdcxx >=13 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - sqlite - - zlib - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 4033736 - timestamp: 1734001047320 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-hf92fc0a_12.conda - sha256: b11e6169fdbef472c307129192fd46133eec543036e41ab2f957615713b03d19 - md5: f05759528e44f74888830119ab32fc81 - depends: - - __osx >=11.0 - - freexl >=2 - - freexl >=2.0.0,<3.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - libcxx >=18 - - libiconv >=1.17,<2.0a0 - - librttopo >=1.1.0,<1.2.0a0 - - libsqlite >=3.47.2,<4.0a0 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - sqlite - - zlib - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 2943606 - timestamp: 1734001158789 -- conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-h939089a_12.conda - sha256: fafedc5940e49b3dcce2cd6dfe3cabf64e7cc6b2a0ef7c8fefbf9d6d2c1afb77 - md5: 8b5bfc6caa7c652ec4ec755efb5b7b73 - depends: - - freexl >=2 - - freexl >=2.0.0,<3.0a0 - - geos >=3.13.0,<3.13.1.0a0 - - librttopo >=1.1.0,<1.2.0a0 - - libsqlite >=3.47.2,<4.0a0 - - libxml2 >=2.13.5,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - proj >=9.5.1,<9.6.0a0 - - sqlite - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zlib - license: MPL-1.1 - license_family: MOZILLA - purls: [] - size: 8715367 - timestamp: 1734001064515 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda - sha256: c1ff4589b48d32ca0a2628970d869fa9f7b2c2d00269a3761edc7e9e4c1ab7b8 - md5: f7d30045eccb83f2bb8053041f42db3c - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 939312 - timestamp: 1768147967568 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1b79a29_0.conda - sha256: f942afee5568a0bfba020e52c3f22b788e14017a8dc302652d2ca500756a8a5a - md5: faedef456ba5004af365d450eb38217d - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: blessing - purls: [] - size: 905482 - timestamp: 1768148270069 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda - sha256: 756478128e3e104bd7e7c3ce6c1b0efad7e08c7320c69fdc726e039323c63fbb - md5: 903979414b47d777d548e5f0165e6cd8 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: blessing - purls: [] - size: 1291616 - timestamp: 1768148278261 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda - sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 - md5: eecce068c7e4eddeb169591baac20ac4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 304790 - timestamp: 1745608545575 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda - sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a - md5: b68e8f66b94b44aaa8de4583d3d4cc40 - depends: - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 279193 - timestamp: 1745608793272 -- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda - sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 - md5: 9dce2f112bfd3400f4f432b3d0ac07b2 - depends: - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 292785 - timestamp: 1745608759342 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda - sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e - md5: 1b08cd684f34175e4514474793d44bcb - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc 15.2.0 he0feb66_18 - constrains: - - libstdcxx-ng ==15.2.0=*_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 5852330 - timestamp: 1771378262446 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda - sha256: 3c902ffd673cb3c6ddde624cdb80f870b6c835f8bf28384b0016e7d444dd0145 - md5: 6235adb93d064ecdf3d44faee6f468de - depends: - - libstdcxx 15.2.0 h934c35e_18 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 27575 - timestamp: 1771378314494 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda - sha256: 7480613af15795281bd338a4d3d2ca148f9c2ecafc967b9cc233e78ba2fe4a6d - md5: 6c1028898cf3a2032d9af46689e1b81a - depends: - - __glibc >=2.17,<3.0.a0 - - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.23,<1.24.0a0 - - libgcc >=13 - - libjpeg-turbo >=3.1.0,<4.0a0 - - liblzma >=5.8.1,<6.0a0 - - libstdcxx >=13 - - libwebp-base >=1.5.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: HPND - purls: [] - size: 429381 - timestamp: 1745372713285 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.0-h551f018_4.conda - sha256: 5d3f7a71b70f0d88470eda8e7b6afe3095d66708a70fb912e79d56fc30b35429 - md5: 717e02c4cca2a760438384d48b7cd1b9 - depends: - - __osx >=11.0 - - lerc >=4.0.0,<5.0a0 - - libcxx >=18 - - libdeflate >=1.23,<1.24.0a0 - - libjpeg-turbo >=3.1.0,<4.0a0 - - liblzma >=5.8.1,<6.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: HPND - purls: [] - size: 370898 - timestamp: 1745372834516 -- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda - sha256: 3456e2a6dfe6c00fd0cda316f0cbb47caddf77f83d3ed4040b6ad17ec1610d2a - md5: 7d938ca70c64c5516767b4eae0a56172 - depends: - - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.23,<1.24.0a0 - - libjpeg-turbo >=3.1.0,<4.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.7,<1.6.0a0 - license: HPND - purls: [] - size: 980597 - timestamp: 1745373037447 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee - md5: db409b7c1720428638e7c0d509d3e1b5 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 40311 - timestamp: 1766271528534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b - md5: aea31d2e5b1091feca96fcfe945c3cf9 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - constrains: - - libwebp 1.6.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 429011 - timestamp: 1752159441324 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda - sha256: a4de3f371bb7ada325e1f27a4ef7bcc81b2b6a330e46fac9c2f78ac0755ea3dd - md5: e5e7d467f80da752be17796b87fe6385 - depends: - - __osx >=11.0 - constrains: - - libwebp 1.6.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 294974 - timestamp: 1752159906788 -- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda - sha256: 7b6316abfea1007e100922760e9b8c820d6fc19df3f42fb5aca684cfacb31843 - md5: f9bbae5e2537e3b06e0f7310ba76c893 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - libwebp 1.6.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 279176 - timestamp: 1752159543911 -- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda - sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0 - md5: 8a86073cf3b343b87d03f41790d8b4e5 - depends: - - ucrt - constrains: - - pthreads-win32 <0.0a0 - - msys2-conda-epoch <0.0a0 - license: MIT AND BSD-3-Clause-Clear - purls: [] - size: 36621 - timestamp: 1759768399557 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa - md5: 92ed62436b625154323d40d5f2f11dd7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - pthread-stubs - - xorg-libxau >=1.0.11,<2.0a0 - - xorg-libxdmcp - license: MIT - license_family: MIT - purls: [] - size: 395888 - timestamp: 1727278577118 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda - sha256: bd3816218924b1e43b275863e21a3e13a5db4a6da74cca8e60bc3c213eb62f71 - md5: af523aae2eca6dfa1c8eec693f5b9a79 - depends: - - __osx >=11.0 - - pthread-stubs - - xorg-libxau >=1.0.11,<2.0a0 - - xorg-libxdmcp - license: MIT - license_family: MIT - purls: [] - size: 323658 - timestamp: 1727278733917 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda - sha256: 08dec73df0e161c96765468847298a420933a36bc4f09b50e062df8793290737 - md5: a69bbf778a462da324489976c84cfc8c - depends: - - libgcc >=13 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - pthread-stubs - - ucrt >=10.0.20348.0 - - xorg-libxau >=1.0.11,<2.0a0 - - xorg-libxdmcp - license: MIT - license_family: MIT - purls: [] - size: 1208687 - timestamp: 1727279378819 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda - sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c - md5: 5aa797f8787fe7a17d1b0821485b5adc - depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - purls: [] - size: 100393 - timestamp: 1702724383534 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda - sha256: 23f47e86cc1386e7f815fa9662ccedae151471862e971ea511c5c886aa723a54 - md5: 74e91c36d0eef3557915c68b6c2bef96 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - - libxcb >=1.17.0,<2.0a0 - - libxml2 >=2.13.8,<2.14.0a0 - - xkeyboard-config - - xorg-libxau >=1.0.12,<2.0a0 - license: MIT/X11 Derivative - license_family: MIT - purls: [] - size: 791328 - timestamp: 1754703902365 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda - sha256: 5d12e993894cb8e9f209e2e6bef9c90fa2b7a339a1f2ab133014b71db81f5d88 - md5: 35eeb0a2add53b1e50218ed230fa6a02 - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - - libgcc >=14 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 697033 - timestamp: 1761766011241 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.9-h4a9ca0c_0.conda - sha256: 7ab9b3033f29ac262cd3c846887e5b512f5916c3074d10f298627d67b7a32334 - md5: 763c7e76295bf142145d5821f251b884 - depends: - - __osx >=11.0 - - icu >=75.1,<76.0a0 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 581379 - timestamp: 1761766437117 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.9-h741aa76_0.conda - sha256: 28ac5bbed11644b9e06241ba1dfdac7e3a99e74b69915d45f646717ad9645ca5 - md5: 333d21ab129d5fa5742225bf1d7557a5 - depends: - - libiconv >=1.18,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: MIT - license_family: MIT - purls: [] - size: 1521446 - timestamp: 1761766307746 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda - sha256: 35ddfc0335a18677dd70995fa99b8f594da3beb05c11289c87b6de5b930b47a3 - md5: 31059dc620fa57d787e3899ed0421e6d - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libxml2 >=2.13.8,<2.14.0a0 - license: MIT - license_family: MIT - purls: [] - size: 244399 - timestamp: 1753273455036 -- conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h25c3957_0.conda - sha256: 20857f1adb91cc59826e146ee6cb1157c6abf2901a93d359b1106ba87c8e770b - md5: e84f36aa02735c140099d992d491968d - depends: - - libxml2 >=2.13.8,<2.14.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: [] - size: 416974 - timestamp: 1753273998632 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 - md5: edb0dca6bc32e4f4789199455a1dbeb8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 60963 - timestamp: 1727963148474 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - sha256: ce34669eadaba351cd54910743e6a2261b67009624dbc7daeeafdef93616711b - md5: 369964e85dc26bfe78f41399b366c435 - depends: - - __osx >=11.0 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 46438 - timestamp: 1727963202283 -- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402 - md5: 41fbfac52c601159df6c01f875de31b9 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - zlib 1.3.1 *_2 - license: Zlib - license_family: Other - purls: [] - size: 55476 - timestamp: 1727963768015 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda - sha256: 56bcd20a0a44ddd143b6ce605700fdf876bcf5c509adc50bf27e76673407a070 - md5: 206ad2df1b5550526e386087bef543c7 - depends: - - __osx >=11.0 - constrains: - - openmp 21.1.8|21.1.8.* - - intel-openmp <0.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: APACHE - purls: [] - size: 285974 - timestamp: 1765964756583 -- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-21.1.8-h4fa8253_0.conda - sha256: 145c4370abe870f10987efa9fc15a8383f1dab09abbc9ad4ff15a55d45658f7b - md5: 0d8b425ac862bcf17e4b28802c9351cb - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - intel-openmp <0.0a0 - - openmp 21.1.8|21.1.8.* - license: Apache-2.0 WITH LLVM-exception - license_family: APACHE - purls: [] - size: 347566 - timestamp: 1765964942856 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - sha256: 47326f811392a5fd3055f0f773036c392d26fdb32e4d8e7a8197eed951489346 - md5: 9de5350a85c4a20c685259b889aa6393 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 167055 - timestamp: 1733741040117 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lz4-c-1.10.0-h286801f_1.conda - sha256: 94d3e2a485dab8bdfdd4837880bde3dd0d701e2b97d6134b8806b7c8e69c8652 - md5: 01511afc6cc1909c5303cf31be17b44f - depends: - - __osx >=11.0 - - libcxx >=18 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 148824 - timestamp: 1733741047892 -- conda: https://conda.anaconda.org/conda-forge/win-64/lz4-c-1.10.0-h2466b09_1.conda - sha256: 632cf3bdaf7a7aeb846de310b6044d90917728c73c77f138f08aa9438fc4d6b5 - md5: 0b69331897a92fac3d8923549d48d092 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 139891 - timestamp: 1733741168264 -- conda: https://conda.anaconda.org/conda-forge/linux-64/lzo-2.10-h280c20c_1002.conda - sha256: 5c6bbeec116e29f08e3dad3d0524e9bc5527098e12fc432c0e5ca53ea16337d4 - md5: 45161d96307e3a447cc3eb5896cf6f8c - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 191060 - timestamp: 1753889274283 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lzo-2.10-h925e9cb_1002.conda - sha256: db40fd25c6306bfda469f84cddd8b5ebb9aa08d509cecb49dfd0bb8228466d0c - md5: e56eaa1beab0e7fed559ae9c0264dd88 - depends: - - __osx >=11.0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 152755 - timestamp: 1753889267953 -- conda: https://conda.anaconda.org/conda-forge/win-64/lzo-2.10-h6a83c73_1002.conda - sha256: 344f4f225c6dfb523fb477995545542224c37a5c86161f053a1a18fe547aa979 - md5: c5cb4159f0eea65663b31dd1e49bbb71 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 165589 - timestamp: 1753889311940 -- conda: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.8.1-pyhd8ed1ab_1.conda - sha256: c498a016b233be5a7defee443733a82d5fe41b83016ca8a136876a64fd15564b - md5: c48bbb2bcc3f9f46741a7915d67e6839 - depends: - - networkx >=2.7 - - numpy >=1.23 - - pandas >=1.4,!=1.5.0 - - python >=3.9 - - scikit-learn >=1.0 - - scipy >=1.8 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/mapclassify?source=hash-mapping - size: 56772 - timestamp: 1733731193211 -- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py310h3406613_0.conda - sha256: b3894b37cab530d1adab5b9ce39a1b9f28040403cc0042b77e04a2f227a447de - md5: 8854df4fb4e37cc3ea0a024e48c9c180 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 23673 - timestamp: 1759055396627 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py310hf4fd40f_0.conda - sha256: fe90edbce0137081fb6f7c14ef56b9954628abb6f52882011f8cd5d44425fc37 - md5: cd0fbf3b6ffdda2958e4b720f03429ba - depends: - - __osx >=11.0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 23707 - timestamp: 1759055558733 -- conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.3-py310hdb0e946_0.conda - sha256: 87203ea8bbe265ebabb16673c9442d2097e1b405dc70df49d6920730e7be6e74 - md5: 1fdd2255424eaf0d5e707c205ace2c30 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - jinja2 >=3.0.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/markupsafe?source=hash-mapping - size: 26586 - timestamp: 1759055463355 -- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py310hff52083_0.conda - sha256: 6d087ae3f42e5a53f648a874629b561e8ec34416f6a258837ca0af405550defe - md5: e78bcae4f58d0000f756c3b42da20f13 - depends: - - matplotlib-base >=3.10.8,<3.10.9.0a0 - - pyside6 >=6.7.2 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - tornado >=5 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 17450 - timestamp: 1763055406857 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py310hb6292c7_0.conda - sha256: e19c56288ea1b729089d28614200e8613cdf5107367636736d0d0bf06c750e72 - md5: 33dca3f48bc5d4427238f4f214574f40 - depends: - - matplotlib-base >=3.10.8,<3.10.9.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - tornado >=5 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 17596 - timestamp: 1763055909786 -- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py310h5588dad_0.conda - sha256: 277b0e73a023978311fff8976b6b92e529b13dc9d4487414e12695f5ee0d8555 - md5: 178a19a3e53ec4d213f1193c34e92500 - depends: - - matplotlib-base >=3.10.8,<3.10.9.0a0 - - pyside6 >=6.7.2 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - tornado >=5 - license: PSF-2.0 - license_family: PSF - purls: [] - size: 17874 - timestamp: 1763055525619 -- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py310hfde16b3_0.conda - sha256: 809eaf93eb1901764c9b75803794c0359dd09366f578a13fdbbbe99824920d2c - md5: 093b60a14d2c0d8c10f17e14a73a60d3 - depends: - - __glibc >=2.17,<3.0.a0 - - contourpy >=1.0.1 - - cycler >=0.10 - - fonttools >=4.22.0 - - freetype - - kiwisolver >=1.3.1 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - libgcc >=14 - - libstdcxx >=14 - - numpy >=1.21,<3 - - numpy >=1.23 - - packaging >=20.0 - - pillow >=8 - - pyparsing >=2.3.1 - - python >=3.10,<3.11.0a0 - - python-dateutil >=2.7 - - python_abi 3.10.* *_cp310 - - qhull >=2020.2,<2020.3.0a0 - - tk >=8.6.13,<8.7.0a0 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 7273307 - timestamp: 1763055380888 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py310h0181960_0.conda - sha256: 397a75557d684e4030fcbee1a2adc6669036dd0525d64d6e5c060a5dff7ba027 - md5: f7be8dab2ed23302da20d4c96345eb15 - depends: - - __osx >=11.0 - - contourpy >=1.0.1 - - cycler >=0.10 - - fonttools >=4.22.0 - - freetype - - kiwisolver >=1.3.1 - - libcxx >=19 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - numpy >=1.21,<3 - - numpy >=1.23 - - packaging >=20.0 - - pillow >=8 - - pyparsing >=2.3.1 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python-dateutil >=2.7 - - python_abi 3.10.* *_cp310 - - qhull >=2020.2,<2020.3.0a0 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 7123730 - timestamp: 1763055863073 -- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py310h0bdd906_0.conda - sha256: 97bf5dcb9c38031ff55fa8b92c872a49938e264b0670d1889118eaca72de4b9e - md5: 13072a2da6b67737ad24e22041f68ef5 - depends: - - contourpy >=1.0.1 - - cycler >=0.10 - - fonttools >=4.22.0 - - freetype - - kiwisolver >=1.3.1 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - numpy >=1.21,<3 - - numpy >=1.23 - - packaging >=20.0 - - pillow >=8 - - pyparsing >=2.3.1 - - python >=3.10,<3.11.0a0 - - python-dateutil >=2.7 - - python_abi 3.10.* *_cp310 - - qhull >=2020.2,<2020.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/matplotlib?source=hash-mapping - size: 7166182 - timestamp: 1763055495695 -- conda: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.2.1-pyhd8ed1ab_0.conda - sha256: 9d690334de0cd1d22c51bc28420663f4277cfa60d34fa5cad1ce284a13f1d603 - md5: 00e120ce3e40bad7bfc78861ce3c4a25 - depends: - - python >=3.10 - - traitlets - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/matplotlib-inline?source=hash-mapping - size: 15175 - timestamp: 1761214578417 -- conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.10-h05a5f5f_0.conda - sha256: 0c3700d15377156937ddc89a856527ad77e7cf3fd73cb0dffc75fce8030ddd16 - md5: da01bb40572e689bd1535a5cee6b1d68 - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - libgcc >=13 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libstdcxx >=13 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: Zlib - license_family: Other - purls: [] - size: 93471 - timestamp: 1746450475308 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.10-hff1a8ea_0.conda - sha256: b3503bd3da5d48d57b44835f423951f487574e08a999f13288c81464ac293840 - md5: 93def148863d840e500490d6d78722f9 - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libcxx >=18 - - libiconv >=1.18,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - zstd >=1.5.7,<1.6.0a0 - license: Zlib - license_family: Other - purls: [] - size: 78411 - timestamp: 1746450560057 -- conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.10-h9fa1bad_0.conda - sha256: feacd3657c60ef0758228fc93d46cedb45ac1b1d151cb09780a4d6c4b8b32543 - md5: 2ffdc180adc65f509e996d63513c04b7 - depends: - - bzip2 >=1.0.8,<2.0a0 - - liblzma >=5.8.1,<6.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.7,<1.6.0a0 - license: Zlib - license_family: Other - purls: [] - size: 86618 - timestamp: 1746450788037 -- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.0-hac47afa_455.conda - sha256: b2b4c84b95210760e4d12319416c60ab66e03674ccdcbd14aeb59f82ebb1318d - md5: fd05d1e894497b012d05a804232254ed - depends: - - llvm-openmp >=21.1.8 - - tbb >=2022.3.0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: LicenseRef-IntelSimplifiedSoftwareOct2022 - license_family: Proprietary - purls: [] - size: 100224829 - timestamp: 1767634557029 -- conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - sha256: d09c47c2cf456de5c09fa66d2c3c5035aa1fa228a1983a433c47b876aa16ce90 - md5: 37293a85a0f4f77bbd9cf7aaefc62609 - depends: - - python >=3.9 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/munkres?source=hash-mapping - size: 15851 - timestamp: 1749895533014 -- pypi: https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl - name: nbformat - version: 5.10.4 - sha256: 3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b - requires_dist: - - fastjsonschema>=2.15 - - jsonschema>=2.6 - - jupyter-core>=4.12,!=5.0.* - - traitlets>=5.1 - - myst-parser ; extra == 'docs' - - pydata-sphinx-theme ; extra == 'docs' - - sphinx ; extra == 'docs' - - sphinxcontrib-github-alt ; extra == 'docs' - - sphinxcontrib-spelling ; extra == 'docs' - - pep440 ; extra == 'test' - - pre-commit ; extra == 'test' - - pytest ; extra == 'test' - - testpath ; extra == 'test' - requires_python: '>=3.8' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 - md5: 47e340acb35de30501a76c7c799c41d7 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: X11 AND BSD-3-Clause - purls: [] - size: 891641 - timestamp: 1738195959188 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 - md5: 068d497125e4bf8a66bf707254fff5ae - depends: - - __osx >=11.0 - license: X11 AND BSD-3-Clause - purls: [] - size: 797030 - timestamp: 1738196177597 -- conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 - md5: 598fd7d4d0de2455fb74f56063969a97 - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/nest-asyncio?source=hash-mapping - size: 11543 - timestamp: 1733325673691 -- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda - sha256: 39625cd0c9747fa5c46a9a90683b8997d8b9649881b3dc88336b13b7bdd60117 - md5: fd40bf7f7f4bc4b647dc8512053d9873 - depends: - - python >=3.10 - - python - constrains: - - numpy >=1.24 - - scipy >=1.10,!=1.11.0,!=1.11.1 - - matplotlib >=3.7 - - pandas >=2.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/networkx?source=hash-mapping - size: 1265008 - timestamp: 1731521053408 -- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda - sha256: 0ba94a61f91d67413e60fa8daa85627a8f299b5054b0eff8f93d26da83ec755e - md5: b0cea2c364bf65cd19e023040eeab05d - depends: - - __glibc >=2.17,<3.0.a0 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libgcc >=13 - - liblapack >=3.9.0,<4.0a0 - - libstdcxx >=13 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=hash-mapping - size: 7893263 - timestamp: 1747545075833 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.2.6-py310h4d83441_0.conda - sha256: 87704bcd5f4a4f88eaf2a97f07e9825803b58a8003a209b91e89669317523faf - md5: f4bd8ac423d04b3c444b96f2463d3519 - depends: - - __osx >=11.0 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libcxx >=18 - - liblapack >=3.9.0,<4.0a0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=hash-mapping - size: 5841650 - timestamp: 1747545043441 -- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda - sha256: 6f628e51763b86a535a723664e3aa1e38cb7147a2697f80b75c1980c1ed52f3e - md5: d2596785ac2cf5bab04e2ee9e5d04041 - depends: - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - numpy-base <0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/numpy?source=hash-mapping - size: 6596153 - timestamp: 1747545352390 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h55fea9a_1.conda - sha256: 0b7396dacf988f0b859798711b26b6bc9c6161dca21bacfd778473da58730afa - md5: 01243c4aaf71bde0297966125aea4706 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libpng >=1.6.50,<1.7.0a0 - - libstdcxx >=14 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 357828 - timestamp: 1754297886899 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.3-h889cd5d_1.conda - sha256: 6013916893fcd9bc97c479279cfe4616de7735ec566bad0ee41bc729e14d31b2 - md5: ab581998c77c512d455a13befcddaac3 - depends: - - __osx >=11.0 - - libcxx >=19 - - libpng >=1.6.50,<1.7.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 320198 - timestamp: 1754297986425 -- conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h24db6dd_1.conda - sha256: c29cb1641bc5cfc2197e9b7b436f34142be4766dd2430a937b48b7474935aa55 - md5: 25f45acb1a234ad1c9b9a20e1e6c559e - depends: - - libpng >=1.6.50,<1.7.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 245076 - timestamp: 1754298075628 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - sha256: cb0b07db15e303e6f0a19646807715d28f1264c6350309a559702f4f34f37892 - md5: 2e5bf4f1da39c0b32778561c3c4e5878 - depends: - - __glibc >=2.17,<3.0.a0 - - cyrus-sasl >=2.1.27,<3.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libgcc >=13 - - libstdcxx >=13 - - openssl >=3.5.0,<4.0a0 - license: OLDAP-2.8 - license_family: BSD - purls: [] - size: 780253 - timestamp: 1748010165522 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda - sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c - md5: f61eb8cd60ff9057122a3d338b99c00f - depends: - - __glibc >=2.17,<3.0.a0 - - ca-certificates - - libgcc >=14 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3164551 - timestamp: 1769555830639 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda - sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 - md5: f4f6ad63f98f64191c3e77c5f5f29d76 - depends: - - __osx >=11.0 - - ca-certificates - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3104268 - timestamp: 1769556384749 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda - sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 - md5: eb585509b815415bc964b2c7e11c7eb3 - depends: - - ca-certificates - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 9343023 - timestamp: 1769557547888 -- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda - sha256: c1fc0f953048f743385d31c468b4a678b3ad20caffdeaa94bed85ba63049fd58 - md5: b76541e68fea4d511b1ac46a28dcd2c6 - depends: - - python >=3.8 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/packaging?source=compressed-mapping - size: 72010 - timestamp: 1769093650580 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda - sha256: 43fd80e57ebc9e0c00d169aafce533c49359174dea327a7fa8ca7454628a56f7 - md5: 07697a584fab513ce895c4511f7a2403 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.19,<3 - - numpy >=1.22.4 - - python >=3.10,<3.11.0a0 - - python-dateutil >=2.8.2 - - python-tzdata >=2022.7 - - python_abi 3.10.* *_cp310 - - pytz >=2020.1 - constrains: - - tabulate >=0.9.0 - - psycopg2 >=2.9.6 - - pyarrow >=10.0.1 - - numba >=0.56.4 - - xlsxwriter >=3.0.5 - - qtpy >=2.3.0 - - fastparquet >=2022.12.0 - - scipy >=1.10.0 - - sqlalchemy >=2.0.0 - - openpyxl >=3.1.0 - - html5lib >=1.1 - - s3fs >=2022.11.0 - - lxml >=4.9.2 - - odfpy >=1.4.1 - - pandas-gbq >=0.19.0 - - pytables >=3.8.0 - - fsspec >=2022.11.0 - - gcsfs >=2022.11.0 - - bottleneck >=1.3.6 - - zstandard >=0.19.0 - - pyxlsb >=1.0.10 - - xarray >=2022.12.0 - - pyreadstat >=1.2.0 - - python-calamine >=0.1.7 - - beautifulsoup4 >=4.11.2 - - xlrd >=2.0.1 - - tzdata >=2022.7 - - numexpr >=2.8.4 - - matplotlib >=3.6.3 - - blosc >=1.21.3 - - pyqt5 >=5.15.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pandas?source=hash-mapping - size: 13029755 - timestamp: 1744430958318 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py310h5936506_3.conda - sha256: d6999d5bcebe1837b26d324b6a440b70a23f3e744e9a176fc9c00fc2408c95e7 - md5: ac8e350fb40fcc86b1554ec20af922d0 - depends: - - __osx >=11.0 - - libcxx >=18 - - numpy >=1.19,<3 - - numpy >=1.22.4 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python-dateutil >=2.8.2 - - python-tzdata >=2022.7 - - python_abi 3.10.* *_cp310 - - pytz >=2020.1 - constrains: - - openpyxl >=3.1.0 - - tzdata >=2022.7 - - tabulate >=0.9.0 - - pyxlsb >=1.0.10 - - pyqt5 >=5.15.9 - - pyreadstat >=1.2.0 - - pandas-gbq >=0.19.0 - - qtpy >=2.3.0 - - scipy >=1.10.0 - - pytables >=3.8.0 - - lxml >=4.9.2 - - numba >=0.56.4 - - odfpy >=1.4.1 - - numexpr >=2.8.4 - - xlrd >=2.0.1 - - fsspec >=2022.11.0 - - html5lib >=1.1 - - xarray >=2022.12.0 - - pyarrow >=10.0.1 - - xlsxwriter >=3.0.5 - - s3fs >=2022.11.0 - - bottleneck >=1.3.6 - - beautifulsoup4 >=4.11.2 - - blosc >=1.21.3 - - matplotlib >=3.6.3 - - psycopg2 >=2.9.6 - - zstandard >=0.19.0 - - gcsfs >=2022.11.0 - - sqlalchemy >=2.0.0 - - fastparquet >=2022.12.0 - - python-calamine >=0.1.7 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pandas?source=hash-mapping - size: 12046934 - timestamp: 1744430939366 -- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py310hb4db72f_3.conda - sha256: fa3986017273899fd21aa14a524469bedac3923e2ecfdfdba59a34769b56b9b8 - md5: 60c6ae5813eb1cbc4f7774fb69623db8 - depends: - - numpy >=1.19,<3 - - numpy >=1.22.4 - - python >=3.10,<3.11.0a0 - - python-dateutil >=2.8.2 - - python-tzdata >=2022.7 - - python_abi 3.10.* *_cp310 - - pytz >=2020.1 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - scipy >=1.10.0 - - pyarrow >=10.0.1 - - python-calamine >=0.1.7 - - xlsxwriter >=3.0.5 - - openpyxl >=3.1.0 - - numexpr >=2.8.4 - - matplotlib >=3.6.3 - - fsspec >=2022.11.0 - - lxml >=4.9.2 - - html5lib >=1.1 - - s3fs >=2022.11.0 - - bottleneck >=1.3.6 - - blosc >=1.21.3 - - gcsfs >=2022.11.0 - - pyqt5 >=5.15.9 - - pyreadstat >=1.2.0 - - sqlalchemy >=2.0.0 - - qtpy >=2.3.0 - - odfpy >=1.4.1 - - tabulate >=0.9.0 - - pyxlsb >=1.0.10 - - tzdata >=2022.7 - - xarray >=2022.12.0 - - zstandard >=0.19.0 - - beautifulsoup4 >=4.11.2 - - xlrd >=2.0.1 - - pandas-gbq >=0.19.0 - - psycopg2 >=2.9.6 - - numba >=0.56.4 - - fastparquet >=2022.12.0 - - pytables >=3.8.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pandas?source=hash-mapping - size: 11917543 - timestamp: 1744431481619 -- conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda - sha256: 42b2d77ccea60752f3aa929a6413a7835aaacdbbde679f2f5870a744fa836b94 - md5: 97c1ce2fffa1209e7afb432810ec6e12 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/parso?source=compressed-mapping - size: 82287 - timestamp: 1770676243987 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda - sha256: 09717569649d89caafbf32f6cda1e65aef86e5a86c053d30e4ce77fca8d27b68 - md5: 31614c73d7b103ef76faa4d83d261d34 - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - libgcc >=13 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 956207 - timestamp: 1745931215744 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.44-ha881caa_2.conda - sha256: 797411a2d748c11374b84329002f3c65db032cbf012b20d9b14dba9b6ac52d06 - md5: 1a3f7708de0b393e6665c9f7494b055e - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 621564 - timestamp: 1745931340774 -- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda - sha256: 15dffc9a2d6bb6b8ccaa7cbd26b229d24f1a0a1c4f5685b308a63929c56b381f - md5: a912b2c4ff0f03101c751aa79a331831 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 816653 - timestamp: 1745931851696 -- conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - sha256: 202af1de83b585d36445dc1fda94266697341994d1a3328fabde4989e1b3d07a - md5: d0d408b1f18883a944376da5cf8101ea - depends: - - ptyprocess >=0.5 - - python >=3.9 - license: ISC - purls: - - pkg:pypi/pexpect?source=hash-mapping - size: 53561 - timestamp: 1733302019362 -- conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - sha256: e2ac3d66c367dada209fc6da43e645672364b9fd5f9d28b9f016e24b81af475b - md5: 11a9d1d09a3615fc07c3faf79bc0b943 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pickleshare?source=hash-mapping - size: 11748 - timestamp: 1733327448200 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.3.0-py310h6557065_3.conda - sha256: 7fe27fd1c5a3d85ea355a609d050e50469382223bbf5a07ca750e30b6aebdc25 - md5: e169733dc0c743687a852f1c6e989140 - depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.6.0,<2.0a0 - - libxcb >=1.17.0,<2.0a0 - - python_abi 3.10.* *_cp310 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - lcms2 >=2.17,<3.0a0 - - tk >=8.6.13,<8.7.0a0 - - libjpeg-turbo >=3.1.0,<4.0a0 - - openjpeg >=2.5.3,<3.0a0 - - libzlib >=1.3.1,<2.0a0 - license: HPND - purls: - - pkg:pypi/pillow?source=hash-mapping - size: 882171 - timestamp: 1758208668856 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-11.3.0-py310h5de80a5_3.conda - sha256: f81e77e125c7be7a368aa807784bdb8fe15f26c0b3944560e34a5a8c56acf8e0 - md5: 289f10aa08eeb9a44e62fdc5c9810a7a - depends: - - python - - python 3.10.* *_cpython - - __osx >=11.0 - - libwebp-base >=1.6.0,<2.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - libxcb >=1.17.0,<2.0a0 - - lcms2 >=2.17,<3.0a0 - - openjpeg >=2.5.3,<3.0a0 - - python_abi 3.10.* *_cp310 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - libjpeg-turbo >=3.1.0,<4.0a0 - - tk >=8.6.13,<8.7.0a0 - license: HPND - purls: - - pkg:pypi/pillow?source=hash-mapping - size: 803755 - timestamp: 1758208741246 -- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.3.0-py310hb3a2f59_3.conda - sha256: d4825cfe13dc10bb90553c663b86128c8e53bb8c3eda768f7d0d29c3ad878a92 - md5: a12291a9a7acce46716c518c31ebb298 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libjpeg-turbo >=3.1.0,<4.0a0 - - libwebp-base >=1.6.0,<2.0a0 - - tk >=8.6.13,<8.7.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libzlib >=1.3.1,<2.0a0 - - openjpeg >=2.5.3,<3.0a0 - - libxcb >=1.17.0,<2.0a0 - - lcms2 >=2.17,<3.0a0 - - libfreetype >=2.14.1 - - libfreetype6 >=2.14.1 - - python_abi 3.10.* *_cp310 - license: HPND - purls: - - pkg:pypi/pillow?source=hash-mapping - size: 786227 - timestamp: 1758208682963 -- conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.0.1-pyh8b19718_0.conda - sha256: 585940f09d87787f79f73ff5dff8eb2af8a67e5bec5eebf2f553cd26c840ba69 - md5: 79b5c1440aedc5010f687048d9103628 - depends: - - python >=3.9,<3.13.0a0 - - setuptools - - wheel - license: MIT - license_family: MIT - purls: - - pkg:pypi/pip?source=hash-mapping - size: 1256460 - timestamp: 1739142857253 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda - sha256: 43d37bc9ca3b257c5dd7bf76a8426addbdec381f6786ff441dc90b1a49143b6a - md5: c01af13bdc553d1a8fbfff6e8db075f0 - depends: - - libgcc >=14 - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: MIT - license_family: MIT - purls: [] - size: 450960 - timestamp: 1754665235234 -- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda - sha256: 246fce4706b3f8b247a7d6142ba8d732c95263d3c96e212b9d63d6a4ab4aff35 - md5: 08c8fa3b419df480d985e304f7884d35 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 542795 - timestamp: 1754665193489 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda - sha256: 7f263219cecf0ba6d74c751efa60c4676ce823157ca90aa43ebba5ac615ca0fa - md5: 4fefefb892ce9cc1539405bec2f1a6cd - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/platformdirs?source=compressed-mapping - size: 25643 - timestamp: 1771233827084 -- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-5.24.1-pyhd8ed1ab_1.conda - sha256: d1bbf2d80105bfc8a7ed9817888f4a1686ed393d6435572921add09cc9347c1c - md5: 71ac632876630091c81c50a05ec5e030 - depends: - - packaging - - python >=3.9 - - tenacity >=6.2.0 - constrains: - - ipywidgets >=7.6 - license: MIT - license_family: MIT - purls: - - pkg:pypi/plotly?source=hash-mapping - size: 8022748 - timestamp: 1733733328161 -- conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.5.1-h0054346_0.conda - sha256: 835afb9c8198895ec1ce2916320503d47bb0c25b75c228d744c44e505f1f4e3b - md5: 398cabfd9bd75e90d0901db95224f25f - depends: - - __glibc >=2.17,<3.0.a0 - - libcurl >=8.10.1,<9.0a0 - - libgcc >=13 - - libsqlite >=3.47.0,<4.0a0 - - libstdcxx >=13 - - libtiff >=4.7.0,<4.8.0a0 - - sqlite - constrains: - - proj4 ==999999999999 - license: MIT - license_family: MIT - purls: [] - size: 3108751 - timestamp: 1733138115896 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.5.1-h1318a7e_0.conda - sha256: c6289d6f1a13f28ff3754ac0cb2553f7e7bc4a3102291115f62a04995d0421eb - md5: 5eb42e77ae79b46fabcb0f6f6d130763 - depends: - - __osx >=11.0 - - libcurl >=8.10.1,<9.0a0 - - libcxx >=18 - - libsqlite >=3.47.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - sqlite - constrains: - - proj4 ==999999999999 - license: MIT - license_family: MIT - purls: [] - size: 2673401 - timestamp: 1733138376056 -- conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.5.1-h4f671f6_0.conda - sha256: ddd0be6172e3903bc6602a93394e8051826235377c1ce8c6ba2435869794e726 - md5: 7303dac2aa92318f319508aedab6a127 - depends: - - libcurl >=8.10.1,<9.0a0 - - libsqlite >=3.47.0,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - sqlite - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - constrains: - - proj4 ==999999999999 - license: MIT - license_family: MIT - purls: [] - size: 2740461 - timestamp: 1733138695290 -- conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - sha256: 4817651a276016f3838957bfdf963386438c70761e9faec7749d411635979bae - md5: edb16f14d920fb3faf17f5ce582942d6 - depends: - - python >=3.10 - - wcwidth - constrains: - - prompt_toolkit 3.0.52 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/prompt-toolkit?source=hash-mapping - size: 273927 - timestamp: 1756321848365 -- conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py310h139afa4_0.conda - sha256: 3a6d46033ebad3e69ded3f76852b9c378c2cff632f57421b5926c6add1bae475 - md5: d210342acdb8e3ca6434295497c10b7c - depends: - - python - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 179015 - timestamp: 1769678154886 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py310haea493c_0.conda - sha256: f2336814f97e23cec0c6b082afecc2e9ec5941fce19f08d453e8ea53221c82ef - md5: 8c73aa05dd807bb9b1cdc0e028ab4f13 - depends: - - python - - python 3.10.* *_cpython - - __osx >=11.0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 192483 - timestamp: 1769678341407 -- conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py310h1637853_0.conda - sha256: 71b14cfddc05c0d8c22e2e15103a29ce404ea346e328c7bca5fd1ad682f7f274 - md5: 97d88bac43c17c12d0b266f523a37f61 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/psutil?source=hash-mapping - size: 196390 - timestamp: 1769678167722 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 - md5: b3c17d95b5a10c6e64a21fa17573e70e - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 8252 - timestamp: 1726802366959 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda - sha256: 8ed65e17fbb0ca944bfb8093b60086e3f9dd678c3448b5de212017394c247ee3 - md5: 415816daf82e0b23a736a069a75e9da7 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 8381 - timestamp: 1726802424786 -- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - sha256: 7e446bafb4d692792310ed022fe284e848c6a868c861655a92435af7368bae7b - md5: 3c8f2573569bb816483e5cf57efbbe29 - depends: - - libgcc >=13 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 9389 - timestamp: 1726802555076 -- conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - sha256: a7713dfe30faf17508ec359e0bc7e0983f5d94682492469bd462cdaae9c64d83 - md5: 7d9daffbb8d8e0af0f769dbbcd173a54 - depends: - - python >=3.9 - license: ISC - purls: - - pkg:pypi/ptyprocess?source=hash-mapping - size: 19457 - timestamp: 1733302371990 -- conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - sha256: 71bd24600d14bb171a6321d523486f6a06f855e75e547fa0cb2a0953b02047f0 - md5: 3bfdfb8dbcdc4af1ae3f9a8eb3948f04 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pure-eval?source=hash-mapping - size: 16668 - timestamp: 1733569518868 -- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a - md5: 6b6ece66ebcae2d5f326c77ef2c5a066 - depends: - - python >=3.9 - license: BSD-2-Clause - license_family: BSD - purls: - - pkg:pypi/pygments?source=hash-mapping - size: 889287 - timestamp: 1750615908735 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyogrio-0.10.0-py310h0aed7a2_1.conda - sha256: e7e66bac7ffbbd10a2abef7cea842bb7629adbf6d8b73dcc40079473d3aed77f - md5: 95459fb36d2c19b491361f0a2b6feaf1 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libgdal-core >=3.10.0,<3.11.0a0 - - libstdcxx >=13 - - numpy - - packaging - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyogrio?source=hash-mapping - size: 610091 - timestamp: 1732013579548 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyogrio-0.10.0-py310hd68230c_1.conda - sha256: 1cb31811cc2bb1c5abfe03ecfc1ac1e0b9a1cab6dc69e51f072d2dd22451b2fb - md5: f630c4fe976af207f90a03012114c479 - depends: - - __osx >=11.0 - - libcxx >=18 - - libgdal-core >=3.10.0,<3.11.0a0 - - numpy - - packaging - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyogrio?source=hash-mapping - size: 534901 - timestamp: 1732013619674 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyogrio-0.10.0-py310hf80745b_1.conda - sha256: da7913ee9f0d6843e5605aa779c5dc2ebc08eb69c817db7e9d3068a3a672bda9 - md5: a5c256a8a898c1f84dcd450a27887f8c - depends: - - libgdal-core >=3.10.0,<3.11.0a0 - - numpy - - packaging - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyogrio?source=hash-mapping - size: 780156 - timestamp: 1732013834 -- conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda - sha256: 417fba4783e528ee732afa82999300859b065dc59927344b4859c64aae7182de - md5: 3687cc0b82a8b4c17e1f0eb7e47163d5 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyparsing?source=compressed-mapping - size: 110893 - timestamp: 1769003998136 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyproj-3.7.0-py310h2e9f774_0.conda - sha256: 16a69974015cdcacef2a82d3efcf30dcd556d2dbdf3deab7641495b78625c1af - md5: 42a3ea3c283d930ae6d156b97ffe4740 - depends: - - __glibc >=2.17,<3.0.a0 - - certifi - - libgcc >=13 - - proj >=9.5.0,<9.6.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyproj?source=hash-mapping - size: 536119 - timestamp: 1727795517990 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyproj-3.7.0-py310h861c57f_0.conda - sha256: bd81295fcc04c569fcfbf9d8cef744687ee9a5940716b06f363c7a331d73025e - md5: fcc2303072c38beb8dbdc6fc9211950e - depends: - - __osx >=11.0 - - certifi - - proj >=9.5.0,<9.6.0a0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyproj?source=hash-mapping - size: 474993 - timestamp: 1727795735537 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyproj-3.7.0-py310h19d4cff_0.conda - sha256: 3b9b1a447efa082f47633c6af6887979ebe68f880ec226f60952e199e47804f6 - md5: aec37353830fb374109d3d7e6347cbcd - depends: - - certifi - - proj >=9.5.0,<9.6.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyproj?source=hash-mapping - size: 733814 - timestamp: 1727795859575 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py310hfd10a26_0.conda - sha256: 545ee500ea1dcb8836934b3af0bad4b9f702f03e2f931f4d133d859380058722 - md5: 1610ccfe262ee519716bb69bd4395572 - depends: - - __glibc >=2.17,<3.0.a0 - - libclang13 >=20.1.2 - - libegl >=1.7.0,<2.0a0 - - libgcc >=13 - - libgl >=1.7.0,<2.0a0 - - libopengl >=1.7.0,<2.0a0 - - libstdcxx >=13 - - libxml2 >=2.13.7,<2.14.0a0 - - libxslt >=1.1.39,<2.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - qt6-main 6.9.0.* - - qt6-main >=6.9.0,<6.10.0a0 - license: LGPL-3.0-only - license_family: LGPL - purls: - - pkg:pypi/pyside6?source=hash-mapping - - pkg:pypi/shiboken6?source=hash-mapping - size: 10032602 - timestamp: 1743760684455 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py310hc1b6536_0.conda - sha256: 5308c1032c681e3ad61b26c27d3c0f1f911ba52c2f63f2285b3c489d09cc53ed - md5: e90c8d8a817b5d63b7785d7d18c99ae0 - depends: - - libclang13 >=20.1.2 - - libxml2 >=2.13.7,<2.14.0a0 - - libxslt >=1.1.39,<2.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - qt6-main 6.9.0.* - - qt6-main >=6.9.0,<6.10.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 - license: LGPL-3.0-only - license_family: LGPL - purls: - - pkg:pypi/pyside6?source=hash-mapping - - pkg:pypi/shiboken6?source=hash-mapping - size: 8784423 - timestamp: 1743761558911 -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca - md5: e2fd202833c4a981ce8a65974fe4abd1 - depends: - - __win - - python >=3.9 - - win_inet_pton - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pysocks?source=hash-mapping - size: 21784 - timestamp: 1733217448189 -- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 - md5: 461219d1a5bd61342293efa2c0c90eac - depends: - - __unix - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pysocks?source=hash-mapping - size: 21085 - timestamp: 1733217331982 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.19-h3c07f61_3_cpython.conda - build_number: 3 - sha256: 2d8b5566d82c3872f057661e056d696f2f77a17ee5a36d9ae6ec43052c4d1c51 - md5: be48679ccfbc8710dea1d5970600fa04 - depends: - - __glibc >=2.17,<3.0.a0 - - bzip2 >=1.0.8,<2.0a0 - - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.4,<4.0a0 - - libgcc >=14 - - liblzma >=5.8.2,<6.0a0 - - libnsl >=2.0.1,<2.1.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libuuid >=2.41.3,<3.0a0 - - libxcrypt >=4.4.36 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.10.* *_cp310 - license: Python-2.0 - purls: [] - size: 25358312 - timestamp: 1769471983988 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.19-hcd7f573_3_cpython.conda - build_number: 3 - sha256: 7ce2adb0cc4d45178dc018b55148fa2d6ccae0c98291cef1b21dafcda2de2687 - md5: ac461265b59028847699c0606e17804b - depends: - - __osx >=11.0 - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.4,<4.0a0 - - liblzma >=5.8.2,<6.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - openssl >=3.5.4,<4.0a0 - - readline >=8.3,<9.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - constrains: - - python_abi 3.10.* *_cp310 - license: Python-2.0 - purls: [] - size: 12507955 - timestamp: 1769472053757 -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.19-hc20f281_3_cpython.conda - build_number: 3 - sha256: 77cbf9ab8e6c9f67e645b00a3224f35c92333fd9a737f5e53ef7060d0604c4cb - md5: 7be098c303e842443528587a5b2297f1 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.3,<3.0a0 - - libffi >=3.4,<4.0a0 - - liblzma >=5.8.2,<6.0a0 - - libsqlite >=3.51.2,<4.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.4,<4.0a0 - - tk >=8.6.13,<8.7.0a0 - - tzdata - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - constrains: - - python_abi 3.10.* *_cp310 - license: Python-2.0 - purls: [] - size: 16076382 - timestamp: 1769471071119 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 - md5: 5b8d21249ff20967101ffa321cab24e8 - depends: - - python >=3.9 - - six >=1.5 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/python-dateutil?source=hash-mapping - size: 233310 - timestamp: 1751104122689 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda - sha256: 467134ef39f0af2dbb57d78cb3e4821f01003488d331a8dd7119334f4f47bfbd - md5: 7ead57407430ba33f681738905278d03 - depends: - - python >=3.10 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/tzdata?source=compressed-mapping - size: 143542 - timestamp: 1765719982349 -- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-8_cp310.conda - build_number: 8 - sha256: 7ad76fa396e4bde336872350124c0819032a9e8a0a40590744ff9527b54351c1 - md5: 05e00f3b21e88bb3d658ac700b2ce58c - constrains: - - python 3.10.* *_cpython - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 6999 - timestamp: 1752805924192 -- conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - sha256: 8d2a8bf110cc1fc3df6904091dead158ba3e614d8402a83e51ed3a8aa93cdeb0 - md5: bc8e3267d44011051f2eb14d22fb0960 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pytz?source=hash-mapping - size: 189015 - timestamp: 1742920947249 -- conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-311-py310h282bd7d_1.conda - sha256: 2ce920e200699cc2a114106665451c05efcaf5cf0ca46685d9a7a5914616f7b5 - md5: 0289b272f8a22ad8fc29d6747383b503 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/pywin32?source=hash-mapping - size: 6293229 - timestamp: 1756487147910 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py310h89163eb_2.conda - sha256: 5fba7f5babcac872c72f6509c25331bcfac4f8f5031f0102530a41b41336fce6 - md5: fd343408e64cf1e273ab7c710da374db - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 182769 - timestamp: 1737454971552 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py310hc74094e_2.conda - sha256: 0c46719507e1664b1085f2142b8250250c6aae01ec367d18068688efeba445ec - md5: b8be3d77488c580d2fd81c9bb3cacdf1 - depends: - - __osx >=11.0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 166853 - timestamp: 1737454973579 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py310h38315fa_2.conda - sha256: 49dd492bdf2c479118ca9d61a59ce259594853d367a1a0548926f41a6e734724 - md5: 9986c3731bb820db0830dd0825c26cf9 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - yaml >=0.2.5,<0.3.0a0 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyyaml?source=hash-mapping - size: 157941 - timestamp: 1737455030235 -- conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py310hc4bea81_2.conda - sha256: 3de52f8218a822a1bbfdbeb5ae948c178dfa7622dc81621fe5c6ac0c74dffdf6 - md5: 0731121636c788d581db487531d53928 - depends: - - python - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - zeromq >=4.3.5,<4.4.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 327211 - timestamp: 1771716952315 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py310hf0664f0_2.conda - sha256: 0ac9742b67c453cd6ba7986d0c9365da87ee6cc47fb89a98eb453895fe2f238a - md5: 56eb04048880c7c521f18cb90606e3ea - depends: - - python - - python 3.10.* *_cpython - - __osx >=11.0 - - libcxx >=19 - - zeromq >=4.3.5,<4.4.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=compressed-mapping - size: 305070 - timestamp: 1771717036757 -- conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-27.1.0-py310h78cba24_2.conda - sha256: 28ab660f491cc208a8f3f33c4d3adfe5eb51f9bfb117f3c68e71b49637e44dde - md5: 8cecf961521c3e4cf48df04f8cb259c8 - depends: - - python - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - python_abi 3.10.* *_cp310 - - zeromq >=4.3.5,<4.3.6.0a0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/pyzmq?source=hash-mapping - size: 305690 - timestamp: 1771716971893 -- conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda - sha256: 776363493bad83308ba30bcb88c2552632581b143e8ee25b1982c8c743e73abc - md5: 353823361b1d27eb3960efb076dfcaf6 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: LicenseRef-Qhull - purls: [] - size: 552937 - timestamp: 1720813982144 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda - sha256: 873ac689484262a51fd79bc6103c1a1bedbf524924d7f0088fb80703042805e4 - md5: 6483b1f59526e05d7d894e466b5b6924 - depends: - - __osx >=11.0 - - libcxx >=16 - license: LicenseRef-Qhull - purls: [] - size: 516376 - timestamp: 1720814307311 -- conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda - sha256: 887d53486a37bd870da62b8fa2ebe3993f912ad04bd755e7ed7c47ced97cbaa8 - md5: 854fbdff64b572b5c0b470f334d34c11 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LicenseRef-Qhull - purls: [] - size: 1377020 - timestamp: 1720814433486 -- conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda - sha256: d52a7d4a26f5cb3d335067a1d4140f7f2b0b53ad8d78b2c766e88906863c33aa - md5: ac0eb548e24a2cb3c2c8ba060aef7db2 - depends: - - __glibc >=2.17,<3.0.a0 - - alsa-lib >=1.2.14,<1.3.0a0 - - dbus >=1.13.6,<2.0a0 - - double-conversion >=3.3.1,<3.4.0a0 - - fontconfig >=2.15.0,<3.0a0 - - fonts-conda-ecosystem - - harfbuzz >=11.0.1 - - icu >=75.1,<76.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libclang-cpp20.1 >=20.1.4,<20.2.0a0 - - libclang13 >=20.1.4 - - libcups >=2.3.3,<2.4.0a0 - - libdrm >=2.4.124,<2.5.0a0 - - libegl >=1.7.0,<2.0a0 - - libfreetype >=2.13.3 - - libfreetype6 >=2.13.3 - - libgcc >=13 - - libgl >=1.7.0,<2.0a0 - - libglib >=2.84.1,<3.0a0 - - libjpeg-turbo >=3.1.0,<4.0a0 - - libllvm20 >=20.1.4,<20.2.0a0 - - libpng >=1.6.47,<1.7.0a0 - - libpq >=17.4,<18.0a0 - - libsqlite >=3.49.1,<4.0a0 - - libstdcxx >=13 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libxcb >=1.17.0,<2.0a0 - - libxkbcommon >=1.9.2,<2.0a0 - - libxml2 >=2.13.7,<2.14.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - pcre2 >=10.44,<10.45.0a0 - - wayland >=1.23.1,<2.0a0 - - xcb-util >=0.4.1,<0.5.0a0 - - xcb-util-cursor >=0.1.5,<0.2.0a0 - - xcb-util-image >=0.4.0,<0.5.0a0 - - xcb-util-keysyms >=0.4.1,<0.5.0a0 - - xcb-util-renderutil >=0.3.10,<0.4.0a0 - - xcb-util-wm >=0.4.2,<0.5.0a0 - - xorg-libice >=1.1.2,<2.0a0 - - xorg-libsm >=1.2.6,<2.0a0 - - xorg-libx11 >=1.8.12,<2.0a0 - - xorg-libxcomposite >=0.4.6,<1.0a0 - - xorg-libxcursor >=1.2.3,<2.0a0 - - xorg-libxdamage >=1.1.6,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxrandr >=1.5.4,<2.0a0 - - xorg-libxtst >=1.2.5,<2.0a0 - - xorg-libxxf86vm >=1.1.6,<2.0a0 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - qt 6.9.0 - license: LGPL-3.0-only - license_family: LGPL - purls: [] - size: 51745422 - timestamp: 1746636875150 -- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h83cda92_0.conda - sha256: 84ff37de3c72a612dfbf9b317d5501231a87582f2edf4959ff706b84b4aa9246 - md5: d92e5a0de3263315551d54d5574f5193 - depends: - - double-conversion >=3.3.1,<3.4.0a0 - - harfbuzz >=11.0.0,<12.0a0 - - icu >=75.1,<76.0a0 - - krb5 >=1.21.3,<1.22.0a0 - - libclang13 >=20.1.1 - - libglib >=2.84.0,<3.0a0 - - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.47,<1.7.0a0 - - libsqlite >=3.49.1,<4.0a0 - - libtiff >=4.7.0,<4.8.0a0 - - libwebp-base >=1.5.0,<2.0a0 - - libzlib >=1.3.1,<2.0a0 - - openssl >=3.4.1,<4.0a0 - - pcre2 >=10.44,<10.45.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.42.34438 - - zstd >=1.5.7,<1.6.0a0 - constrains: - - qt 6.9.0 - license: LGPL-3.0-only - license_family: LGPL - purls: [] - size: 94992566 - timestamp: 1743635306726 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda - sha256: 6e5e704c1c21f820d760e56082b276deaf2b53cf9b751772761c3088a365f6f4 - md5: 2c42649888aac645608191ffdc80d13a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - constrains: - - __glibc >=2.17 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 5176669 - timestamp: 1746622023242 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rav1e-0.7.1-h0716509_3.conda - sha256: 65f862b2b31ef2b557990a82015cbd41e5a66041c2f79b4451dd14b4595d4c04 - md5: 7b37f30516100b86ea522350c8cab44c - depends: - - __osx >=11.0 - constrains: - - __osx >=11.0 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 856271 - timestamp: 1746622200646 -- conda: https://conda.anaconda.org/conda-forge/win-64/rav1e-0.7.1-ha073cba_3.conda - sha256: d19a58b882a0387c7c8efbfce4e67a0df4b19d8da6cf6cec3011b6079e5bc743 - md5: 3bd3626822633688691ed41d661c2b2e - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 4122383 - timestamp: 1746622805379 -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 - md5: d7d95fc8287ea7bf33e0e7116d2b95ec - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 345073 - timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 - md5: f8381319127120ce51e081dce4865cf4 - depends: - - __osx >=11.0 - - ncurses >=6.5,<7.0a0 - license: GPL-3.0-only - license_family: GPL - purls: [] - size: 313930 - timestamp: 1765813902568 -- pypi: https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl - name: referencing - version: 0.37.0 - sha256: 381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 - requires_dist: - - attrs>=22.2.0 - - rpds-py>=0.7.0 - - typing-extensions>=4.4.0 ; python_full_version < '3.13' - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda - sha256: 7813c38b79ae549504b2c57b3f33394cea4f2ad083f0994d2045c2e24cb538c5 - md5: c65df89a0b2e321045a9e01d1337b182 - depends: - - python >=3.10 - - certifi >=2017.4.17 - - charset-normalizer >=2,<4 - - idna >=2.5,<4 - - urllib3 >=1.21.1,<3 - - python - constrains: - - chardet >=3.0.2,<6 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/requests?source=compressed-mapping - size: 63602 - timestamp: 1766926974520 -- pypi: https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl - name: rpds-py - version: 0.30.0 - sha256: 4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: rpds-py - version: 0.30.0 - sha256: 0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 - requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl - name: rpds-py - version: 0.30.0 - sha256: 1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 - requires_python: '>=3.10' -- conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.3.0-py310hfd4b839_3.conda - sha256: 0fa05f5698eca0fe401d1d740c6836d2674389dd8d2c39d43bd2411ae53ae8a0 - md5: 9633c2a1e6cd2accc27e5b93ebf58d0b - depends: - - libspatialindex >=2.1.0,<2.1.1.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rtree?source=hash-mapping - size: 57967 - timestamp: 1734967774693 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.3.0-py310h78b29c1_3.conda - sha256: 49150c8af86af4e5cd10965957f5e12bd6f0cd21e868b25bcddc810cf96ae02f - md5: b1a98514f83f96139df2030d871b689b - depends: - - libspatialindex >=2.1.0,<2.1.1.0a0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rtree?source=hash-mapping - size: 58882 - timestamp: 1734967887770 -- conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.3.0-py310hdd37b41_3.conda - sha256: 7e527a1d7fd61a94d842490aa36cd283cb864fe97fb08b329a03925e327a2c25 - md5: 9bc10b479d71bfe1922c82087e2b1ab5 - depends: - - libspatialindex >=2.1.0,<2.1.1.0a0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: MIT - license_family: MIT - purls: - - pkg:pypi/rtree?source=hash-mapping - size: 58495 - timestamp: 1734967816955 -- conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.7.2-py310h228f341_0.conda - sha256: 8af2a49b75b9697653a0bf55717c8153732c4fc53f58d4aa0ed692ae348c49f6 - md5: 0f3e3324506bd3e67934eda9895f37a7 - depends: - - __glibc >=2.17,<3.0.a0 - - _openmp_mutex >=4.5 - - joblib >=1.2.0 - - libgcc >=14 - - libstdcxx >=14 - - numpy >=1.21,<3 - - numpy >=1.22.0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - scipy >=1.8.0 - - threadpoolctl >=3.1.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scikit-learn?source=hash-mapping - size: 8415134 - timestamp: 1757406407327 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.7.2-py310h660f142_0.conda - sha256: f7960d72c7d36e1830d985d70587bc85e571d4bdcdea3cfea6e81602e2a222ea - md5: 26f940c6a467ed3fe2b4fbab43ab312e - depends: - - __osx >=11.0 - - joblib >=1.2.0 - - libcxx >=19 - - llvm-openmp >=19.1.7 - - numpy >=1.21,<3 - - numpy >=1.22.0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - - scipy >=1.8.0 - - threadpoolctl >=3.1.0 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scikit-learn?source=hash-mapping - size: 7749690 - timestamp: 1757407202358 -- conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.7.2-py310h21054b0_0.conda - sha256: 8515607e6b0e97edd93120368a9e788f3149fdc0855252a9d112e32ad522ba4a - md5: 2b93662be724f88f5196549133adbfe1 - depends: - - joblib >=1.2.0 - - numpy >=1.21,<3 - - numpy >=1.22.0 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - scipy >=1.8.0 - - threadpoolctl >=3.1.0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scikit-learn?source=hash-mapping - size: 7675668 - timestamp: 1757433583495 -- conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda - sha256: 4cb98641f870666d365594013701d5691205a0fe81ac3ba7778a23b1cc2caa8e - md5: 8c29cd33b64b2eb78597fa28b5595c8d - depends: - - __glibc >=2.17,<3.0.a0 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libgcc >=13 - - libgfortran - - libgfortran5 >=13.3.0 - - liblapack >=3.9.0,<4.0a0 - - libstdcxx >=13 - - numpy <2.5 - - numpy >=1.19,<3 - - numpy >=1.23.5 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scipy?source=hash-mapping - size: 16417101 - timestamp: 1739791865060 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.15.2-py310h32ab4ed_0.conda - sha256: f6ff2c1ba4775300199e8bc0331d2e2ccb5906f58f3835c5426ddc591c9ad7bf - md5: a389f540c808b22b3c696d7aea791a41 - depends: - - __osx >=11.0 - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - libcxx >=18 - - libgfortran >=5 - - libgfortran5 >=13.2.0 - - liblapack >=3.9.0,<4.0a0 - - numpy <2.5 - - numpy >=1.19,<3 - - numpy >=1.23.5 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scipy?source=hash-mapping - size: 13507343 - timestamp: 1739792089317 -- conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py310h15c175c_0.conda - sha256: f19350c2061b1cdc3151a33c3dd4f71a1a481f9b10ac186674f957814bc839bc - md5: 81798168111d1021e3d815217c444418 - depends: - - libblas >=3.9.0,<4.0a0 - - libcblas >=3.9.0,<4.0a0 - - liblapack >=3.9.0,<4.0a0 - - numpy <2.5 - - numpy >=1.19,<3 - - numpy >=1.23.5 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/scipy?source=hash-mapping - size: 14352068 - timestamp: 1739793156239 -- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda - sha256: fd7201e38e38bf7f25818d624ca8da97b8998957ca9ae3fb7fdc9c17e6b25fcd - md5: 1d00d46c634177fc8ede8b99d6089239 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/setuptools?source=compressed-mapping - size: 637506 - timestamp: 1770634745653 -- conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.6-py310had3dfd6_2.conda - sha256: f39309969c028b3b53831b4b7982d68d7de1bfdc2bf25d3330b8e4aea1494350 - md5: a4166b41e54d22e794859641b7cae2d0 - depends: - - __glibc >=2.17,<3.0.a0 - - geos >=3.13.0,<3.13.1.0a0 - - libgcc >=13 - - numpy >=1.19,<3 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/shapely?source=hash-mapping - size: 486930 - timestamp: 1727273539386 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.6-py310h6b3522b_2.conda - sha256: 34812447c29faca0b5e0682bec0eaeca5f70f89ced370d9175a8e8504bf118fb - md5: f4fd6f92dc2cb99a198e216a54dfc7cc - depends: - - __osx >=11.0 - - geos >=3.13.0,<3.13.1.0a0 - - numpy >=1.19,<3 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/shapely?source=hash-mapping - size: 449516 - timestamp: 1727273686755 -- conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.6-py310hde62f2e_2.conda - sha256: d147abfc8d8acfa460e5f8094a7271277255d6fb73075b38c808938f59408838 - md5: 3793f088ec82fd4194f2712643150132 - depends: - - geos >=3.13.0,<3.13.1.0a0 - - numpy >=1.19,<3 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/shapely?source=hash-mapping - size: 453430 - timestamp: 1727274008606 -- conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d - md5: 3339e3b65d58accf4ca4fb8748ab16b3 - depends: - - python >=3.9 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/six?source=hash-mapping - size: 18455 - timestamp: 1753199211006 -- conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda - sha256: 48f3f6a76c34b2cfe80de9ce7f2283ecb55d5ed47367ba91e8bb8104e12b8f11 - md5: 98b6c9dc80eb87b2519b97bcf7e578dd - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libstdcxx >=14 - - libgcc >=14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 45829 - timestamp: 1762948049098 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/snappy-1.2.2-hada39a4_1.conda - sha256: cb9305ede19584115f43baecdf09a3866bfcd5bcca0d9e527bd76d9a1dbe2d8d - md5: fca4a2222994acd7f691e57f94b750c5 - depends: - - libcxx >=19 - - __osx >=11.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 38883 - timestamp: 1762948066818 -- conda: https://conda.anaconda.org/conda-forge/win-64/snappy-1.2.2-h7fa0ca8_1.conda - sha256: d2deda1350abf8c05978b73cf7fe9147dd5c7f2f9b312692d1b98e52efad53c3 - md5: 3075846de68f942150069d4289aaad63 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 67417 - timestamp: 1762948090450 -- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.51.2-hbc0de68_0.conda - sha256: 65436099fd33e4471348d614c1de9235fdd4e5b7d86a5a12472922e6b6628951 - md5: a6adeaa8efb007e2e1ab3e45768ea987 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libsqlite 3.51.2 h0c1763c_0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - readline >=8.3,<9.0a0 - license: blessing - purls: [] - size: 183835 - timestamp: 1768147980363 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.51.2-h85ec8f2_0.conda - sha256: 63c2bbb58e5ca58232cbe61754b85d0a080e5360291cebd52653e000bb0ae8fd - md5: 7821b42fed75ef394d401f59f70e0732 - depends: - - __osx >=11.0 - - libsqlite 3.51.2 h1b79a29_0 - - libzlib >=1.3.1,<2.0a0 - - ncurses >=6.5,<7.0a0 - - readline >=8.3,<9.0a0 - license: blessing - purls: [] - size: 165822 - timestamp: 1768148297178 -- conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.51.2-hdb435a2_0.conda - sha256: 8194c1326f052852dd827f5277ba381228a968e841d410eb18c622cf851b11ba - md5: bc9265bd9f30f9ded263cb762a4fc847 - depends: - - libsqlite 3.51.2 hf5d6505_0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: blessing - purls: [] - size: 400812 - timestamp: 1768148302390 -- conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda - sha256: 570da295d421661af487f1595045760526964f41471021056e993e73089e9c41 - md5: b1b505328da7a6b246787df4b5a49fbc - depends: - - asttokens - - executing - - pure_eval - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/stack-data?source=hash-mapping - size: 26988 - timestamp: 1733569565672 -- conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda - sha256: e5e036728ef71606569232cc94a0480722e14ed69da3dd1e363f3d5191d83c01 - md5: 9a6117aee038999ffefe6082ff1e9a81 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libstdcxx >=14 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 2620937 - timestamp: 1769280649780 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-4.0.0-h0cb729a_0.conda - sha256: f7fc5a18f4a6cf61fa4b6697c6aa28426b07a3df2b53a96b25dda28641991532 - md5: 3dc1d4f4c9829c82c7f6660878abcd32 - depends: - - __osx >=11.0 - - libcxx >=19 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 1455052 - timestamp: 1769280806030 -- conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.0-hac47afa_0.conda - sha256: ab0ed5b654892750005c3a5aa57994ec8191b6cbee58511199d2a322026426d9 - md5: b050c2a626cda95910f1660f570a7ba4 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: BSD-2-Clause - license_family: BSD - purls: [] - size: 1809227 - timestamp: 1769280679130 -- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-hd094cb3_1.conda - sha256: c31cac57913a699745d124cdc016a63e31c5749f16f60b3202414d071fc50573 - md5: 17c38aaf14c640b85c4617ccb59c1146 - depends: - - libhwloc >=2.12.1,<2.12.2.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: APACHE - purls: [] - size: 155714 - timestamp: 1762510341121 -- conda: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda - sha256: 32e75900d6a094ffe4290a8c9f1fa15744d9da8ff617aba4acaa0f057a065c34 - md5: 043f0599dc8aa023369deacdb5ac24eb - depends: - - python >=3.10 - - python - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/tenacity?source=hash-mapping - size: 31404 - timestamp: 1770510172846 -- conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda - sha256: 6016672e0e72c4cf23c0cf7b1986283bd86a9c17e8d319212d78d8e9ae42fdfd - md5: 9d64911b31d57ca443e9f1e36b04385f - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/threadpoolctl?source=hash-mapping - size: 23869 - timestamp: 1741878358548 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac - md5: cffd3bdd58090148f4cfcd831f4b26ab - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libzlib >=1.3.1,<2.0a0 - constrains: - - xorg-libx11 >=1.8.12,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3301196 - timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 - md5: a9d86bc62f39b94c4661716624eb21b0 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: TCL - license_family: BSD - purls: [] - size: 3127137 - timestamp: 1769460817696 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda - sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 - md5: 0481bfd9814bf525bd4b3ee4b51494c4 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: TCL - license_family: BSD - purls: [] - size: 3526350 - timestamp: 1769460339384 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py310h7c4b9e2_0.conda - sha256: c27c28d19f8ba8ef6efd35dc47951c985db8a828db38444e1fad3f93f8cedb8d - md5: 30b9d5c1bc99ffbc45a63ab8d1725b93 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 663313 - timestamp: 1765458854459 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py310hfe3a0ae_0.conda - sha256: b04eb945081bef51b7fec81b8cfab1711c7f8ff1dd122ca217b99fdbbea6d0be - md5: 57010dd2f9319b8f6efba3a7b8e48e81 - depends: - - __osx >=11.0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 665175 - timestamp: 1765836991989 -- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py310h29418f3_0.conda - sha256: fa9d807ba6b2c33ab061586292709fedeb3113f5462829d1357ac18193c8fd44 - md5: 5f19583828bd8325b001fe471776ead8 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/tornado?source=hash-mapping - size: 665930 - timestamp: 1765836632159 -- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda - sha256: 11e2c85468ae9902d24a27137b6b39b4a78099806e551d390e394a8c34b48e40 - md5: 9efbfdc37242619130ea42b1cc4ed861 - depends: - - colorama - - python >=3.9 - license: MPL-2.0 or MIT - purls: - - pkg:pypi/tqdm?source=hash-mapping - size: 89498 - timestamp: 1735661472632 -- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - sha256: f39a5620c6e8e9e98357507262a7869de2ae8cc07da8b7f84e517c9fd6c2b959 - md5: 019a7385be9af33791c989871317e1ed - depends: - - python >=3.9 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/traitlets?source=hash-mapping - size: 110051 - timestamp: 1733367480074 -- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 - md5: 0caa1af407ecff61170c9437a808404d - depends: - - python >=3.10 - - python - license: PSF-2.0 - license_family: PSF - purls: - - pkg:pypi/typing-extensions?source=hash-mapping - size: 51692 - timestamp: 1756220668932 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c - md5: ad659d0a2b3e47e38d829aa8cad2d610 - license: LicenseRef-Public-Domain - purls: [] - size: 119135 - timestamp: 1767016325805 -- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 - md5: 71b24316859acd00bdb8b38f5e2ce328 - constrains: - - vc14_runtime >=14.29.30037 - - vs2015_runtime >=14.29.30037 - license: LicenseRef-MicrosoftWindowsSDK10 - purls: [] - size: 694692 - timestamp: 1756385147981 -- conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py310h7c4b9e2_0.conda - sha256: 44ecba51c98c3fb2ce3d00295d423d3bb254cde1790eff9818ed328aa608ab28 - md5: 234e9858dd691d3f597147e22cbf16cf - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/unicodedata2?source=hash-mapping - size: 410408 - timestamp: 1770909105501 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py310h72544b6_0.conda - sha256: 48e56c2068cce4b2d09cceca65ca1c877ebf550e3ad67af3ed30db162bc89e0b - md5: a35cf23aa03fb8d3a95158253918ed00 - depends: - - __osx >=11.0 - - python >=3.10,<3.11.0a0 - - python >=3.10,<3.11.0a0 *_cpython - - python_abi 3.10.* *_cp310 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/unicodedata2?source=hash-mapping - size: 416056 - timestamp: 1770910020955 -- conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py310h29418f3_0.conda - sha256: 0ce3386d49564a30da221cdee59edf113ef27e1ea784dd33f5f39411b7faeccb - md5: 8c34b3ebcfd8d6e4989ae1a2f2a63d03 - depends: - - python >=3.10,<3.11.0a0 - - python_abi 3.10.* *_cp310 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/unicodedata2?source=hash-mapping - size: 406410 - timestamp: 1770909213469 -- conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda - sha256: 2aad2aeff7c69a2d7eecd7b662eef756b27d6a6b96f3e2c2a7071340ce14543e - md5: d71d3a66528853c0a1ac2c02d79a0284 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 48270 - timestamp: 1715010035325 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda - sha256: fa0bcbfb20a508ca9bf482236fe799581cbd0eab016e47a865e9fa44dbe3c512 - md5: e8ff9e11babbc8cd77af5a4258dc2802 - depends: - - __osx >=11.0 - - libcxx >=16 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 40625 - timestamp: 1715010029254 -- conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - sha256: ed0eed8ed0343d29cdbfaeb1bfd141f090af696547d69f91c18f46350299f00d - md5: 28b4cf9065681f43cc567410edf8243d - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 49181 - timestamp: 1715010467661 -- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda - sha256: af641ca7ab0c64525a96fd9ad3081b0f5bcf5d1cbb091afb3f6ed5a9eee6111a - md5: 9272daa869e03efe68833e3dc7a02130 - depends: - - backports.zstd >=1.0.0 - - brotli-python >=1.2.0 - - h2 >=4,<5 - - pysocks >=1.5.6,<2.0,!=1.5.7 - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/urllib3?source=hash-mapping - size: 103172 - timestamp: 1767817860341 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda - sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a - md5: 1e610f2416b6acdd231c5f573d754a0f - depends: - - vc14_runtime >=14.44.35208 - track_features: - - vc14 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 19356 - timestamp: 1767320221521 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda - sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 - md5: 37eb311485d2d8b2c419449582046a42 - depends: - - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_34 - constrains: - - vs2015_runtime 14.44.35208.* *_34 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 683233 - timestamp: 1767320219644 -- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda - sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 - md5: 242d9f25d2ae60c76b38a5e42858e51d - depends: - - ucrt >=10.0.20348.0 - constrains: - - vs2015_runtime 14.44.35208.* *_34 - license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime - license_family: Proprietary - purls: [] - size: 115235 - timestamp: 1767320173250 -- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_34.conda - sha256: 63ff4ec6e5833f768d402f5e95e03497ce211ded5b6f492e660e2bfc726ad24d - md5: f276d1de4553e8fca1dfb6988551ebb4 - depends: - - vc14_runtime >=14.44.35208 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 19347 - timestamp: 1767320221943 -- conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda - sha256: ba673427dcd480cfa9bbc262fd04a9b1ad2ed59a159bd8f7e750d4c52282f34c - md5: 0f2ca7906bf166247d1d760c3422cb8a - depends: - - __glibc >=2.17,<3.0.a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 - - libstdcxx >=13 - license: MIT - license_family: MIT - purls: [] - size: 330474 - timestamp: 1751817998141 -- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda - sha256: e298b508b2473c4227206800dfb14c39e4b14fd79d4636132e9e1e4244cdf4aa - md5: c3197f8c0d5b955c904616b716aca093 - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/wcwidth?source=compressed-mapping - size: 71550 - timestamp: 1770634638503 -- conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda - sha256: d6cf2f0ebd5e09120c28ecba450556ce553752652d91795442f0e70f837126ae - md5: bdbd7385b4a67025ac2dba4ef8cb6a8f - depends: - - packaging >=24.0 - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/wheel?source=hash-mapping - size: 31858 - timestamp: 1769139207397 -- conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda - sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f - md5: 46e441ba871f524e2b067929da3051c2 - depends: - - __win - - python >=3.9 - license: LicenseRef-Public-Domain - purls: - - pkg:pypi/win-inet-pton?source=hash-mapping - size: 9555 - timestamp: 1733130678956 -- conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - sha256: 76c7405bcf2af639971150f342550484efac18219c0203c5ee2e38b8956fe2a0 - md5: e7f6ed84d4623d52ee581325c1587a6b - depends: - - libgcc-ng >=10.3.0 - - libstdcxx-ng >=10.3.0 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 3357188 - timestamp: 1646609687141 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - sha256: 2fed6987dba7dee07bd9adc1a6f8e6c699efb851431bcb6ebad7de196e87841d - md5: b1f7f2780feffe310b068c021e8ff9b2 - depends: - - libcxx >=12.0.1 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 1832744 - timestamp: 1646609481185 -- conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - sha256: 02b9874049112f2b7335c9a3e880ac05d99a08d9a98160c5a98898b2b3ac42b2 - md5: ca7129a334198f08347fb19ac98a2de9 - depends: - - vc >=14.1,<15 - - vs2015_runtime >=14.16.27033 - license: GPL-2.0-or-later - license_family: GPL - purls: [] - size: 5517425 - timestamp: 1646611941216 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda - sha256: ad8cab7e07e2af268449c2ce855cbb51f43f4664936eff679b1f3862e6e4b01d - md5: fdc27cb255a7a2cc73b7919a968b48f0 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libxcb >=1.17.0,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 20772 - timestamp: 1750436796633 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda - sha256: c2be9cae786fdb2df7c2387d2db31b285cf90ab3bfabda8fa75a596c3d20fc67 - md5: 4d1fc190b99912ed557a8236e958c559 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libxcb >=1.13 - - libxcb >=1.17.0,<2.0a0 - - xcb-util-image >=0.4.0,<0.5.0a0 - - xcb-util-renderutil >=0.3.10,<0.4.0a0 - license: MIT - license_family: MIT - purls: [] - size: 20829 - timestamp: 1763366954390 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda - sha256: 94b12ff8b30260d9de4fd7a28cca12e028e572cbc504fd42aa2646ec4a5bded7 - md5: a0901183f08b6c7107aab109733a3c91 - depends: - - libgcc-ng >=12 - - libxcb >=1.16,<2.0.0a0 - - xcb-util >=0.4.1,<0.5.0a0 - license: MIT - license_family: MIT - purls: [] - size: 24551 - timestamp: 1718880534789 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda - sha256: 546e3ee01e95a4c884b6401284bb22da449a2f4daf508d038fdfa0712fe4cc69 - md5: ad748ccca349aec3e91743e08b5e2b50 - depends: - - libgcc-ng >=12 - - libxcb >=1.16,<2.0.0a0 - license: MIT - license_family: MIT - purls: [] - size: 14314 - timestamp: 1718846569232 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda - sha256: 2d401dadc43855971ce008344a4b5bd804aca9487d8ebd83328592217daca3df - md5: 0e0cbe0564d03a99afd5fd7b362feecd - depends: - - libgcc-ng >=12 - - libxcb >=1.16,<2.0.0a0 - license: MIT - license_family: MIT - purls: [] - size: 16978 - timestamp: 1718848865819 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda - sha256: 31d44f297ad87a1e6510895740325a635dd204556aa7e079194a0034cdd7e66a - md5: 608e0ef8256b81d04456e8d211eee3e8 - depends: - - libgcc-ng >=12 - - libxcb >=1.16,<2.0.0a0 - license: MIT - license_family: MIT - purls: [] - size: 51689 - timestamp: 1718844051451 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-h988505b_2.conda - sha256: 339ab0ff05170a295e59133cd0fa9a9c4ba32b6941c8a2a73484cc13f81e248a - md5: 9dda9667feba914e0e80b95b82f7402b - depends: - - __glibc >=2.17,<3.0.a0 - - icu >=75.1,<76.0a0 - - libgcc >=13 - - libnsl >=2.0.1,<2.1.0a0 - - libstdcxx >=13 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 1648243 - timestamp: 1727733890754 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-h92fc2f4_2.conda - sha256: 863a7c2a991a4399d362d42c285ebc20748a4ea417647ebd3a171e2220c7457d - md5: 50b7325437ef0901fe25dc5c9e743b88 - depends: - - __osx >=11.0 - - icu >=75.1,<76.0a0 - - libcxx >=17 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 1277884 - timestamp: 1727733870250 -- conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-he0c23c2_2.conda - sha256: 759ae22a0a221dc1c0ba39684b0dcf696aab4132478e17e56a0366ded519e54e - md5: 82b6eac3c198271e98b48d52d79726d8 - depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: Apache - purls: [] - size: 3574017 - timestamp: 1727734520239 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda - sha256: aa03b49f402959751ccc6e21932d69db96a65a67343765672f7862332aa32834 - md5: 71ae752a748962161b4740eaff510258 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 396975 - timestamp: 1759543819846 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda - sha256: c12396aabb21244c212e488bbdc4abcdef0b7404b15761d9329f5a4a39113c4b - md5: fb901ff28063514abb6046c9ec2c4a45 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - license: MIT - license_family: MIT - purls: [] - size: 58628 - timestamp: 1734227592886 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda - sha256: 277841c43a39f738927145930ff963c5ce4c4dacf66637a3d95d802a64173250 - md5: 1c74ff8c35dcadf952a16f752ca5aa49 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libuuid >=2.38.1,<3.0a0 - - xorg-libice >=1.1.2,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 27590 - timestamp: 1741896361728 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda - sha256: 516d4060139dbb4de49a4dcdc6317a9353fb39ebd47789c14e6fe52de0deee42 - md5: 861fb6ccbc677bb9a9fb2468430b9c6a - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libxcb >=1.17.0,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 839652 - timestamp: 1770819209719 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda - sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b - md5: b2895afaf55bf96a8c8282a2e47a5de0 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 15321 - timestamp: 1762976464266 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda - sha256: adae11db0f66f86156569415ed79cda75b2dbf4bea48d1577831db701438164f - md5: 78b548eed8227a689f93775d5d23ae09 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 14105 - timestamp: 1762976976084 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda - sha256: 156a583fa43609507146de1c4926172286d92458c307bb90871579601f6bc568 - md5: 8436cab9a76015dfe7208d3c9f97c156 - depends: - - libgcc >=14 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 109246 - timestamp: 1762977105140 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda - sha256: 048c103000af9541c919deef03ae7c5e9c570ffb4024b42ecb58dbde402e373a - md5: f2ba4192d38b6cef2bb2c25029071d90 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - - xorg-libxfixes >=6.0.2,<7.0a0 - license: MIT - license_family: MIT - purls: [] - size: 14415 - timestamp: 1770044404696 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda - sha256: 832f538ade441b1eee863c8c91af9e69b356cd3e9e1350fff4fe36cc573fc91a - md5: 2ccd714aa2242315acaf0a67faea780b - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - xorg-libx11 >=1.8.10,<2.0a0 - - xorg-libxfixes >=6.0.1,<7.0a0 - - xorg-libxrender >=0.9.11,<0.10.0a0 - license: MIT - license_family: MIT - purls: [] - size: 32533 - timestamp: 1730908305254 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda - sha256: 43b9772fd6582bf401846642c4635c47a9b0e36ca08116b3ec3df36ab96e0ec0 - md5: b5fcc7172d22516e1f965490e65e33a4 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - xorg-libx11 >=1.8.10,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxfixes >=6.0.1,<7.0a0 - license: MIT - license_family: MIT - purls: [] - size: 13217 - timestamp: 1727891438799 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda - sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 - md5: 1dafce8548e38671bea82e3f5c6ce22f - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - license: MIT - license_family: MIT - purls: [] - size: 20591 - timestamp: 1762976546182 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda - sha256: f7fa0de519d8da589995a1fe78ef74556bb8bc4172079ae3a8d20c3c81354906 - md5: 9d1299ace1924aa8f4e0bc8e71dd0cf7 - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 19156 - timestamp: 1762977035194 -- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda - sha256: 366b8ae202c3b48958f0b8784bbfdc37243d3ee1b1cd4b8e76c10abe41fa258b - md5: a7c03e38aa9c0e84d41881b9236eacfb - depends: - - libgcc >=14 - - libwinpthread >=12.0.0.r4.gg4f2fc60ca - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 70691 - timestamp: 1762977015220 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda - sha256: 79c60fc6acfd3d713d6340d3b4e296836a0f8c51602327b32794625826bd052f - md5: 34e54f03dfea3e7a2dcf1453a85f1085 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 50326 - timestamp: 1769445253162 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda - sha256: 83c4c99d60b8784a611351220452a0a85b080668188dce5dfa394b723d7b64f4 - md5: ba231da7fccf9ea1e768caf5c7099b84 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 20071 - timestamp: 1759282564045 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda - sha256: 1a724b47d98d7880f26da40e45f01728e7638e6ec69f35a3e11f92acd05f9e7a - md5: 17dcc85db3c7886650b8908b183d6876 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - xorg-libx11 >=1.8.10,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxfixes >=6.0.1,<7.0a0 - license: MIT - license_family: MIT - purls: [] - size: 47179 - timestamp: 1727799254088 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda - sha256: 80ed047a5cb30632c3dc5804c7716131d767089f65877813d4ae855ee5c9d343 - md5: e192019153591938acf7322b6459d36e - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxrender >=0.9.12,<0.10.0a0 - license: MIT - license_family: MIT - purls: [] - size: 30456 - timestamp: 1769445263457 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda - sha256: 044c7b3153c224c6cedd4484dd91b389d2d7fd9c776ad0f4a34f099b3389f4a1 - md5: 96d57aba173e878a2089d5638016dc5e - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - xorg-libx11 >=1.8.10,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 33005 - timestamp: 1734229037766 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda - sha256: 752fdaac5d58ed863bbf685bb6f98092fe1a488ea8ebb7ed7b606ccfce08637a - md5: 7bbe9a0cc0df0ac5f5a8ad6d6a11af2f - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - xorg-libx11 >=1.8.10,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - - xorg-libxi >=1.7.10,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 32808 - timestamp: 1727964811275 -- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda - sha256: 64db17baaf36fa03ed8fae105e2e671a7383e22df4077486646f7dbf12842c9f - md5: 665d152b9c6e78da404086088077c844 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - xorg-libx11 >=1.8.12,<2.0a0 - - xorg-libxext >=1.3.6,<2.0a0 - license: MIT - license_family: MIT - purls: [] - size: 18701 - timestamp: 1769434732453 -- conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2025.11.0-pyhd8ed1ab_0.conda - sha256: b194a1fbc38f29c563b102ece9d006f7a165bf9074cdfe50563d3bce8cae9f84 - md5: 16933322051fa260285f1a44aae91dd6 - depends: - - python >=3.8 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/xyzservices?source=hash-mapping - size: 51128 - timestamp: 1763813786075 -- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad - md5: a77f85f77be52ff59391544bfe73390a - depends: - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - license: MIT - license_family: MIT - purls: [] - size: 85189 - timestamp: 1753484064210 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h925e9cb_3.conda - sha256: b03433b13d89f5567e828ea9f1a7d5c5d697bf374c28a4168d71e9464f5dafac - md5: 78a0fe9e9c50d2c381e8ee47e3ea437d - depends: - - __osx >=11.0 - license: MIT - license_family: MIT - purls: [] - size: 83386 - timestamp: 1753484079473 -- conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - sha256: 80ee68c1e7683a35295232ea79bcc87279d31ffeda04a1665efdb43cbd50a309 - md5: 433699cba6602098ae8957a323da2664 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - license: MIT - license_family: MIT - purls: [] - size: 63944 - timestamp: 1753484092156 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda - sha256: 47cfe31255b91b4a6fa0e9dbaf26baa60ac97e033402dbc8b90ba5fee5ffe184 - md5: 8035e5b54c08429354d5d64027041cad - depends: - - libstdcxx >=14 - - libgcc >=14 - - __glibc >=2.17,<3.0.a0 - - libgcc >=14 - - libsodium >=1.0.20,<1.0.21.0a0 - - krb5 >=1.21.3,<1.22.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 310648 - timestamp: 1757370847287 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-hebf3989_1.conda - sha256: caf6df12d793600faec21b7e6025e2e8fb8de26672cce499f9471b99b6776eb1 - md5: 19cff1c627ff58429701113bf35300c8 - depends: - - libcxx >=16 - - libsodium >=1.0.18,<1.0.19.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 288572 - timestamp: 1709135728486 -- conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-h5bddc39_9.conda - sha256: 690cf749692c8ea556646d1a47b5824ad41b2f6dfd949e4cdb6c44a352fcb1aa - md5: a6c8f8ee856f7c3c1576e14b86cd8038 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libsodium >=1.0.20,<1.0.21.0a0 - - krb5 >=1.21.3,<1.22.0a0 - license: MPL-2.0 - license_family: MOZILLA - purls: [] - size: 265212 - timestamp: 1757370864284 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - sha256: 5d7c0e5f0005f74112a34a7425179f4eb6e73c92f5d109e6af4ddeca407c92ab - md5: c9f075ab2f33b3bbee9e62d4ad0a6cd8 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc >=13 - - libzlib 1.3.1 hb9d3cd8_2 - license: Zlib - license_family: Other - purls: [] - size: 92286 - timestamp: 1727963153079 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda - sha256: 58f8860756680a4831c1bf4f294e2354d187f2e999791d53b1941834c4b37430 - md5: e3170d898ca6cb48f1bb567afb92f775 - depends: - - __osx >=11.0 - - libzlib 1.3.1 h8359307_2 - license: Zlib - license_family: Other - purls: [] - size: 77606 - timestamp: 1727963209370 -- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_2.conda - sha256: 8c688797ba23b9ab50cef404eca4d004a948941b6ee533ead0ff3bf52012528c - md5: be60c4e8efa55fddc17b4131aa47acbd - depends: - - libzlib 1.3.1 h2466b09_2 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Zlib - license_family: Other - purls: [] - size: 107439 - timestamp: 1727963788936 -- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 - md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 - depends: - - __glibc >=2.17,<3.0.a0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 601375 - timestamp: 1764777111296 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 - md5: ab136e4c34e97f34fb621d2592a393d8 - depends: - - __osx >=11.0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 433413 - timestamp: 1764777166076 -- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda - sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 - md5: 053b84beec00b71ea8ff7a4f84b55207 - depends: - - vc >=14.3,<15 - - vc14_runtime >=14.44.35208 - - ucrt >=10.0.20348.0 - - libzlib >=1.3.1,<2.0a0 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 388453 - timestamp: 1764777142545 diff --git a/pixi.toml b/pixi.toml deleted file mode 100644 index 0cac156f..00000000 --- a/pixi.toml +++ /dev/null @@ -1,34 +0,0 @@ -[workspace] -authors = ["Chenhao Ding "] -channels = ["conda-forge", "main", "r", "msys2", "gurobi"] -name = "fleetpy" -platforms = ["osx-arm64", "linux-64", "win-64"] -version = "0.1.0" - -[tasks] -run_examples = "python run_examples.py" - -[dependencies] -pip = "25.0.*" -numpy = "2.2.*" -plotly = "5.24.*" -python = "3.10.*" -scipy = "1.15.*" -fiona = "==1.10.1" -geopandas = "==1.0.1" -pandas = "==2.2.3" -pyogrio = "==0.10.0" -pyproj = "==3.7.0" -pyyaml = "==6.0.2" -rtree = "==1.3.0" -shapely = "==2.0.6" -tqdm = "==4.67.1" -matplotlib = "*" -requests = "*" -ipykernel = "*" -gurobi = ">=13.0.1,<14" - -[pypi-dependencies] -cython = "==3.0.11" -dill = "==0.3.9" -nbformat = ">=4.2.0" From ccf2d675844109e107050136b9d1e8cd1c9cac63 Mon Sep 17 00:00:00 2001 From: Chenhao Ding Date: Mon, 9 Mar 2026 17:52:06 +0100 Subject: [PATCH 31/31] Add strategy doc comments to PTBroker modules and update changelog - Add header comments to PTBrokerBasic, PTBroker, PTBrokerEI, PTBrokerPAYG describing each strategy's intermodal request handling logic and noting that code has only been tested with ImmediateDecisionsSimulation + PoolingIRSOnly - Remove commented-out debug code in PoolingIRSOnly - Update changelog [1.1.0]: replace TPCS references with accurate descriptions of the three broker strategies (PTBroker, PTBrokerEI, PTBrokerPAYG), add missing entries, and correct global variable names --- changelog.md | 16 ++++++++++++---- src/broker/PTBroker.py | 16 ++++++++++++++++ src/broker/PTBrokerBasic.py | 19 +++++++++++++++++++ src/broker/PTBrokerEI.py | 16 ++++++++++++++++ src/broker/PTBrokerPAYG.py | 19 ++++++++++++++----- src/fleetctrl/PoolingIRSOnly.py | 11 ----------- 6 files changed, 77 insertions(+), 20 deletions(-) diff --git a/changelog.md b/changelog.md index b3a0093d..9dc3f26f 100644 --- a/changelog.md +++ b/changelog.md @@ -8,7 +8,7 @@ Key update: 1. Refactored routing file structure: road-related routing modules are moved to the `road` subdirectory, and PT-related routing modules are moved to the `pt` subdirectory. 2. Introduced a C++ routing module based on the RAPTOR algorithm for querying the fastest PT travel plans between two stations. 3. Introduced the PTControl module to simulate PT operator behavior, such as recording offer information and dynamically updating GTFS files. -4. Introduced the PTBroker module based on the TPCS strategy to simulate MaaS platform planning for intermodal requests. +4. Introduced three PTBroker strategy variants to simulate different levels of MaaS–DRT coordination for intermodal requests: Plan-As-You-Go (PTBrokerPAYG), Estimation-based Integration (PTBrokerEI), and Collaborative Coordination (PTBroker). 5. Introduced subrequest ID coding rules for intermodal scenarios, using unique integers to classify legs and `{parent_rid}_{subtrip_id}` to define new subrequest IDs. ### Added @@ -26,15 +26,23 @@ Key update: - example_100_intermodal.csv: Intermodal demand based on example_100.csv, containing 25 monomodal, 25 first-mile, 25 last-mile, and 25 first-last-mile requests +- example_100_intermodal_lmwt30.csv: Variant of the intermodal demand file with a 30-second last-mile wait time constraint + - example_gtfs: Public transport design based on example_network -- PTBrokerTPCS: PTBroker module based on TPCS strategy for intermodal planning. Use `G_BROKER_TPCS_USE_DEFAULT` to toggle between full three-stage or first-stage only +- PTBrokerBasic: Base class providing shared infrastructure for intermodal request handling across all PTBroker variants (FM, LM, FLM sub-request creation, offer assembly, booking confirmation) + +- PTBroker (Collaborative Coordination): Simulates a future scenario with tight MaaS–DRT integration. DRT provides a predicted FM dropoff time; PT feeds back the user's expected station waiting time, which MaaS uses to dynamically adjust the DRT dropoff deadline, giving DRT more pooling flexibility while guaranteeing PT connection. LM DRT wait time can also be constrained to minimize destination wait. + +- PTBrokerEI (Estimation-based Integration): Simulates current MaaS platforms with limited real-time DRT communication. FM dropoff time is estimated using `broker_maas_detour_time_factor` rather than obtained from an actual DRT offer. A conservative factor ensures PT is caught but increases travel time; an optimistic factor risks missing PT. + +- PTBrokerPAYG (Plan-As-You-Go): Simulates the absence of a MaaS platform. Each leg is planned only after the previous one completes (FM DRT → PT → LM DRT). Trips may be interrupted if a subsequent leg is unavailable. - intermodal_evaluation: Evaluation methods designed for intermodal scenarios - example_study & module_tests: Added intermodal scenario example experiments -- globals: Added subrequest ID coding rules for intermodal scenarios and global variables for PT, Intermodal, and TPCS +- globals: Added `RQ_MODAL_STATE`, `RQ_SUB_TRIP_ID`, and `PAYG_TRIP_STATE` enums for intermodal sub-request classification; added global variable names for PT (`G_PT_*`), intermodal offers (`G_IM_*`), and broker configuration (`G_BROKER_*`, including `G_BROKER_MAAS_DETOUR_TIME_FACTOR`, `G_BROKER_TRANSFER_SEARCH_METHOD`, `G_BROKER_ALWAYS_QUERY_PT`, `G_IM_LM_WAIT_TIME`) - init_modules: Added initialization code for PTControl and PTBroker modules @@ -59,7 +67,7 @@ Key update: - RollingHorizon: `return_immediate_reservation_offer` method added `excluded_vid` input -- PoolingIRSOnly: `user_request` method now adds the vehicle used for the FM leg to `excluded_vid` when processing FLM requests, ignoring this vehicle for the LM leg of the same parent request +- PoolingIRSOnly: `user_request` method added optional `max_wait_time` parameter (used for LM leg of intermodal requests); tracks `flm_excluded_vid` to exclude the FM vehicle from LM assignment in FLM requests - Vehicles: `assign_vehicle_plan` method now uses `rid_struct` to obtain request information diff --git a/src/broker/PTBroker.py b/src/broker/PTBroker.py index b46ffa1f..fc4244d7 100644 --- a/src/broker/PTBroker.py +++ b/src/broker/PTBroker.py @@ -2,6 +2,22 @@ # - Adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. # - Support multiple AMoD operators for firstlastmile requests. +# -------------------------------------------------------------------------------------------------------------------- # +# PTBroker: Collaborative Coordination Strategy +# +# Simulates a future scenario with autonomous DRT and tight MaaS–DRT integration: +# - MaaS queries DRT for FM and immediately receives a predicted dropoff time (actual offer, not estimated). +# - MaaS books PT and LM DRT based on that predicted dropoff time. +# - PT returns the user's expected waiting time at the boarding station; MaaS feeds this back to DRT. +# - DRT dynamically adjusts the user's latest dropoff deadline, giving DRT more flexibility for +# ride-pooling while still ensuring the user catches the PT vehicle. +# - MaaS can also constrain LM DRT waiting time, minimizing wait at the destination station. +# Result: higher service rate and shorter travel times through real-time coordination between MaaS and DRT. +# +# NOTE: This code has only been tested and applied in the ImmediateDecisionsSimulation environment +# combined with the PoolingIRSOnly fleet controller. +# -------------------------------------------------------------------------------------------------------------------- # + # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports # ----------------------------- diff --git a/src/broker/PTBrokerBasic.py b/src/broker/PTBrokerBasic.py index e308e4e6..9bb56fc7 100644 --- a/src/broker/PTBrokerBasic.py +++ b/src/broker/PTBrokerBasic.py @@ -2,6 +2,25 @@ # - Adjust PT waiting time based on dynamic GTFS data (e.g., delays), and then adjust FM and LM offers accordingly. # - Support multiple AMoD operators for firstlastmile requests. +# -------------------------------------------------------------------------------------------------------------------- # +# PTBrokerBasic: Base Intermodal Broker +# +# Base class for all PTBroker variants. Provides the shared infrastructure for intermodal request handling: +# - MONOMODAL / PT: Forward the request directly to the AMoD operator or PT operator. +# - FIRSTMILE (FM): Select a PT boarding transfer stop, create FM_AMOD sub-request +# (origin → PT boarding stop), and create PT sub-request (boarding stop → destination). +# - LASTMILE (LM): Select a PT alighting transfer stop, create PT sub-request +# (origin → PT alighting stop), and create LM_AMOD sub-request (PT alighting stop → destination). +# - FIRSTLASTMILE (FLM): Select boarding and alighting transfer stops, create FLM_AMOD_0 sub-request +# (origin → PT boarding stop), PT sub-request (boarding → alighting), and FLM_AMOD_1 sub-request +# (PT alighting stop → destination). +# Subclasses (PTBroker, PTBrokerEI, PTBrokerPAYG) override specific methods to implement different +# coordination strategies between MaaS and DRT. +# +# NOTE: This code has only been tested and applied in the ImmediateDecisionsSimulation environment +# combined with the PoolingIRSOnly fleet controller. +# -------------------------------------------------------------------------------------------------------------------- # + # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports # ----------------------------- diff --git a/src/broker/PTBrokerEI.py b/src/broker/PTBrokerEI.py index cee18605..54cf1b66 100644 --- a/src/broker/PTBrokerEI.py +++ b/src/broker/PTBrokerEI.py @@ -1,3 +1,19 @@ +# -------------------------------------------------------------------------------------------------------------------- # +# PTBrokerEI: Estimation-based Integration Strategy +# +# Simulates current MaaS platforms with limited real-time DRT communication: +# - MaaS cannot obtain an actual FM DRT offer in time, so it *estimates* the FM DRT dropoff time +# using a detour time factor (`broker_maas_dtf`). +# - PT and LM DRT are booked based on this estimated dropoff time. +# - `broker_maas_dtf` controls estimation conservatism: +# - A large (conservative) value ensures the user catches PT but increases overall travel time. +# - A small (optimistic) value reduces travel time but risks missing PT due to pooling delays. +# - In experiments, only `broker_maas_dtf=100` was used (50 was not run). +# +# NOTE: This code has only been tested and applied in the ImmediateDecisionsSimulation environment +# combined with the PoolingIRSOnly fleet controller. +# -------------------------------------------------------------------------------------------------------------------- # + # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports # ----------------------------- diff --git a/src/broker/PTBrokerPAYG.py b/src/broker/PTBrokerPAYG.py index 44969b69..92a2dabc 100644 --- a/src/broker/PTBrokerPAYG.py +++ b/src/broker/PTBrokerPAYG.py @@ -1,10 +1,19 @@ # -------------------------------------------------------------------------------------------------------------------- # -# PTBrokerPAYG: Plan-As-You-Go Broker Strategy +# PTBrokerPAYG: Plan-As-You-Go (PAYG) Broker Strategy # -# This broker simulates traveler behavior without a MaaS platform - travelers plan their trip step by step: -# - For FM/FLM: After FM AMoD alighting, query PT in real-time -# - For LM/FLM: After PT alighting, request LM AMoD in real-time -# - If any step fails (no offer available), mark the trip as interrupted +# This broker simulates traveler behavior without a MaaS platform — travelers plan their trip step by step, +# querying the next leg only after completing the current one: +# - FIRSTMILE (FM): At request time, create only FM_AMOD (origin → PT boarding stop). +# After AMoD alighting, query PT in real-time and create the PT sub-request. +# - LASTMILE (LM): At request time, query PT (origin → PT alighting stop). +# After PT alighting, request LM_AMOD in real-time (PT alighting stop → destination). +# - FIRSTLASTMILE (FLM): At request time, create only FLM_AMOD_0 (origin → PT boarding stop). +# After AMoD alighting, query PT in real-time. After PT alighting, request FLM_AMOD_1 in real-time. +# If any step fails to find an available service, the trip is marked as interrupted. +# Unlike PTBrokerBasic (TPCS), no pre-planned combined offer is presented to the user upfront. +# +# NOTE: This code has only been tested and applied in the ImmediateDecisionsSimulation environment +# combined with the PoolingIRSOnly fleet controller. # -------------------------------------------------------------------------------------------------------------------- # # standard distribution imports diff --git a/src/fleetctrl/PoolingIRSOnly.py b/src/fleetctrl/PoolingIRSOnly.py index bbc383bb..b7afbb73 100644 --- a/src/fleetctrl/PoolingIRSOnly.py +++ b/src/fleetctrl/PoolingIRSOnly.py @@ -129,17 +129,6 @@ def user_request(self, rq, sim_time, max_wait_time=None): if t_pu_earliest - sim_time > self.opt_horizon: self.reservation_module.add_reservation_request(prq, sim_time) offer = self.reservation_module.return_immediate_reservation_offer(prq.get_rid_struct(), sim_time, excluded_vid=excluded_vid) - - # # record excluded vids for flm request - # if rq_modal_state == RQ_MODAL_STATE.FIRSTLASTMILE: - # assigned_vid: int = self.reservation_module.rid_to_assigned_vid.get(rid_struct) - # if assigned_vid is not None: - # if parent_rid in self.flm_excluded_vid: - # self.flm_excluded_vid[parent_rid].append(assigned_vid) - # else: - # self.flm_excluded_vid[parent_rid] = [assigned_vid] - # print(f"excluded vid {assigned_vid} for request {rid_struct}") - LOG.debug(f"reservation offer for rid {rid_struct} : {offer}") else: list_tuples = insertion_with_heuristics(sim_time, prq, self, force_feasible_assignment=True, excluded_vid=excluded_vid)