From 0a91bdc5f2e3574a66d08aa8ca5f89efdb349083 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:54:00 +0200 Subject: [PATCH 001/103] Convert flask to fastapi --- cea/interfaces/dashboard/api/__init__.py | 42 +- cea/interfaces/dashboard/api/contents.py | 68 +- cea/interfaces/dashboard/api/dashboard.py | 301 +- cea/interfaces/dashboard/api/databases.py | 96 +- cea/interfaces/dashboard/api/glossary.py | 31 +- cea/interfaces/dashboard/api/inputs.py | 498 +- cea/interfaces/dashboard/api/project.py | 625 +-- cea/interfaces/dashboard/api/tools.py | 166 +- cea/interfaces/dashboard/api/utils.py | 10 +- cea/interfaces/dashboard/dashboard.py | 95 +- cea/interfaces/dashboard/frontend/.gitignore | 1 - cea/interfaces/dashboard/frontend/__init__.py | 26 - cea/interfaces/dashboard/plots/routes.py | 91 +- cea/interfaces/dashboard/server/__init__.py | 54 +- cea/interfaces/dashboard/server/jobs.py | 222 +- cea/interfaces/dashboard/server/socketio.py | 4 + cea/interfaces/dashboard/server/streams.py | 46 +- cea/worker.py | 2 +- conda-lock.yml | 4565 +++++++++-------- environment.yml | 10 +- 20 files changed, 3703 insertions(+), 3250 deletions(-) delete mode 100644 cea/interfaces/dashboard/frontend/.gitignore delete mode 100644 cea/interfaces/dashboard/frontend/__init__.py create mode 100644 cea/interfaces/dashboard/server/socketio.py diff --git a/cea/interfaces/dashboard/api/__init__.py b/cea/interfaces/dashboard/api/__init__.py index 4ee036ee64..3a1c2915ec 100644 --- a/cea/interfaces/dashboard/api/__init__.py +++ b/cea/interfaces/dashboard/api/__init__.py @@ -1,29 +1,19 @@ -from flask import Blueprint -from flask_restx import Api -from .tools import api as tools -from .project import api as project -from .inputs import api as inputs -from .dashboard import api as dashboard -from .glossary import api as glossary -from .databases import api as databases -from .contents import api as contents +from fastapi import APIRouter -blueprint = Blueprint('api', __name__, url_prefix='/api') -api = Api(blueprint) +import cea.interfaces.dashboard.api.inputs as inputs +import cea.interfaces.dashboard.api.contents as contents +import cea.interfaces.dashboard.api.dashboard as dashboard +import cea.interfaces.dashboard.api.databases as databases +import cea.interfaces.dashboard.api.glossary as glossary +import cea.interfaces.dashboard.api.project as project +import cea.interfaces.dashboard.api.tools as tools -api.add_namespace(tools, path='/tools') -api.add_namespace(project, path='/project') -api.add_namespace(inputs, path='/inputs') -api.add_namespace(inputs, path='/inputs') -api.add_namespace(dashboard, path='/dashboards') -api.add_namespace(glossary, path='/glossary') -api.add_namespace(databases, path='/databases') -api.add_namespace(contents, path='/contents') +router = APIRouter() - -@api.errorhandler -def default_error_handler(error): - """Default error handler""" - import traceback - trace = traceback.format_exc() - return {'message': str(error), 'trace': trace}, 500 +router.include_router(inputs.router, prefix="/inputs") +router.include_router(contents.router, prefix="/contents") +router.include_router(dashboard.router, prefix="/dashboard") +router.include_router(databases.router, prefix="/databases") +router.include_router(glossary.router, prefix="/glossary") +router.include_router(project.router, prefix="/project") +router.include_router(tools.router, prefix="/tools") diff --git a/cea/interfaces/dashboard/api/contents.py b/cea/interfaces/dashboard/api/contents.py index 4cf7737609..b073696b57 100644 --- a/cea/interfaces/dashboard/api/contents.py +++ b/cea/interfaces/dashboard/api/contents.py @@ -1,13 +1,13 @@ import os.path from dataclasses import dataclass, asdict from enum import Enum -from pathlib import Path from typing import Optional, List -from flask import current_app -from flask_restx import Namespace, Resource +from fastapi import APIRouter, HTTPException, status -api = Namespace('Contents', description='Local path file contents') +from cea.interfaces.dashboard.dashboard import CEAConfig + +router = APIRouter() class ContentType(Enum): @@ -15,12 +15,6 @@ class ContentType(Enum): file = 'file' -contents_parser = api.parser() -contents_parser.add_argument('type', type=ContentType, required=True, location='args') -contents_parser.add_argument('show_hidden', type=bool, default=False, location='args') -contents_parser.add_argument('root', type=str, default=None, location='args') - - class ContentPathNotFound(Exception): pass @@ -68,7 +62,7 @@ def get_content_info(root_path: str, content_path: str, content_type: ContentTyp for item in os.listdir(full_path) if not item.startswith(".") or show_hidden ] contents = [get_content_info(root_path, os.path.join(content_path, _path).replace("\\", "/"), _type, - depth - 1, show_hidden) + depth - 1, show_hidden) for _path, _type in _contents] size = None @@ -85,29 +79,29 @@ def get_content_info(root_path: str, content_path: str, content_type: ContentTyp ) -@api.route('/', defaults={'content_path': ''}) -@api.route('/') -@api.expect(contents_parser) -class Contents(Resource): - def get(self, content_path: str): - """ - Get information of the content path provided - """ - args = contents_parser.parse_args() - content_type: ContentType = args["type"] - show_hidden: bool = args["show_hidden"] - root: Path = args["root"] - - if root is None: - config = current_app.cea_config - root_path = config.server.project_root - else: - root_path = root - - try: - content_info = get_content_info(root_path, content_path, content_type, show_hidden=show_hidden) - return content_info.as_dict() - except ContentPathNotFound: - return {"message": f"Path `{content_path}` does not exist"}, 404 - except ContentTypeInvalid: - return {"message": f"Path `{content_path}` is not of type `{content_type.value}`"}, 400 +@router.get('/') +@router.get('/{content_path}') +async def get_contents(config: CEAConfig, type: ContentType, root: str, + content_path: str = "", show_hidden: bool = False): + """ + Get information of the content path provided + """ + content_type = type + + if root is None: + root_path = config.server.project_root + else: + root_path = root + try: + content_info = get_content_info(root_path, content_path, content_type, show_hidden=show_hidden) + return content_info.as_dict() + except ContentPathNotFound: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Path `{content_path}` does not exist", + ) + except ContentTypeInvalid: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Path `{content_path}` is not of type `{content_type.value}`", + ) diff --git a/cea/interfaces/dashboard/api/dashboard.py b/cea/interfaces/dashboard/api/dashboard.py index 695f896853..7550f64269 100644 --- a/cea/interfaces/dashboard/api/dashboard.py +++ b/cea/interfaces/dashboard/api/dashboard.py @@ -1,16 +1,15 @@ - - - import hashlib +from typing import Dict, Any -from flask import current_app, request -from flask_restx import Namespace, Resource +from fastapi import APIRouter import cea.config -import cea.plots.cache +import cea.plots +from cea.plots.cache import MemoryPlotCache from .utils import deconstruct_parameters +from ..dashboard import CEAConfig -api = Namespace('Dashboard', description='Dashboard plots') +router = APIRouter() LAYOUTS = ['row', 'grid'] CATEGORIES = None @@ -33,8 +32,7 @@ def dashboard_to_dict(dashboard): return out -def get_parameters_from_plot(plot, scenario_name=None): - config = cea.config.Configuration() +def get_parameters_from_plot(config, plot, scenario_name=None): parameters = [] # Make sure to set scenario name to config first if 'scenario-name' in plot.expected_parameters: @@ -57,8 +55,7 @@ def get_parameters_from_plot(plot, scenario_name=None): return parameters -def get_parameters_from_plot_class(plot_class, scenario_name=None): - config = cea.config.Configuration() +def get_parameters_from_plot_class(config, plot_class, scenario_name=None): parameters = [] # Make sure to set scenario name to config first if 'scenario-name' in plot_class.expected_parameters and scenario_name is not None: @@ -70,193 +67,175 @@ def get_parameters_from_plot_class(plot_class, scenario_name=None): return parameters -@api.route('/') -class Dashboards(Resource): - def get(self): - """ - Get list of Dashboards - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) +@router.get('/') +async def get_dashboards(config: CEAConfig): + """ + Get list of Dashboards + """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) - out = [] - for d in dashboards: - out.append(dashboard_to_dict(d)) + out = [] + for d in dashboards: + out.append(dashboard_to_dict(d)) + + return out - return out - def post(self): - """ - Create Dashboard - """ - form = api.payload - config = current_app.cea_config +@router.post('/') +async def create_dashboard(config: CEAConfig, payload: Dict[str, Any], ): + """ + Create Dashboard + """ + form = payload - if 'grid' in form['layout']: - types = [[2] + [1] * 4, [1] * 6, [1] * 3 + [3], [2, 1] * 2] - grid_width = types[int(form['layout'].split('-')[-1]) - 1] - dashboard_index = cea.plots.new_dashboard(config, current_app.plot_cache, form['name'], 'grid', - grid_width=grid_width) - else: - dashboard_index = cea.plots.new_dashboard(config, current_app.plot_cache, form['name'], form['layout']) + if 'grid' in form['layout']: + types = [[2] + [1] * 4, [1] * 6, [1] * 3 + [3], [2, 1] * 2] + grid_width = types[int(form['layout'].split('-')[-1]) - 1] + dashboard_index = cea.plots.new_dashboard(config, MemoryPlotCache(config.project), form['name'], 'grid', + grid_width=grid_width) + else: + dashboard_index = cea.plots.new_dashboard(config, MemoryPlotCache(config.project), form['name'], form['layout']) + + return {'new_dashboard_index': dashboard_index} + + +@router.post('/duplicate') +async def duplicate_dashboard(config: CEAConfig, payload: Dict[str, Any]): + form = payload + dashboard_index = cea.plots.duplicate_dashboard(config, MemoryPlotCache(config.project), form['name'], + form['dashboard_index']) + + return {'new_dashboard_index': dashboard_index} + + +@router.get('/{dashboard_index}') +async def get_dashboard(config: CEAConfig, dashboard_index: int): + """ + Get Dashboard + """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) - return {'new_dashboard_index': dashboard_index} + return dashboard_to_dict(dashboards[dashboard_index]) -@api.route('/duplicate') -class DashboardDuplicate(Resource): - def post(self): - form = api.payload - config = current_app.cea_config - dashboard_index = cea.plots.duplicate_dashboard(config, current_app.plot_cache, form['name'], - form['dashboard_index']) +@router.get('/{dashboard_index}') +async def delete_dashboard(config: CEAConfig, dashboard_index: int): + """ + Delete Dashboard + """ + cea.plots.delete_dashboard(config, dashboard_index) - return {'new_dashboard_index': dashboard_index} + return {'message': 'deleted dashboard'} -@api.route('/') -class Dashboard(Resource): - def get(self, dashboard_index): - """ - Get Dashboard - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) +@router.patch('/{dashboard_index}') +async def update_dashboard(config: CEAConfig, dashboard_index: int, payload: Dict[str, Any]): + """ + Update Dashboard properties + """ + form = payload + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) - return dashboard_to_dict(dashboards[dashboard_index]) + dashboard = dashboards[dashboard_index] + dashboard.set_scenario(form['scenario']) + cea.plots.write_dashboards(config, dashboards) - def delete(self, dashboard_index): - """ - Delete Dashboard - """ - config = current_app.cea_config - cea.plots.delete_dashboard(config, dashboard_index) + return {'new_dashboard_index': dashboard_index} - return {'message': 'deleted dashboard'} - def patch(self, dashboard_index): - """ - Update Dashboard properties - """ - form = api.payload - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.cea_config) +@router.get('/plot-categories') +async def get_plot_categories(): + return get_categories(None) - dashboard = dashboards[dashboard_index] - dashboard.set_scenario(form['scenario']) - cea.plots.write_dashboards(config, dashboards) - return {'new_dashboard_index': dashboard_index} +@router.get('/plot-categories/{category_name}/plots/{plot_id>}/parameters') +async def get_plot_category_parameters(config: CEAConfig, category_name: str, plot_id: str, scenario: str = None): + plot_class = cea.plots.categories.load_plot_by_id(category_name, plot_id, config.plugins) + return get_parameters_from_plot_class(config, plot_class, scenario) -@api.route('/plot-categories') -class DashboardPlotCategories(Resource): +@router.get('/{dashboard_index}/plots/{plot_index}>') +async def get_plot(config: CEAConfig, dashboard_index: int, plot_index: int): """ - Get Plot Categories + Get Dashboard Plot """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) - def get(self): - return get_categories(current_app.cea_config.plugins) + return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] -@api.route('/plot-categories//plots//parameters') -class DashboardPlotCategoriesParameters(Resource): +@router.put('/{dashboard_index}/plots/{plot_index}>') +async def create_plot_at_index(config: CEAConfig, dashboard_index: int, plot_index: int, payload: Dict[str, Any]): """ - Get Plot Form Parameters from Config + Create/Replace a new Plot at specified index """ + form = payload - def get(self, category_name, plot_id): - config = current_app.cea_config - plot_class = cea.plots.categories.load_plot_by_id(category_name, plot_id, config.plugins) - return get_parameters_from_plot_class(plot_class, request.args.get('scenario')) - - -@api.route('//plots/') -class DashboardPlot(Resource): - def get(self, dashboard_index, plot_index): - """ - Get Dashboard Plot - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) - - return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] - - def put(self, dashboard_index, plot_index): - """ - Create/Replace a new Plot at specified index - """ - form = api.payload - config = current_app.cea_config - - # avoid overwriting original config.scenario for plot - temp_config = cea.config.Configuration() - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) - dashboard = dashboards[dashboard_index] - - if 'category' in form and 'plot_id' in form: - dashboard.add_plot(form['category'], form['plot_id'], plugins=config.plugins, index=plot_index) - - # Set parameters if included in form and plot exists - if 'parameters' in form: - plot = dashboard.plots[plot_index] - plot_parameters = plot.expected_parameters.items() - if 'scenario-name' in plot.expected_parameters: - temp_config.scenario_name = form['parameters']['scenario-name'] - print('expected_parameters: {}'.format(plot_parameters)) - for pname, fqname in plot_parameters: - parameter = temp_config.get_parameter(fqname) - if isinstance(parameter, cea.config.MultiChoiceParameter): - plot.parameters[pname] = parameter.decode(','.join(form['parameters'][pname])) - else: - plot.parameters[pname] = parameter.decode(form['parameters'][pname]) + # avoid overwriting original config.scenario for plot + temp_config = cea.config.Configuration() + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboard = dashboards[dashboard_index] - cea.plots.write_dashboards(config, dashboards) + if 'category' in form and 'plot_id' in form: + dashboard.add_plot(form['category'], form['plot_id'], plugins=config.plugins, index=plot_index) - return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] + # Set parameters if included in form and plot exists + if 'parameters' in form: + plot = dashboard.plots[plot_index] + plot_parameters = plot.expected_parameters.items() + if 'scenario-name' in plot.expected_parameters: + temp_config.scenario_name = form['parameters']['scenario-name'] + print('expected_parameters: {}'.format(plot_parameters)) + for pname, fqname in plot_parameters: + parameter = temp_config.get_parameter(fqname) + if isinstance(parameter, cea.config.MultiChoiceParameter): + plot.parameters[pname] = parameter.decode(','.join(form['parameters'][pname])) + else: + plot.parameters[pname] = parameter.decode(form['parameters'][pname]) - def delete(self, dashboard_index, plot_index): - """ - Delete Plot from Dashboard - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) + cea.plots.write_dashboards(config, dashboards) - dashboard = dashboards[dashboard_index] - dashboard.remove_plot(plot_index) - cea.plots.write_dashboards(config, dashboards) + return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] - return dashboard_to_dict(dashboard) +@router.delete('/{dashboard_index}/plots/{plot_index}>') +async def delete_plot(config: CEAConfig, dashboard_index: int, plot_index: int): + """ + Delete Plot from Dashboard + """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) -@api.route('//plots//parameters') -class DashboardPlotParameters(Resource): - def get(self, dashboard_index, plot_index): - """ - Get Plot Form Parameters of Plot in Dashboard - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) + dashboard = dashboards[dashboard_index] + dashboard.remove_plot(plot_index) + cea.plots.write_dashboards(config, dashboards) - dashboard = dashboards[dashboard_index] - plot = dashboard.plots[plot_index] + return dashboard_to_dict(dashboard) - return get_parameters_from_plot(plot, request.args.get('scenario')) +@router.get('/{dashboard_index}/plots/{plot_index}/parameters') +async def get_plot_parameters(config: CEAConfig, dashboard_index: int, plot_index: int, scenario: str = None): + """ + Get Plot Form Parameters of Plot in Dashboard + """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) -@api.route('//plots//input-files') -class DashboardPlotInputFiles(Resource): - def get(self, dashboard_index, plot_index): - """ - Get input files of Plot - """ - config = current_app.cea_config - dashboards = cea.plots.read_dashboards(config, current_app.plot_cache) + dashboard = dashboards[dashboard_index] + plot = dashboard.plots[plot_index] - dashboard = dashboards[dashboard_index] - plot = dashboard.plots[plot_index] + return get_parameters_from_plot(config, plot, scenario) + + +@router.get('/{dashboard_index}/plots/{plot_index}/input-files') +async def get_plot_input_files(config: CEAConfig, dashboard_index: int, plot_index: int): + """ + Get input files of Plot + """ + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + + dashboard = dashboards[dashboard_index] + plot = dashboard.plots[plot_index] - data_path = plot.plot_data_to_file() - input_paths = [locator_method(*args) for locator_method, args in plot.input_files] + data_path = plot.plot_data_to_file() + input_paths = [locator_method(*args) for locator_method, args in plot.input_files] - return {'inputs': input_paths, 'data': [data_path] if data_path else []} + return {'inputs': input_paths, 'data': [data_path] if data_path else []} diff --git a/cea/interfaces/dashboard/api/databases.py b/cea/interfaces/dashboard/api/databases.py index 8041450cc8..8ee2a168b4 100644 --- a/cea/interfaces/dashboard/api/databases.py +++ b/cea/interfaces/dashboard/api/databases.py @@ -1,16 +1,14 @@ - - - import os from collections import OrderedDict -from flask_restx import Namespace, Resource, abort import pandas as pd +from fastapi import APIRouter, HTTPException, status from cea.databases import get_regions, get_database_tree, databases_folder_path from cea.utilities.schedule_reader import schedule_to_dataframe -api = Namespace("Databases", description="Database data for technologies in CEA") +router = APIRouter() + DATABASES_SCHEMA_KEYS = { "CONSTRUCTION_STANDARD": ["get_database_construction_standards"], @@ -65,32 +63,40 @@ def read_all_databases(database_path): return out -@api.route("/region") -class DatabaseRegions(Resource): - def get(self): - return {'regions': get_regions()} - - -@api.route("/region/") -class DatabaseRegion(Resource): - def get(self, region): - regions = get_regions() - if region not in regions: - abort(400, "Could not find '{}' region. Try instead {}".format(region, ", ".join(regions))) - return {"categories": get_database_tree(os.path.join(databases_folder_path, region))['categories']} - - -@api.route("/region//databases") -class DatabaseData(Resource): - def get(self, region): - regions = get_regions() - if region not in regions: - abort(400, "Could not find '{}' region. Try instead {}".format(region, ", ".join(regions))) - try: - return read_all_databases(os.path.join(databases_folder_path, region)) - except IOError as e: - print(e) - abort(500, str(e)) +@router.get("/region") +async def get_database_regions(): + return {'regions': get_regions()} + + +@router.get("/region/{region}") +async def get_database_region(region: str): + regions = get_regions() + if region not in regions: + _regions = ", ".join(regions) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Could not find '{region}' region. Try instead {_regions}", + ) + return {"categories": get_database_tree(os.path.join(databases_folder_path, region))['categories']} + + +@router.get("/region/{region}/databases") +async def get_database_region_data(region: str): + regions = get_regions() + if region not in regions: + _regions = ", ".join(regions) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"Could not find '{region}' region. Try instead {_regions}", + ) + try: + return read_all_databases(os.path.join(databases_folder_path, region)) + except IOError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) def convert_path_to_name(schema_dict): @@ -105,17 +111,17 @@ def convert_path_to_name(schema_dict): return schema_dict -@api.route("/schema") -class DatabaseSchema(Resource): - def get(self): - import cea.scripts - schemas = cea.schemas.schemas(plugins=[]) - out = {} - for db_name, db_schema_keys in DATABASES_SCHEMA_KEYS.items(): - out[db_name] = {} - for db_schema_key in db_schema_keys: - try: - out[db_name].update(convert_path_to_name(schemas[db_schema_key]['schema'])) - except KeyError as ex: - raise KeyError(f"Could not convert_path_to_name for {db_name}/{db_schema_key}. {ex}") - return out +@router.get("/schema") +async def get_database_schema(): + import cea.schemas + + schemas = cea.schemas.schemas(plugins=[]) + out = {} + for db_name, db_schema_keys in DATABASES_SCHEMA_KEYS.items(): + out[db_name] = {} + for db_schema_key in db_schema_keys: + try: + out[db_name].update(convert_path_to_name(schemas[db_schema_key]['schema'])) + except KeyError as ex: + raise KeyError(f"Could not convert_path_to_name for {db_name}/{db_schema_key}. {ex}") + return out diff --git a/cea/interfaces/dashboard/api/glossary.py b/cea/interfaces/dashboard/api/glossary.py index bba6d8d3b1..e6e65e895a 100644 --- a/cea/interfaces/dashboard/api/glossary.py +++ b/cea/interfaces/dashboard/api/glossary.py @@ -1,22 +1,19 @@ - - - -from flask_restx import Namespace, Resource -from flask import current_app +from fastapi import APIRouter from cea.glossary import read_glossary_df +from cea.interfaces.dashboard.dashboard import CEAConfig -api = Namespace('Glossary', description='Glossary for variables used in CEA') +router = APIRouter() -@api.route('/') -class Glossary(Resource): - def get(self): - glossary = read_glossary_df(plugins=current_app.cea_config.plugins) - groups = glossary.groupby('SCRIPT') - data = [] - for group in groups.groups: - df = groups.get_group(group) - result = df[~df.index.duplicated(keep='first')].fillna('-') - data.append({'script': group if group != '-' else 'inputs', 'variables': result.to_dict(orient='records')}) - return data +@router.get('/') +async def get_glossary(config: CEAConfig): + plugins = config.plugins + glossary = read_glossary_df(plugins=plugins) + groups = glossary.groupby('SCRIPT') + data = [] + for group in groups.groups: + df = groups.get_group(group) + result = df[~df.index.duplicated(keep='first')].fillna('-') + data.append({'script': group if group != '-' else 'inputs', 'variables': result.to_dict(orient='records')}) + return data diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index 1c640ce586..c4edb4d7ab 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -2,28 +2,29 @@ import os import shutil import traceback -from collections import OrderedDict +from typing import Dict, Any import geopandas import pandas as pd -from flask import current_app, request -from flask_restx import Namespace, Resource, abort +from fastapi import APIRouter, HTTPException, status +from fiona.errors import DriverError +from pydantic import BaseModel import cea.inputlocator -import cea.utilities.dbf -import cea.scripts import cea.schemas +import cea.scripts +import cea.utilities.dbf from cea.datamanagement.databases_verification import InputFileValidator from cea.interfaces.dashboard.api.databases import read_all_databases, DATABASES_SCHEMA_KEYS +from cea.interfaces.dashboard.dashboard import CEAConfig from cea.plots.supply_system.a_supply_system_map import get_building_connectivity, newer_network_layout_exists from cea.plots.variable_naming import get_color_array from cea.technologies.network_layout.main import layout_network, NetworkLayout from cea.utilities.schedule_reader import schedule_to_file, get_all_schedule_names, schedule_to_dataframe, \ read_cea_schedule, save_cea_schedule from cea.utilities.standardize_coordinates import get_geographic_coordinate_system -from fiona.errors import DriverError -api = Namespace('Inputs', description='Input data for CEA') +router = APIRouter() COLORS = { 'surroundings': get_color_array('white'), @@ -49,7 +50,7 @@ def get_input_database_schemas(): """Parse the schemas.yml file and create the dictionary of column types""" schemas = cea.schemas.schemas(plugins=[]) - input_database_schemas = OrderedDict() + input_database_schemas = dict() for db_name, locator in INPUT_DATABASES: schema = schemas[locator] input_database_schemas[db_name] = { @@ -66,159 +67,163 @@ def get_input_database_schemas(): NETWORK_KEYS = ['dc', 'dh'] -@api.route('/') -class InputList(Resource): - def get(self): - return {'buildingProperties': INPUT_KEYS, 'geoJSONs': GEOJSON_KEYS} +@router.get("/") +async def get_keys(): + return {'buildingProperties': INPUT_KEYS, 'geoJSONs': GEOJSON_KEYS} -@api.route('/building-properties/') -class InputBuildingProperties(Resource): - def get(self, db): - if db not in INPUTS: - abort(400, 'Input file not found: %s' % db, choices=INPUT_KEYS) - db_info = INPUTS[db] - columns = OrderedDict() - for column_name, column in db_info['columns'].items(): - columns[column_name] = column['type'] - return columns +@router.get('/building-properties/{db}') +async def get_building_props_db(db: str): + if db not in INPUTS: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Input file not found: {db}', + ) + db_info = INPUTS[db] + columns = dict() + for column_name, column in db_info['columns'].items(): + columns[column_name] = column['type'] + return columns -@api.route('/geojson/') -class InputGeojson(Resource): - def get(self, kind): - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) +@router.get('/geojson/{kind}') +async def get_input_geojson(config: CEAConfig, kind: str): + locator = cea.inputlocator.InputLocator(config.scenario) - if kind not in GEOJSON_KEYS: - abort(400, 'Input file not found: %s' % kind, choices=GEOJSON_KEYS) - # Building geojsons - elif kind in INPUT_KEYS and kind in GEOJSON_KEYS: - db_info = INPUTS[kind] - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) - location = getattr(locator, db_info['location'])() - if db_info['file_type'] != 'shp': - abort(500, 'Invalid database for geojson: %s' % location) - return df_to_json(location)[0] - elif kind in NETWORK_KEYS: - return get_network(config, kind)[0] - elif kind == 'streets': - return df_to_json(locator.get_street_network())[0] - - -@api.route('/building-properties') -class BuildingProperties(Resource): - def get(self): - return get_building_properties() - - -@api.route('/all-inputs') -class AllInputs(Resource): - def get(self): - config = current_app.cea_config + if kind not in GEOJSON_KEYS: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Input file not found: {kind}', + ) + # Building geojsons + elif kind in INPUT_KEYS and kind in GEOJSON_KEYS: + db_info = INPUTS[kind] locator = cea.inputlocator.InputLocator(config.scenario) + location = getattr(locator, db_info['location'])() + if db_info['file_type'] != 'shp': + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'Invalid database for geojson: {location}', + ) + return df_to_json(location)[0] + elif kind in NETWORK_KEYS: + return get_network(config, kind)[0] + elif kind == 'streets': + return df_to_json(locator.get_street_network())[0] + + +@router.get('/building-properties') +async def get_building_props(config: CEAConfig): + return get_building_properties(config) + + +@router.get('/all-inputs') +async def get_all_inputs(config: CEAConfig): + locator = cea.inputlocator.InputLocator(config.scenario) - # FIXME: Find a better way, current used to test for Input Editor - store = get_building_properties() - store['geojsons'] = {} - store['connected_buildings'] = {} - store['crs'] = {} - store['geojsons']['zone'], store['crs']['zone'] = df_to_json(locator.get_zone_geometry()) - store['geojsons']['surroundings'], store['crs']['surroundings'] = df_to_json( - locator.get_surroundings_geometry()) - store['geojsons']['trees'], store['crs']['trees'] = df_to_json(locator.get_tree_geometry()) - store['geojsons']['streets'], store['crs']['streets'] = df_to_json(locator.get_street_network()) - store['geojsons']['dc'], store['connected_buildings']['dc'], store['crs']['dc'] = get_network(config, 'dc') - store['geojsons']['dh'], store['connected_buildings']['dh'], store['crs']['dh'] = get_network(config, 'dh') - store['colors'] = COLORS - store['schedules'] = {} - - return store - - def put(self): - form = api.payload - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) + # FIXME: Find a better way, current used to test for Input Editor + store = get_building_properties(config) + store['geojsons'] = {} + store['connected_buildings'] = {} + store['crs'] = {} + store['geojsons']['zone'], store['crs']['zone'] = df_to_json(locator.get_zone_geometry()) + store['geojsons']['surroundings'], store['crs']['surroundings'] = df_to_json( + locator.get_surroundings_geometry()) + store['geojsons']['trees'], store['crs']['trees'] = df_to_json(locator.get_tree_geometry()) + store['geojsons']['streets'], store['crs']['streets'] = df_to_json(locator.get_street_network()) + store['geojsons']['dc'], store['connected_buildings']['dc'], store['crs']['dc'] = get_network(config, 'dc') + store['geojsons']['dh'], store['connected_buildings']['dh'], store['crs']['dh'] = get_network(config, 'dh') + store['colors'] = COLORS + store['schedules'] = {} - tables = form['tables'] - geojsons = form['geojsons'] - crs = form['crs'] - schedules = form['schedules'] + return store - out = {'tables': {}, 'geojsons': {}} - # TODO: Maybe save the files to temp location in case something fails - for db in INPUTS: - db_info = INPUTS[db] - location = getattr(locator, db_info['location'])() - file_type = db_info['file_type'] +class InputForm(BaseModel): + tables: Dict[str, Any] = {} + geojsons: Dict[str, Any] = {} + crs: Dict[str, Any] = {} + schedules: Dict[str, Any] = {} - if tables.get(db) is None: # ignore if table does not exist - continue - if len(tables[db]): - if file_type == 'shp': - table_df = geopandas.GeoDataFrame.from_features(geojsons[db]['features'], - crs=get_geographic_coordinate_system()) - out['geojsons'][db] = json.loads(table_df.to_json()) - table_df = table_df.to_crs(crs[db]) - table_df.to_file(location, driver='ESRI Shapefile', encoding='ISO-8859-1') - - table_df = pd.DataFrame(table_df.drop(columns='geometry')) - out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) - elif file_type == 'dbf': - table_df = pd.read_json(json.dumps(tables[db]), orient='index') +@router.put('/all-inputs') +async def save_all_inputs(config: CEAConfig, form: InputForm): + locator = cea.inputlocator.InputLocator(config.scenario) + + tables = form.tables + geojsons = form.geojsons + crs = form.crs + schedules = form.schedules + + out = {'tables': {}, 'geojsons': {}} - # Make sure index name is 'Name; - table_df.index.name = 'Name' - table_df = table_df.reset_index() + # TODO: Maybe save the files to temp location in case something fails + for db in INPUTS: + db_info = INPUTS[db] + location = getattr(locator, db_info['location'])() + file_type = db_info['file_type'] - cea.utilities.dbf.dataframe_to_dbf(table_df, location) - out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) + if tables.get(db) is None: # ignore if table does not exist + continue + + if len(tables[db]): + if file_type == 'shp': + table_df = geopandas.GeoDataFrame.from_features(geojsons[db]['features'], + crs=get_geographic_coordinate_system()) + out['geojsons'][db] = json.loads(table_df.to_json()) + table_df = table_df.to_crs(crs[db]) + table_df.to_file(location, driver='ESRI Shapefile', encoding='ISO-8859-1') - else: # delete file if empty unless it is surroundings (allow for empty surroundings file) - if db == "surroundings": - table_df = geopandas.GeoDataFrame(columns=["Name", "height_ag", "floors_ag"], geometry=[], - crs=get_geographic_coordinate_system()) - table_df.to_file(location) + table_df = pd.DataFrame(table_df.drop(columns='geometry')) + out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) + elif file_type == 'dbf': + table_df = pd.read_json(json.dumps(tables[db]), orient='index') - out['tables'][db] = [] + # Make sure index name is 'Name; + table_df.index.name = 'Name' + table_df = table_df.reset_index() - elif os.path.isfile(location): - if file_type == 'shp': - import glob - for filepath in glob.glob(os.path.join(locator.get_building_geometry_folder(), '%s.*' % db)): - os.remove(filepath) - elif file_type == 'dbf': - os.remove(location) + cea.utilities.dbf.dataframe_to_dbf(table_df, location) + out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) + else: # delete file if empty unless it is surroundings (allow for empty surroundings file) + if db == "surroundings": + table_df = geopandas.GeoDataFrame(columns=["Name", "height_ag", "floors_ag"], geometry=[], + crs=get_geographic_coordinate_system()) + table_df.to_file(location) + + out['tables'][db] = [] + + elif os.path.isfile(location): if file_type == 'shp': - out['geojsons'][db] = {} - - if schedules: - for building in schedules: - schedule_dict = schedules[building] - schedule_path = locator.get_building_weekly_schedules(building) - schedule_data = schedule_dict['SCHEDULES'] - schedule_complementary_data = {'MONTHLY_MULTIPLIER': schedule_dict['MONTHLY_MULTIPLIER'], - 'METADATA': schedule_dict['METADATA']} - data = pd.DataFrame() - for day in ['WEEKDAY', 'SATURDAY', 'SUNDAY']: - df = pd.DataFrame({'HOUR': range(1, 25), 'DAY': [day] * 24}) - for schedule_type, schedule in schedule_data.items(): - df[schedule_type] = schedule[day] - data = pd.concat([df, data], ignore_index=True) - save_cea_schedule(data.to_dict('list'), schedule_complementary_data, schedule_path) - print('Schedule file written to {}'.format(schedule_path)) - return out + import glob + for filepath in glob.glob(os.path.join(locator.get_building_geometry_folder(), '%s.*' % db)): + os.remove(filepath) + elif file_type == 'dbf': + os.remove(location) + if file_type == 'shp': + out['geojsons'][db] = {} -def get_building_properties(): - import cea.glossary + if schedules: + for building in schedules: + schedule_dict = schedules[building] + schedule_path = locator.get_building_weekly_schedules(building) + schedule_data = schedule_dict['SCHEDULES'] + schedule_complementary_data = {'MONTHLY_MULTIPLIER': schedule_dict['MONTHLY_MULTIPLIER'], + 'METADATA': schedule_dict['METADATA']} + data = pd.DataFrame() + for day in ['WEEKDAY', 'SATURDAY', 'SUNDAY']: + df = pd.DataFrame({'HOUR': range(1, 25), 'DAY': [day] * 24}) + for schedule_type, schedule in schedule_data.items(): + df[schedule_type] = schedule[day] + data = pd.concat([df, data], ignore_index=True) + save_cea_schedule(data.to_dict('list'), schedule_complementary_data, schedule_path) + print('Schedule file written to {}'.format(schedule_path)) + return out - config = current_app.cea_config +def get_building_properties(config): locator = cea.inputlocator.InputLocator(config.scenario) store = {'tables': {}, 'columns': {}} for db in INPUTS: @@ -347,125 +352,130 @@ def df_to_json(file_location): return None, None -@api.route('/building-schedule/') -class BuildingSchedule(Resource): - def get(self, building): - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) - try: - schedule_path = locator.get_building_weekly_schedules(building) - schedule_data, schedule_complementary_data = read_cea_schedule(schedule_path) - df = pd.DataFrame(schedule_data).set_index(['DAY', 'HOUR']) - out = {'SCHEDULES': { - schedule_type: {day: df.loc[day][schedule_type].values.tolist() for day in df.index.levels[0]} - for schedule_type in df.columns}} - out.update(schedule_complementary_data) - return out - except IOError as e: - print(e) - abort(500, 'File not found') +@router.get('/building-schedule/{building}') +async def get_building_schedule(config: CEAConfig, building: str): + locator = cea.inputlocator.InputLocator(config.scenario) + try: + schedule_path = locator.get_building_weekly_schedules(building) + schedule_data, schedule_complementary_data = read_cea_schedule(schedule_path) + df = pd.DataFrame(schedule_data).set_index(['DAY', 'HOUR']) + out = {'SCHEDULES': { + schedule_type: {day: df.loc[day][schedule_type].values.tolist() for day in df.index.levels[0]} + for schedule_type in df.columns}} + out.update(schedule_complementary_data) + return out + except IOError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) -@api.route('/databases') -class InputDatabaseData(Resource): - def get(self): - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) - try: - return read_all_databases(locator.get_databases_folder()) - except IOError as e: - print(e) - abort(500, str(e)) +@router.get('/databases') +async def get_input_database_data(config: CEAConfig): + locator = cea.inputlocator.InputLocator(config.scenario) + try: + return read_all_databases(locator.get_databases_folder()) + except IOError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) - def put(self): - config = current_app.cea_config - payload = json.loads(request.data) - locator = cea.inputlocator.InputLocator(config.scenario) - for db_type in payload: - for db_name in payload[db_type]: - if db_name == 'USE_TYPES': - database_dict_to_file(payload[db_type]['USE_TYPES']['USE_TYPE_PROPERTIES'], - locator.get_database_use_types_properties()) - for archetype, schedule_dict in payload[db_type]['USE_TYPES']['SCHEDULES'].items(): - schedule_dict_to_file( - schedule_dict, - locator.get_database_standard_schedules_use( - archetype - ) - ) - else: - locator_method = DATABASES_SCHEMA_KEYS[db_name][0] - db_path = locator.__getattribute__(locator_method)() - database_dict_to_file(payload[db_type][db_name], db_path) +@router.put('/databases') +async def put_input_database_data(config: CEAConfig, payload: Dict[str, Any]): + locator = cea.inputlocator.InputLocator(config.scenario) - return payload + for db_type in payload: + for db_name in payload[db_type]: + if db_name == 'USE_TYPES': + database_dict_to_file(payload[db_type]['USE_TYPES']['USE_TYPE_PROPERTIES'], + locator.get_database_use_types_properties()) + for archetype, schedule_dict in payload[db_type]['USE_TYPES']['SCHEDULES'].items(): + schedule_dict_to_file( + schedule_dict, + locator.get_database_standard_schedules_use( + archetype + ) + ) + else: + locator_method = DATABASES_SCHEMA_KEYS[db_name][0] + db_path = locator.__getattribute__(locator_method)() + database_dict_to_file(payload[db_type][db_name], db_path) + return payload -@api.route('/databases/copy') -class InputDatabaseCopy(Resource): - def put(self): - config = current_app.cea_config - payload = api.payload - locator = cea.inputlocator.InputLocator(config.scenario) - if payload and 'path' in payload and 'name' in payload: - copy_path = os.path.join(payload['path'], payload['name']) - if os.path.exists(copy_path): - abort(500, 'Copy path {} already exists. Choose a different path/name.'.format(copy_path)) - locator.ensure_parent_folder_exists(copy_path) - shutil.copytree(locator.get_databases_folder(), copy_path) - return {'message': 'Database copied to {}'.format(copy_path)} - else: - abort(500, "'path' and 'name' required") +@router.put('/databases/copy') +async def copy_input_database(config: CEAConfig, payload: Dict[str, Any]): + locator = cea.inputlocator.InputLocator(config.scenario) + if payload and 'path' in payload and 'name' in payload: + copy_path = os.path.join(payload['path'], payload['name']) + if os.path.exists(copy_path): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'Copy path {copy_path} already exists. Choose a different path/name.', + ) + locator.ensure_parent_folder_exists(copy_path) + shutil.copytree(locator.get_databases_folder(), copy_path) + return {'message': 'Database copied to {}'.format(copy_path)} + else: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="'path' and 'name' required", + ) + + +@router.get('/databases/check') +async def check_input_database(config: CEAConfig): + locator = cea.inputlocator.InputLocator(config.scenario) + try: + locator.verify_database_template() + except IOError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) -@api.route('/databases/check') -class InputDatabaseCheck(Resource): - def get(self): - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) - try: - locator.verify_database_template() - except IOError as e: - print(e) - abort(500, str(e)) - return {'message': 'Database in path seems to be valid.'} + return {'message': 'Database in path seems to be valid.'} -@api.route("/databases/validate") -class InputDatabaseValidate(Resource): - def get(self): - import cea.scripts - config = current_app.cea_config - locator = cea.inputlocator.InputLocator(config.scenario) - schemas = cea.schemas.schemas(plugins=[]) - validator = InputFileValidator(locator, plugins=config.plugins) - out = OrderedDict() - - for db_name, schema_keys in DATABASES_SCHEMA_KEYS.items(): - for schema_key in schema_keys: - schema = schemas[schema_key] - if schema_key != 'get_database_standard_schedules_use': - db_path = locator.__getattribute__(schema_key)() +@router.get("/databases/validate") +async def validate_input_database(config: CEAConfig): + import cea.scripts + locator = cea.inputlocator.InputLocator(config.scenario) + schemas = cea.schemas.schemas(plugins=[]) + validator = InputFileValidator(locator, plugins=config.plugins) + out = dict() + + for db_name, schema_keys in DATABASES_SCHEMA_KEYS.items(): + for schema_key in schema_keys: + schema = schemas[schema_key] + if schema_key != 'get_database_standard_schedules_use': + db_path = locator.__getattribute__(schema_key)() + try: + df = pd.read_excel(db_path, sheet_name=None) + errors = validator.validate(df, schema) + if errors: + out[db_name] = errors + except IOError: + out[db_name] = [{}, 'Could not find or read file: {}'.format(db_path)] + else: + for use_type in get_all_schedule_names(locator.get_database_use_types_folder()): + db_path = locator.__getattribute__(schema_key)(use_type) try: - df = pd.read_excel(db_path, sheet_name=None) + df = schedule_to_dataframe(db_path) errors = validator.validate(df, schema) if errors: - out[db_name] = errors + out[use_type] = errors except IOError: - out[db_name] = [{}, 'Could not find or read file: {}'.format(db_path)] - else: - for use_type in get_all_schedule_names(locator.get_database_use_types_folder()): - db_path = locator.__getattribute__(schema_key)(use_type) - try: - df = schedule_to_dataframe(db_path) - errors = validator.validate(df, schema) - if errors: - out[use_type] = errors - except IOError: - out[use_type] = [{}, 'Could not find or read file: {}'.format(db_path)] - return out + out[use_type] = [{}, 'Could not find or read file: {}'.format(db_path)] + return out def database_dict_to_file(db_dict, db_path): @@ -477,7 +487,7 @@ def database_dict_to_file(db_dict, db_path): def schedule_dict_to_file(schedule_dict, schedule_path): - schedule = OrderedDict() + schedule = dict() for key, data in schedule_dict.items(): schedule[key] = pd.DataFrame(data) schedule_to_file(schedule, schedule_path) @@ -498,7 +508,3 @@ def get_choices(choice_properties, path): label = 'none' out.append({'value': choice, 'label': label}) return out - - -if __name__ == "__main__": - print(get_input_database_schemas()) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 4238ea3462..4c62144218 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -1,197 +1,214 @@ - - - +import glob import os import shutil -import glob import tempfile -from functools import wraps import traceback +from typing import Dict, Any import geopandas -from flask import current_app, request -from flask_restx import Namespace, Resource, fields, abort -from staticmap import StaticMap, Polygon +from fastapi import APIRouter, HTTPException, status, Request, Path, Depends +from pydantic import BaseModel from shapely.geometry import shape -import json +from staticmap import StaticMap, Polygon -import cea.inputlocator import cea.api -import cea.config +import cea.inputlocator +from cea.interfaces.dashboard.dashboard import CEAConfig from cea.plots.colors import color_to_rgb from cea.utilities.standardize_coordinates import get_geographic_coordinate_system -api = Namespace('Project', description='Current project for CEA') +router = APIRouter() # PATH_REGEX = r'(^[a-zA-Z]:\\[\\\S|*\S]?.*$)|(^(/[^/ ]*)+/?$)' -PROJECT_PATH_MODEL = api.model('Project Path', { - 'project': fields.String(description='Path of Project'), -}) - -SCENARIO_PATH_MODEL = api.inherit('Scenario Path', PROJECT_PATH_MODEL, { - 'scenario_name': fields.String(description='Name of Scenario') -}) - -PROJECT_MODEL = api.inherit('Project', SCENARIO_PATH_MODEL, { - 'project_name': fields.String(description='Name of Project'), - 'scenarios_list': fields.List(fields.String, description='List of Scenarios found in Project') -}) - -NEW_PROJECT_MODEL = api.model('New Project', { - 'project_name': fields.String(description='Name of Project'), - 'project_root': fields.String(description='Root path of Project') -}) - - -@api.route('/') -class Project(Resource): - @api.marshal_with(PROJECT_MODEL) - @api.doc(params={'project': 'Path of Project (Leave blank to use path in config)'}) - def get(self): - project = request.args.get('project') - if project is None: - config = current_app.cea_config - scenario_name = config.scenario_name - else: - if not os.path.exists(project): - abort(400, 'Project path: "{project}" does not exist'.format(project=project)) - # Prevent changing current_app config - config = cea.config.Configuration() +# PROJECT_PATH_MODEL = api.model('Project Path', { +# 'project': fields.String(description='Path of Project'), +# }) +# +# SCENARIO_PATH_MODEL = api.inherit('Scenario Path', PROJECT_PATH_MODEL, { +# 'scenario_name': fields.String(description='Name of Scenario') +# }) +# +# PROJECT_MODEL = api.inherit('Project', SCENARIO_PATH_MODEL, { +# 'project_name': fields.String(description='Name of Project'), +# 'scenarios_list': fields.List(fields.String, description='List of Scenarios found in Project') +# }) +# +# NEW_PROJECT_MODEL = api.model('New Project', { +# 'project_name': fields.String(description='Name of Project'), +# 'project_root': fields.String(description='Root path of Project') +# }) + +class ScenarioPath(BaseModel): + project: str + scenario_name: str + + +class NewProject(BaseModel): + project_name: str + project_root: str + + +@router.get('/') +async def get_project_info(config: CEAConfig, project: str = None): + + if project is None: + scenario_name = config.scenario_name + else: + if not os.path.exists(project): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Project path: "{project}" does not exist', + ) + config.project = project + scenario_name = None + + return {'project_name': os.path.basename(config.project), 'project': config.project, + 'scenario_name': scenario_name, 'scenarios_list': list_scenario_names_for_project(config)} + + +@router.post('/') +async def create_new_project(new_project: NewProject): + """ + Create new project folder + """ + project_name = new_project.project_name + project_root = new_project.project_root + + if project_name and project_root: + project = os.path.join(project_root, project_name) + try: + os.makedirs(project, exist_ok=True) + except OSError as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + return {'message': 'Project folder created', 'project': project} + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Parameters not valid - project_name: {project_name}, project_root: {project_root}', + ) + + +@router.put('/') +async def update_project(config: CEAConfig, scenario_path: ScenarioPath): + """ + Update Project info in config + """ + project = scenario_path.project + scenario_name = scenario_path.scenario_name + + if project and scenario_name: + # Project path must exist but scenario does not have to + if os.path.exists(project): config.project = project - scenario_name = None - - return {'project_name': os.path.basename(config.project), 'project': config.project, - 'scenario_name': scenario_name, 'scenarios_list': list_scenario_names_for_project(config)} - - @api.expect(NEW_PROJECT_MODEL) - def post(self): - """Create new project folder""" - project_name = api.payload.get('project_name') - project_root = api.payload.get('project_root') - - if project_name and project_root: - project = os.path.join(project_root, project_name) - try: - os.makedirs(project, exist_ok=True) - except OSError as e: - abort(400, str(e)) - - return {'message': 'Project folder created', 'project': project} - else: - abort(400, 'Parameters not valid - project_name: {project_name}, project_root: {project_root}'.format( - project_name=project_name, project_root=project_root - )) - - @api.expect(SCENARIO_PATH_MODEL) - def put(self): - """Update Project info in config""" - config = current_app.cea_config - project = api.payload.get('project') - scenario_name = api.payload.get('scenario_name') - - if project and scenario_name: - # Project path must exist but scenario does not have to - if os.path.exists(project): - config.project = project - config.scenario_name = scenario_name - config.save() - return {'message': 'Updated project info in config', 'project': project, 'scenario_name': scenario_name} - else: - abort(400, 'project: "{project}" does not exist'.format(project=project)) + config.scenario_name = scenario_name + config.save() + return {'message': 'Updated project info in config', 'project': project, 'scenario_name': scenario_name} else: - abort(400, - 'Parameters not valid - project: {project}, scenario_name: {scenario_name}'.format( - project=project, scenario_name=scenario_name)) - - -@api.route('/scenario/') -class Scenarios(Resource): - def post(self): - """Create new scenario""" - payload: dict = api.payload - project = payload.get('project') - scenario_name = payload.get('scenario_name') - if scenario_name is None: - return {'message': 'scenario_name parameter cannot be empty'}, 500 - - databases_path = payload.get('databases_path') - input_data = payload.get('input_data') - - with tempfile.TemporaryDirectory() as tmp: - config = cea.config.Configuration() - config.project = tmp - config.scenario_name = "temp_scenario" - - _project = project or config.project - - locator = cea.inputlocator.InputLocator(config.scenario) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'project: "{project}" does not exist', + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Parameters not valid - project: {project}, scenario_name: {scenario_name}', + ) + + +@router.post('/scenario/') +async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): + """ + Create new scenario + """ + project = payload.get('project') + scenario_name = payload.get('scenario_name') + if scenario_name is None: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail='scenario_name parameter cannot be empty', + ) + + databases_path = payload.get('databases_path') + input_data = payload.get('input_data') + + with tempfile.TemporaryDirectory() as tmp: + config.project = tmp + config.scenario_name = "temp_scenario" + + _project = project or config.project + + locator = cea.inputlocator.InputLocator(config.scenario) + + # Run database_initializer to copy databases to input + if databases_path is not None: + try: + cea.api.data_initializer(config, databases_path=databases_path) + except Exception as e: + raise Exception(f'data_initializer: {e}') from e - # Run database_initializer to copy databases to input - if databases_path is not None: + if input_data == 'import': + files = payload.get('files') + if files is not None: + try: + output_path, project_name = os.path.split(config.project) + cea.api.create_new_scenario(config, + output_path=output_path, + project=project_name, + scenario=config.scenario_name, + zone=files.get('zone'), + surroundings=files.get('surroundings'), + streets=files.get('streets'), + terrain=files.get('terrain'), + typology=files.get('typology')) + except Exception as e: + raise Exception(f'create_new_scenario: {e}') from e + + elif input_data == 'copy': + source_scenario_name = payload.get('copy_scenario') + source_scenario = os.path.join(_project, source_scenario_name) + os.makedirs(locator.get_input_folder(), exist_ok=True) + shutil.copytree(cea.inputlocator.InputLocator(source_scenario).get_input_folder(), + locator.get_input_folder()) + + elif input_data == 'generate': + tools = payload.get('tools', []) + for tool in tools: try: - cea.api.data_initializer(config, databases_path=databases_path) + if tool == 'zone': + # FIXME: Setup a proper endpoint for site creation + site_geojson = payload.get('geojson') + if site_geojson is None: + raise ValueError('Could not find GeoJson for site polygon') + site = geopandas.GeoDataFrame(crs=get_geographic_coordinate_system(), + geometry=[shape(site_geojson['features'][0]['geometry'])]) + site_path = locator.get_site_polygon() + locator.ensure_parent_folder_exists(site_path) + site.to_file(site_path) + print(f'site.shp file created at {site_path}') + cea.api.zone_helper(config) + elif tool == 'surroundings': + cea.api.surroundings_helper(config) + elif tool == 'streets': + cea.api.streets_helper(config) + elif tool == 'terrain': + cea.api.terrain_helper(config) + elif tool == 'weather': + cea.api.weather_helper(config) except Exception as e: - raise Exception(f'data_initializer: {e}') from e - - if input_data == 'import': - files = payload.get('files') - if files is not None: - try: - output_path, project_name = os.path.split(config.project) - cea.api.create_new_scenario(config, - output_path=output_path, - project=project_name, - scenario=config.scenario_name, - zone=files.get('zone'), - surroundings=files.get('surroundings'), - streets=files.get('streets'), - terrain=files.get('terrain'), - typology=files.get('typology')) - except Exception as e: - raise Exception(f'create_new_scenario: {e}') from e - - elif input_data == 'copy': - source_scenario_name = payload.get('copy_scenario') - source_scenario = os.path.join(_project, source_scenario_name) - os.makedirs(locator.get_input_folder(), exist_ok=True) - shutil.copytree(cea.inputlocator.InputLocator(source_scenario).get_input_folder(), - locator.get_input_folder()) - - elif input_data == 'generate': - tools = payload.get('tools', []) - for tool in tools: - try: - if tool == 'zone': - # FIXME: Setup a proper endpoint for site creation - site_geojson = api.payload.get('geojson') - if site_geojson is None: - raise ValueError('Could not find GeoJson for site polygon') - site = geopandas.GeoDataFrame(crs=get_geographic_coordinate_system(), - geometry=[shape(site_geojson['features'][0]['geometry'])]) - site_path = locator.get_site_polygon() - locator.ensure_parent_folder_exists(site_path) - site.to_file(site_path) - print(f'site.shp file created at {site_path}') - cea.api.zone_helper(config) - elif tool == 'surroundings': - cea.api.surroundings_helper(config) - elif tool == 'streets': - cea.api.streets_helper(config) - elif tool == 'terrain': - cea.api.terrain_helper(config) - elif tool == 'weather': - cea.api.weather_helper(config) - except Exception as e: - raise Exception(f'{tool}_helper: {e}') from e - - # Move temp scenario to correct path - new_scenario_path = os.path.join(_project, str(scenario_name).strip()) - print(f"Moving from {config.scenario} to {new_scenario_path}") - shutil.move(config.scenario, new_scenario_path) - - return {'scenarios_list': list_scenario_names_for_project(config)} + raise Exception(f'{tool}_helper: {e}') from e + + # Move temp scenario to correct path + new_scenario_path = os.path.join(_project, str(scenario_name).strip()) + print(f"Moving from {config.scenario} to {new_scenario_path}") + shutil.move(config.scenario, new_scenario_path) + + return {'scenarios_list': list_scenario_names_for_project(config)} def glob_shapefile_auxilaries(shapefile_path): @@ -200,134 +217,148 @@ def glob_shapefile_auxilaries(shapefile_path): return glob.glob('{basepath}.*'.format(basepath=os.path.splitext(shapefile_path)[0])) -def check_scenario_exists(func): - @wraps(func) - def wrapper(*args, **kwargs): - config = current_app.cea_config - if len(request.data): - try: - # DELETE method might have a "project" payload... - data = json.loads(request.data.decode('utf-8')) - config.project = data["project"] - except Exception: - pass - choices = list_scenario_names_for_project(config) - if kwargs['scenario'] not in choices: - abort(400, 'Scenario does not exist', choices=choices) - else: - return func(*args, **kwargs) - return wrapper +def list_scenario_names_for_project(config): + with config.ignore_restrictions(): + return config.get_parameter('general:scenario-name')._choices -# FIXME: Potential Issue. Need to check if the scenario being deleted/renamed is running in scripts. -@api.route('/scenario/') -class Scenario(Resource): - method_decorators = [check_scenario_exists] - - def get(self, scenario): - """Scenario details""" - return {'name': scenario} - - def put(self, scenario): - """Update scenario""" - config = current_app.cea_config - scenario_path = os.path.join(config.project, scenario) - new_scenario_name = api.payload.get('name') - try: - if new_scenario_name is not None: - new_path = os.path.join(config.project, new_scenario_name) - os.rename(scenario_path, new_path) - if config.scenario_name == scenario: - config.scenario_name = new_scenario_name - config.save() - return {'name': new_scenario_name} - except OSError: - abort(400, 'Make sure that the scenario you are trying to rename is not open in any application. ' - 'Try and refresh the page again.') - - def delete(self, scenario): - """Delete scenario from project""" - config = current_app.cea_config - scenario_path = os.path.join(config.project, scenario) - try: - shutil.rmtree(scenario_path) - return {'scenarios': list_scenario_names_for_project(config)} - except OSError: - traceback.print_exc() - abort(400, 'Make sure that the scenario you are trying to delete is not open in any application. ' - 'Try and refresh the page again.') - - -@api.route('/scenario//image') -class ScenarioImage(Resource): - @api.doc(params={'project': 'Path of Project (Leave blank to use path in config)'}) - def get(self, scenario): - building_limit = 500 - - project = request.args.get('project') - if project is None: - config = current_app.cea_config - else: - if not os.path.exists(project): - abort(400, 'Project path: "{project}" does not exist'.format(project=project)) - config = cea.config.Configuration() - config.project = project - - choices = list_scenario_names_for_project(config) - if scenario in choices: - locator = cea.inputlocator.InputLocator(os.path.join(config.project, scenario)) - zone_path = locator.get_zone_geometry() - if os.path.isfile(zone_path): - cache_path = os.path.join(config.project, '.cache') - image_path = os.path.join(cache_path, scenario + '.png') - - zone_modified = os.path.getmtime(zone_path) - if not os.path.isfile(image_path): - image_modified = 0 - else: - image_modified = os.path.getmtime(image_path) - - if zone_modified > image_modified: - print(f'Generating preview image for scenario: {scenario}') - # Make sure .cache folder exists - os.makedirs(cache_path, exist_ok=True) - - try: - zone_df = geopandas.read_file(zone_path) - zone_df = zone_df.to_crs(get_geographic_coordinate_system()) - polygons = zone_df['geometry'] - - m = StaticMap(256, 160, url_template='http://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png') - if len(polygons) <= building_limit: - polygons = [list(polygons.geometry.exterior[row_id].coords) for row_id in - range(polygons.shape[0])] - for polygon in polygons: - out = Polygon(polygon, color_to_rgb('purple'), 'black', False) - m.add_polygon(out) - else: - print(f'Number of buildings({len(polygons)}) exceed building limit({building_limit}): ' - f'Generating simplified image') - # Generate only the shape outline of the zone area - convex_hull = polygons.unary_union.convex_hull - polygon = convex_hull.exterior.coords - out = Polygon(polygon, None, color_to_rgb('purple'), False) - m.add_polygon(out) +async def check_scenario_exists(request: Request, config: CEAConfig, scenario: str = Path()): + try: + data = await request.json() + except Exception: + data = None - image = m.render() - image.save(image_path) - except Exception as e: - abort(400, str(e)) + if len(data): + try: + config.project = data["project"] + except Exception: + pass + choices = list_scenario_names_for_project(config) + if scenario not in choices: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Scenario does not exist.', + ) - import base64 - with open(image_path, 'rb') as imgFile: - image = base64.b64encode(imgFile.read()) - return {'image': image.decode("utf-8")} - abort(400, 'Zone file not found') - else: - abort(400, 'Scenario does not exist', choices=choices) +# FIXME: Potential Issue. Need to check if the scenario being deleted/renamed is running in scripts. +@router.get('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) +async def get(scenario: str): + """Scenario details""" + return {'name': scenario} + + +@router.put('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) +async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): + """Update scenario""" + scenario_path = os.path.join(config.project, scenario) + new_scenario_name = payload.get('name') + try: + if new_scenario_name is not None: + new_path = os.path.join(config.project, new_scenario_name) + os.rename(scenario_path, new_path) + if config.scenario_name == scenario: + config.scenario_name = new_scenario_name + config.save() + return {'name': new_scenario_name} + except OSError: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Make sure that the scenario you are trying to rename is not open in any application. ' + 'Try and refresh the page again.', + ) + + +@router.delete('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) +async def delete(config: CEAConfig, scenario: str): + """Delete scenario from project""" + scenario_path = os.path.join(config.project, scenario) + try: + shutil.rmtree(scenario_path) + return {'scenarios': list_scenario_names_for_project(config)} + except OSError: + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Make sure that the scenario you are trying to delete is not open in any application. ' + 'Try and refresh the page again.', + ) + + +@router.get('/scenario/{scenario}/image') +async def get_scenario_image(config: CEAConfig, project: str, scenario: str): + building_limit = 500 + + if project is None: + config = config + else: + if not os.path.exists(project): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Project path: "{project}" does not exist', + ) + config = config + config.project = project + + choices = list_scenario_names_for_project(config) + if scenario in choices: + locator = cea.inputlocator.InputLocator(os.path.join(config.project, scenario)) + zone_path = locator.get_zone_geometry() + if os.path.isfile(zone_path): + cache_path = os.path.join(config.project, '.cache') + image_path = os.path.join(cache_path, scenario + '.png') + + zone_modified = os.path.getmtime(zone_path) + if not os.path.isfile(image_path): + image_modified = 0 + else: + image_modified = os.path.getmtime(image_path) + if zone_modified > image_modified: + print(f'Generating preview image for scenario: {scenario}') + # Make sure .cache folder exists + os.makedirs(cache_path, exist_ok=True) -def list_scenario_names_for_project(config): - with config.ignore_restrictions(): - return config.get_parameter('general:scenario-name')._choices + try: + zone_df = geopandas.read_file(zone_path) + zone_df = zone_df.to_crs(get_geographic_coordinate_system()) + polygons = zone_df['geometry'] + + m = StaticMap(256, 160, url_template='http://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png') + if len(polygons) <= building_limit: + polygons = [list(polygons.geometry.exterior[row_id].coords) for row_id in + range(polygons.shape[0])] + for polygon in polygons: + out = Polygon(polygon, color_to_rgb('purple'), 'black', False) + m.add_polygon(out) + else: + print(f'Number of buildings({len(polygons)}) exceed building limit({building_limit}): ' + f'Generating simplified image') + # Generate only the shape outline of the zone area + convex_hull = polygons.unary_union.convex_hull + polygon = convex_hull.exterior.coords + out = Polygon(polygon, None, color_to_rgb('purple'), False) + m.add_polygon(out) + + image = m.render() + image.save(image_path) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=str(e), + ) + + import base64 + with open(image_path, 'rb') as imgFile: + image = base64.b64encode(imgFile.read()) + + return {'image': image.decode("utf-8")} + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Zone file not found', + ) + else: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Scenario does not exist', + ) diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index 13260c46cf..ef2608fa5c 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -1,95 +1,85 @@ +from typing import Dict, Any +from fastapi import APIRouter - -from flask import current_app -from flask_restx import Namespace, Resource, fields - +import cea.config import cea.scripts from .utils import deconstruct_parameters - -api = Namespace('Tools', description='Scripts for CEA') - -TOOL_DESCRIPTION_MODEL = api.model('Tool', { - 'label': fields.String(description='Name of tool'), - 'description': fields.String(description='Description of tool') -}) - -TOOL_LIST = api.model('ToolList', {'tools': fields.List}) - - -@api.route('/') -class ToolList(Resource): - def get(self): - from itertools import groupby - from collections import OrderedDict - - config = current_app.cea_config - tools = cea.scripts.for_interface('dashboard', plugins=config.plugins) - result = OrderedDict() - for category, group in groupby(tools, lambda t: t.category): - result[category] = [ - {'name': t.name, 'label': t.label, 'description': t.description} for t in group] - - return result - - -@api.route('/') -class Tool(Resource): - def get(self, tool_name): - config = current_app.cea_config - script = cea.scripts.by_name(tool_name, plugins=config.plugins) - - parameters = [] - categories = {} - for _, parameter in config.matching_parameters(script.parameters): - if parameter.category: - if parameter.category not in categories: - categories[parameter.category] = [] - categories[parameter.category].append( - deconstruct_parameters(parameter)) - else: - parameters.append(deconstruct_parameters(parameter)) - - out = { - 'category': script.category, - 'label': script.label, - 'description': script.description, - 'parameters': parameters, - 'categorical_parameters': categories, - } - - return out - - -@api.route('//default') -class ToolDefault(Resource): - def post(self, tool_name): - """Restore the default configuration values for the CEA""" - config = current_app.cea_config - default_config = cea.config.Configuration( - config_file=cea.config.DEFAULT_CONFIG) - - for parameter in parameters_for_script(tool_name, config): - if parameter.name != 'scenario': - parameter.set( - default_config.sections[parameter.section.name].parameters[parameter.name].get()) - config.save() - return 'Success' - - -@api.route('//save-config') -class ToolSave(Resource): - def post(self, tool_name): - """Save the configuration for this tool to the configuration file""" - config = current_app.cea_config - payload = api.payload - for parameter in parameters_for_script(tool_name, config): - if parameter.name != 'scenario' and parameter.name in payload: - value = payload[parameter.name] - print('%s: %s' % (parameter.name, value)) - parameter.set(value) - config.save() - return 'Success' +from ..dashboard import CEAConfig + +router = APIRouter() + + +# TOOL_DESCRIPTION_MODEL = api.model('Tool', { +# 'label': fields.String(description='Name of tool'), +# 'description': fields.String(description='Description of tool') +# }) +# +# TOOL_LIST = api.model('ToolList', {'tools': fields.List}) + + +@router.get('/') +async def get_tool_list(config: CEAConfig): + from itertools import groupby + + tools = cea.scripts.for_interface('dashboard', plugins=config.plugins) + result = dict() + for category, group in groupby(tools, lambda t: t.category): + result[category] = [ + {'name': t.name, 'label': t.label, 'description': t.description} for t in group] + + return result + + +@router.get('/{tool_name}') +async def get_tool_properties(config: CEAConfig, tool_name: str): + script = cea.scripts.by_name(tool_name, plugins=config.plugins) + + parameters = [] + categories = {} + for _, parameter in config.matching_parameters(script.parameters): + if parameter.category: + if parameter.category not in categories: + categories[parameter.category] = [] + categories[parameter.category].append( + deconstruct_parameters(parameter, config)) + else: + parameters.append(deconstruct_parameters(parameter, config)) + + out = { + 'category': script.category, + 'label': script.label, + 'description': script.description, + 'parameters': parameters, + 'categorical_parameters': categories, + } + + return out + + +@router.post('/{tool_name}/default') +async def restore_default_config(config: CEAConfig, tool_name: str): + """Restore the default configuration values for the CEA""" + default_config = cea.config.Configuration(config_file=cea.config.DEFAULT_CONFIG) + + for parameter in parameters_for_script(tool_name, config): + if parameter.name != 'scenario': + parameter.set( + default_config.sections[parameter.section.name].parameters[parameter.name].get()) + config.save() + return 'Success' + + +@router.post('/{tool_name}/save-config') +async def save_tool_config(config: CEAConfig, tool_name: str, payload: Dict[str, Any]): + """Save the configuration for this tool to the configuration file""" + for parameter in parameters_for_script(tool_name, config): + if parameter.name != 'scenario' and parameter.name in payload: + value = payload[parameter.name] + print('%s: %s' % (parameter.name, value)) + parameter.set(value) + config.save() + return 'Success' def parameters_for_script(script_name, config): diff --git a/cea/interfaces/dashboard/api/utils.py b/cea/interfaces/dashboard/api/utils.py index 348c3a60c1..6dad3ebadb 100644 --- a/cea/interfaces/dashboard/api/utils.py +++ b/cea/interfaces/dashboard/api/utils.py @@ -1,13 +1,8 @@ - - - -from flask import current_app - import cea.config import cea.inputlocator -def deconstruct_parameters(p: cea.config.Parameter): +def deconstruct_parameters(p: cea.config.Parameter, config=None): params = {'name': p.name, 'type': type(p).__name__, 'nullable': False, 'help': p.help} try: params["value"] = p.get() @@ -19,7 +14,6 @@ def deconstruct_parameters(p: cea.config.Parameter): params['choices'] = p._choices if isinstance(p, cea.config.WeatherPathParameter): - config = current_app.cea_config locator = cea.inputlocator.InputLocator(config.scenario) params['choices'] = {wn: locator.get_weather( wn) for wn in locator.get_weather_names()} @@ -35,4 +29,4 @@ def deconstruct_parameters(p: cea.config.Parameter): except AttributeError as e: pass - return params \ No newline at end of file + return params diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 1a73ada14b..d8808d1fd4 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -1,55 +1,62 @@ -import webbrowser +import sys -from flask import Flask -from flask_cors import CORS -from flask_socketio import SocketIO +import uvicorn +from fastapi import FastAPI, Depends +from fastapi.middleware.cors import CORSMiddleware +from typing_extensions import Annotated import cea.config -import cea.plots -import cea.plots.cache + + +def get_cea_config(): + config = cea.config.Configuration() + return config + + +CEAConfig = Annotated[dict, Depends(get_cea_config)] + + +def create_app(): + origins = [ + "http://localhost", + "http://localhost:5173", + "http://localhost:5050", + ] + + app = FastAPI() + + # Setup CORS + app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + + # Mount socketio app + from cea.interfaces.dashboard.server.socketio import socket_app + app.mount("/socket.io", socket_app, "socketio") + + # Import other routers + import cea.interfaces.dashboard.api as api + import cea.interfaces.dashboard.plots.routes as plots + import cea.interfaces.dashboard.server as server + + app.include_router(api.router, prefix='/api') + app.include_router(plots.router, prefix='/plots') + app.include_router(server.router, prefix='/server') + + return app def main(config): - config.restricted_to = None # allow access to the whole config file - plot_cache = cea.plots.cache.MemoryPlotCache(config.project) - app = Flask(__name__) - CORS(app) - app.config.from_mapping({'SECRET_KEY': 'secret'}) - socketio = SocketIO(app, cors_allowed_origins="*") - - if config.server.browser: - from cea.interfaces.dashboard.frontend import blueprint as frontend - app.register_blueprint(frontend) - - from cea.interfaces.dashboard.plots.routes import blueprint as plots_blueprint - from cea.interfaces.dashboard.server import blueprint as server_blueprint, shutdown_server - from cea.interfaces.dashboard.api import blueprint as api_blueprint - - app.register_blueprint(plots_blueprint) - app.register_blueprint(api_blueprint) - app.register_blueprint(server_blueprint) - - # keep a copy of the configuration we're using - app.cea_config = config - app.plot_cache = plot_cache - app.socketio = socketio - - print("start CEA dashboard server") - - if config.server.browser: - url = f"http://{config.server.host}:{config.server.port}" - print(f"Open {url} in your browser to access the GUI") - webbrowser.open(url) - - print("Press Ctrl+C to stop server") + app = create_app() try: - socketio.run(app, host=config.server.host, port=config.server.port) + uvicorn.run(app, host="127.0.0.1", port=5050) except KeyboardInterrupt: - with app.app_context(): - shutdown_server() - - print("server exited") + sys.exit(0) -if __name__ == '__main__': +if __name__ == "__main__": main(cea.config.Configuration()) diff --git a/cea/interfaces/dashboard/frontend/.gitignore b/cea/interfaces/dashboard/frontend/.gitignore deleted file mode 100644 index 378eac25d3..0000000000 --- a/cea/interfaces/dashboard/frontend/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/cea/interfaces/dashboard/frontend/__init__.py b/cea/interfaces/dashboard/frontend/__init__.py deleted file mode 100644 index 5f9faff5f5..0000000000 --- a/cea/interfaces/dashboard/frontend/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -import os.path -from io import BytesIO -from urllib.request import urlopen -from zipfile import ZipFile - -from flask import Blueprint - -blueprint = Blueprint('frontend', __name__, url_prefix='/', static_folder="build", static_url_path="/") - - -@blueprint.route('/') -def frontend(): - return blueprint.send_static_file('index.html') - - -def get_build(): - url = "https://github.com/architecture-building-systems/CityEnergyAnalyst-GUI/releases/download/v3.35.0-browser/build.zip" - output = os.path.join(os.path.dirname(os.path.abspath(__file__)), "build") - - print("Fetching GUI build...") - with urlopen(url) as r: - with ZipFile(BytesIO(r.read())) as f: - f.extractall(output) - - -get_build() diff --git a/cea/interfaces/dashboard/plots/routes.py b/cea/interfaces/dashboard/plots/routes.py index b57e657611..f10f69895c 100644 --- a/cea/interfaces/dashboard/plots/routes.py +++ b/cea/interfaces/dashboard/plots/routes.py @@ -1,29 +1,27 @@ +import re - - -from flask import Blueprint, render_template, current_app, make_response +from fastapi import APIRouter, Request +from fastapi.responses import HTMLResponse +from fastapi.templating import Jinja2Templates import cea.inputlocator import cea.plots import cea.plots.categories - -import re - import cea.schemas from cea import MissingInputDataException +from cea.interfaces.dashboard.dashboard import CEAConfig +from cea.plots.cache import MemoryPlotCache -blueprint = Blueprint( - 'plots_blueprint', - __name__, - url_prefix='/plots', - template_folder='templates', -) +router = APIRouter() + +templates = Jinja2Templates(directory="templates") def script_suggestions(locator_names): """Return a list of CeaScript objects that produce the output for each locator name""" import cea.scripts - plugins = current_app.cea_config.plugins + # TODO: Load plugins from config + plugins = [] schemas = cea.schemas.schemas(plugins=plugins) script_names = [] for name in locator_names: @@ -31,30 +29,46 @@ def script_suggestions(locator_names): return [cea.scripts.by_name(n, plugins=plugins) for n in sorted(set(script_names))] -def load_plot(dashboard, plot_index): +def load_plot(config, dashboard, plot_index): """Load a plot from the dashboard_yml""" - cea_config = current_app.cea_config - dashboards = cea.plots.read_dashboards(cea_config, current_app.plot_cache) + dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) dashboard = dashboards[dashboard] plot = dashboard.plots[plot_index] return plot -def render_missing_data(missing_files): - return render_template('missing_input_files.html', - missing_input_files=[lm(*args) for lm, args in missing_files], - script_suggestions=script_suggestions(lm.__name__ for lm, _ in missing_files)), 404 +def render_missing_data(request, missing_files): + return templates.TemplateResponse( + request=request, + name='missing_input_files.html', + context={ + "missing_input_files": [lm(*args) for lm, args in missing_files], + "script_suggestions": script_suggestions(lm.__name__ for lm, _ in missing_files) + } + ) + + +def render_plot(request, plot_div, plot_title): + return templates.TemplateResponse( + request=request, + name='plot.html', + context={ + "plot_div": plot_div, + "plot_title": plot_title + } + ) -@blueprint.route('/div//') -def route_div(dashboard_index, plot_index): + +@router.get('/div/{dashboard_index}/{plot_index}', response_class=HTMLResponse) +async def route_div(config: CEAConfig, request: Request, dashboard_index: int, plot_index: int): """Return the plot as a div to be used in an AJAX call""" - plot = load_plot(dashboard_index, plot_index) + plot = load_plot(config, dashboard_index, plot_index) try: plot_div = plot.plot_div() except MissingInputDataException: - return render_missing_data(plot.missing_input_files()) + return render_missing_data(request, plot.missing_input_files()) except NotImplementedError as e: - return make_response('

{message}

'.format(message=str(e)), 404) + return HTMLResponse(f'

{e}

', 404) # Remove parent
if exists due to plotly v4 if plot_div.startswith("
"): plot_div = plot_div[5:-5].strip() @@ -64,26 +78,25 @@ def route_div(dashboard_index, plot_index): div_id = re.match('
/') -def route_plot(dashboard_index, plot_index): - plot = load_plot(dashboard_index, plot_index) +@router.get('/plot/{dashboard_index}/{plot_index}', response_class=HTMLResponse) +async def route_plot(config: CEAConfig, request: Request, dashboard_index: int, plot_index: int): + plot = load_plot(config, dashboard_index, plot_index) plot_title = plot.title if 'scenario-name' in plot.parameters: plot_title += ' - {}'.format(plot.parameters['scenario-name']) try: plot_div = plot.plot_div() except MissingInputDataException: - return render_missing_data(plot.missing_input_files()) + return render_missing_data(request, plot.missing_input_files()) except NotImplementedError as e: - return make_response('

{message}

'.format(message=str(e)), 404) - return render_template('plot.html', plot_div=plot_div, plot_title=plot_title) - - -@blueprint.app_errorhandler(500) -def internal_error(error): - import traceback - error_trace = traceback.format_exc() - return error_trace, 500 + return HTMLResponse(f'

{e}

', 404) + return render_plot(request, plot_div, plot_title) + +# @blueprint.app_errorhandler(500) +# def internal_error(error): +# import traceback +# error_trace = traceback.format_exc() +# return error_trace, 500 diff --git a/cea/interfaces/dashboard/server/__init__.py b/cea/interfaces/dashboard/server/__init__.py index f9cb17abe7..2ef427befc 100644 --- a/cea/interfaces/dashboard/server/__init__.py +++ b/cea/interfaces/dashboard/server/__init__.py @@ -1,49 +1,29 @@ -""" -The /server api blueprint is used by cea-worker processes to manage jobs and files. -""" +from fastapi import APIRouter -from flask import Blueprint, current_app -from flask_restx import Api, Resource -from .jobs import api as jobs, worker_processes, kill_job -from .streams import api as streams +import cea.interfaces.dashboard.server.jobs as jobs +import cea.interfaces.dashboard.server.streams as streams -__author__ = "Daren Thomas" -__copyright__ = "Copyright 2019, Architecture and Building Systems - ETH Zurich" -__credits__ = ["Daren Thomas"] -__license__ = "MIT" -__version__ = "0.1" -__maintainer__ = "Daren Thomas" -__email__ = "cea@arch.ethz.ch" -__status__ = "Production" +router = APIRouter() -blueprint = Blueprint('server', __name__, url_prefix='/server') -api = Api(blueprint) - -# there might potentially be more namespaces added in the future, e.g. a method for locating files etc. -api.add_namespace(jobs, path='/jobs') -api.add_namespace(streams, path='/streams') +router.include_router(jobs.router, prefix='/jobs') +router.include_router(streams.router, prefix='/streams') def shutdown_worker_processes(): """When shutting down the flask server, make sure any subprocesses are also terminated. See issue #2408.""" - for jobid in worker_processes.keys(): - kill_job(jobid) - + for jobid in jobs.worker_processes.keys(): + jobs.kill_job(jobid) -def shutdown_server(): - print("Shutting down server...") - shutdown_worker_processes() - current_app.socketio.stop() +@router.get("/alive") +async def get_health_check(): + return {'success': True} -@api.route("/alive") -class ServerAlive(Resource): - def get(self): - return {'success': True} +@router.post("/shutdown") +async def shutdown(): + print("Shutting down server...") + shutdown_worker_processes() + # current_app.socketio.stop() -@api.route("/shutdown") -class ServerShutdown(Resource): - def post(self): - shutdown_server() - return {'message': 'Shutting down...'} + return {'message': 'Shutting down...'} diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index e592a573de..fce693dc66 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -1,27 +1,17 @@ """ jobs: maintain a list of jobs to be simulated. """ - import subprocess -from dataclasses import dataclass, asdict from datetime import datetime +from typing import Dict, Any import psutil +from fastapi import APIRouter +from pydantic import BaseModel -from flask_restx import Namespace, Resource, fields, reqparse -from flask import request, current_app - -__author__ = "Daren Thomas" -__copyright__ = "Copyright 2019, Architecture and Building Systems - ETH Zurich" -__credits__ = ["Daren Thomas"] -__license__ = "MIT" -__version__ = "0.1" -__maintainer__ = "Daren Thomas" -__email__ = "cea@arch.ethz.ch" -__status__ = "Production" +from cea.interfaces.dashboard.server.socketio import sio - -api = Namespace('Jobs', description='A job server for cea-worker processes') +router = APIRouter() # Job states JOB_STATE_PENDING = 0 @@ -30,39 +20,40 @@ JOB_STATE_ERROR = 3 JOB_STATE_CANCELED = 4 -job_info_model = api.model('JobInfo', { - 'id': fields.Integer, - 'script': fields.String, - 'state': fields.Integer, - 'error': fields.String, - 'parameters': fields.Raw, - 'start_time': fields.DateTime, - 'end_time': fields.DateTime, -}) - -job_info_request_parser = reqparse.RequestParser() -job_info_request_parser.add_argument("id", type=int, location="json") -job_info_request_parser.add_argument("script", type=str, required=True, location="json") -job_info_request_parser.add_argument("state", location="json") -job_info_request_parser.add_argument("error", location="json") -job_info_request_parser.add_argument("parameters", type=dict, location="json") +# job_info_model = api.model('JobInfo', { +# 'id': fields.Integer, +# 'script': fields.String, +# 'state': fields.Integer, +# 'error': fields.String, +# 'parameters': fields.Raw, +# 'start_time': fields.DateTime, +# 'end_time': fields.DateTime, +# }) +# +# job_info_request_parser = reqparse.RequestParser() +# job_info_request_parser.add_argument("id", type=int, location="json") +# job_info_request_parser.add_argument("script", type=str, required=True, location="json") +# job_info_request_parser.add_argument("state", location="json") +# job_info_request_parser.add_argument("error", location="json") +# job_info_request_parser.add_argument("parameters", type=dict, location="json") worker_processes = {} # jobid -> subprocess.Popen def next_id(): - """FIXME: replace with better solution""" + """ + FIXME: replace with better solution + """ try: - return max(jobs.keys()) + 1 + return str(len(jobs.keys()) + 1) except ValueError: # this is the first job... - return 1 + return str(1) # FIXME: replace with database or similar solution -@dataclass -class JobInfo: +class JobInfo(BaseModel): """Store all the information required to run a job""" id: str script: str @@ -78,93 +69,78 @@ class JobInfo: } -@api.route("/") -class Job(Resource): - @api.marshal_with(job_info_model) - def get(self, jobid): - """Return a JobInfo by id""" - return jobs[jobid] - - -@api.route("/new") -class NewJob(Resource): - @api.marshal_with(job_info_model) - def post(self): - """Post a new job to the list of jobs to complete""" - args = job_info_request_parser.parse_args() - print("NewJob: args={args}".format(**locals())) - job = JobInfo(id=next_id(), script=args.script, parameters=args.parameters) - jobs[job.id] = job - current_app.socketio.emit("cea-job-created", api.marshal(job, job_info_model)) - return job - - -@api.route("/list") -class ListJobs(Resource): - @api.marshal_with(job_info_model, as_list=True) - def get(self): - return [asdict(job) for job in jobs.values()] - - -@api.route("/started/") -class JobStarted(Resource): - @api.marshal_with(job_info_model) - def post(self, jobid): - job = jobs[jobid] - job.state = JOB_STATE_STARTED - job.start_time = datetime.now() - current_app.socketio.emit("cea-worker-started", api.marshal(job, job_info_model)) - return job - - -@api.route("/success/") -class JobSuccess(Resource): - @api.marshal_with(job_info_model) - def post(self, jobid): - job = jobs[jobid] - job.state = JOB_STATE_SUCCESS - job.error = None - job.end_time = datetime.now() - if job.id in worker_processes: - del worker_processes[job.id] - current_app.socketio.emit("cea-worker-success", api.marshal(job, job_info_model)) - return job - - -@api.route("/error/") -class JobError(Resource): - @api.marshal_with(job_info_model) - def post(self, jobid): - job = jobs[jobid] - job.state = JOB_STATE_ERROR - job.error = request.data.decode() - job.end_time = datetime.now() - if job.id in worker_processes: - del worker_processes[job.id] - current_app.socketio.emit("cea-worker-error", api.marshal(job, job_info_model)) - return job - - -@api.route('/start/') -class JobStart(Resource): - def post(self, jobid): - """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" - print("tools/route_start: {jobid}".format(**locals())) - worker_processes[jobid] = subprocess.Popen(["python", "-m", "cea.worker", "{jobid}".format(jobid=jobid)]) - return jobid - - -@api.route("/cancel/") -class JobCanceled(Resource): - @api.marshal_with(job_info_model) - def post(self, jobid): - job = jobs[jobid] - job.state = JOB_STATE_CANCELED - job.error = "Canceled by user" - job.end_time = datetime.now() - kill_job(jobid) - current_app.socketio.emit("cea-worker-canceled", api.marshal(job, job_info_model)) - return job +@router.get("/{job_id}") +async def get_job_info(job_id: str): + """Return a JobInfo by id""" + return jobs[job_id] + + +@router.post("/new") +async def create_new_job(payload: Dict[str, Any]): + """Post a new job to the list of jobs to complete""" + args = payload + print("NewJob: args={args}".format(**locals())) + job = JobInfo(id=next_id(), script=args["script"], parameters=args["parameters"]) + jobs[job.id] = job + await sio.emit("cea-job-created", job.model_dump(mode='json')) + return job + + +@router.get("/") +async def get_jobs(): + return [job.dict() for job in jobs.values()] + + +@router.post("/started/{job_id}") +async def set_job_started(job_id: str) -> JobInfo: + job = jobs[job_id] + job.state = JOB_STATE_STARTED + job.start_time = datetime.now() + await sio.emit("cea-worker-started", job.model_dump(mode='json')) + return job + + +@router.post("/success/{job_id}") +async def set_job_success(job_id: str) -> JobInfo: + job = jobs[job_id] + job.state = JOB_STATE_SUCCESS + job.error = None + job.end_time = datetime.now() + if job.id in worker_processes: + del worker_processes[job.id] + await sio.emit("cea-worker-success", job.model_dump(mode='json')) + return job + + +@router.post("/error/{job_id}") +async def set_job_error(job_id: str, error: str) -> JobInfo: + job = jobs[job_id] + job.state = JOB_STATE_ERROR + job.error = error + job.end_time = datetime.now() + if job.id in worker_processes: + del worker_processes[job.id] + await sio.emit("cea-worker-error", job.model_dump(mode='json')) + return job + + +@router.post('/start/{job_id}') +async def start_job(job_id: str): + """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" + print("tools/route_start: {job_id}".format(**locals())) + worker_processes[job_id] = subprocess.Popen(["python", "-m", "cea.worker", f"{job_id}"]) + return job_id + + +@router.post("/cancel/{job_id}") +async def cancel_job(job_id: str) -> JobInfo: + job = jobs[job_id] + job.state = JOB_STATE_CANCELED + job.error = "Canceled by user" + job.end_time = datetime.now() + kill_job(job_id) + await sio.emit("cea-worker-canceled", job.model_dump(mode='json')) + return job def kill_job(jobid): diff --git a/cea/interfaces/dashboard/server/socketio.py b/cea/interfaces/dashboard/server/socketio.py new file mode 100644 index 0000000000..8e5e0c1414 --- /dev/null +++ b/cea/interfaces/dashboard/server/socketio.py @@ -0,0 +1,4 @@ +import socketio + +sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins=[]) +socket_app = socketio.ASGIApp(sio) diff --git a/cea/interfaces/dashboard/server/streams.py b/cea/interfaces/dashboard/server/streams.py index 56e2018eb5..ace3716124 100644 --- a/cea/interfaces/dashboard/server/streams.py +++ b/cea/interfaces/dashboard/server/streams.py @@ -3,40 +3,32 @@ FIXME: when does this data get cleared? """ +from collections import defaultdict -from flask import request, current_app -from flask_restx import Namespace, Resource +from fastapi import APIRouter, Request -__author__ = "Daren Thomas" -__copyright__ = "Copyright 2019, Architecture and Building Systems - ETH Zurich" -__credits__ = ["Daren Thomas"] -__license__ = "MIT" -__version__ = "0.1" -__maintainer__ = "Daren Thomas" -__email__ = "cea@arch.ethz.ch" -__status__ = "Production" +from cea.interfaces.dashboard.server.socketio import sio -api = Namespace('Streams', description='A collection of output from cea-worker processes') +router = APIRouter() # map jobid to a list of messages -streams = {} +streams = defaultdict(list) -@api.route("/read/") -class ReadStream(Resource): - def get(self, jobid): - try: - return ''.join(streams[jobid]) - except KeyError: - return '' +@router.get("/read/{job_id}") +async def read_stream(job_id: str): + try: + return ''.join(streams[job_id]) + except KeyError: + return '' -@api.route("/write/") -class WriteStream(Resource): - def put(self, jobid): - msg = request.get_data(as_text=True) - streams.setdefault(jobid, []).append(msg) +@router.put("/write/{job_id}") +async def write_stream(job_id: str, request: Request): + body = await request.body() + message = body.decode("utf-8") - # emit the message using socket.io - current_app.socketio.emit('cea-worker-message', {"message": msg, "jobid": jobid}) - print("\n/server/streams/write/<{jobid}>: {msg}".format(**locals()), end='') + streams[job_id].append(message) + + # emit the message using socket.io + await sio.emit('cea-worker-message', {"message": message, "jobid": job_id}) diff --git a/cea/worker.py b/cea/worker.py index 2040e848ee..2e54057cd5 100644 --- a/cea/worker.py +++ b/cea/worker.py @@ -166,7 +166,7 @@ def main(config=None): def parse_arguments(default_url): import argparse parser = argparse.ArgumentParser() - parser.add_argument("jobid", type=int, help="Job id to run - use 0 to run the next job", default=0) + parser.add_argument("jobid", type=str, help="Job id to run - use 0 to run the next job", default=0) parser.add_argument("-u", "--url", type=str, help="URL of the CEA server api", default=default_url) args = parser.parse_args() return args diff --git a/conda-lock.yml b/conda-lock.yml index 91267c30c1..b008e9fdff 100644 --- a/conda-lock.yml +++ b/conda-lock.yml @@ -13,10 +13,10 @@ version: 1 metadata: content_hash: - linux-64: cfca13da07584c168d45aa0cc28bcc0cefe848a5c401b092704e231318aa114d - osx-arm64: 896861e218da113599ddcea5d0b602c47bd2e6573388a6b411a7c6cd7d87c14d - osx-64: c8a38a69691301caa8dac41a471a60932bb7bdf7c204a68d849a064c33abc79d - win-64: c896787db59651ec7d0923a9bdf8842d9d09cfd295af389f03cf1badb1396062 + linux-64: 19813f267c32b49385277fe02d0e011414ff9d7b357164dcd511594143ef0269 + osx-arm64: 791c61e3805445e0087ea1e716ff5a121943ec32d0fe87bb5a2d303c06bcab60 + osx-64: 7554236fa75e2a06989fbf8f819a6c200289c798925163e217068abe63857f33 + win-64: 38b1240ba23a7a2b5b33597a607c8a08e29897aa9f43b53acdab3c3210ac8e15 channels: - url: conda-forge used_env_vars: [] @@ -244,60 +244,60 @@ package: sha256: 2c0a618d0fa695e4e01a30e7ff31094be540c52e9085cbd724edb132c65cf9cd category: main optional: false -- name: aniso8601 - version: 9.0.1 +- name: annotated-types + version: 0.7.0 manager: conda platform: linux-64 dependencies: - python: '>=2.7' - python-dateutil: '' - url: https://conda.anaconda.org/conda-forge/noarch/aniso8601-9.0.1-pyhd8ed1ab_0.tar.bz2 + python: '>=3.7' + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda hash: - md5: 36fba1a639f2d24723c5480345b78553 - sha256: 201c040b6ee0045805a777f75f37a8648eb8dfd4725d62a4fcddc24d7d6c2a9f + md5: 7e9f4612544c8edbfd6afad17f1bd045 + sha256: 668f0825b6c18e4012ca24a0070562b6ec801ebc7008228a428eb52b4038873f category: main optional: false -- name: aniso8601 - version: 9.0.1 +- name: annotated-types + version: 0.7.0 manager: conda platform: osx-64 dependencies: - python-dateutil: '' - python: '>=2.7' - url: https://conda.anaconda.org/conda-forge/noarch/aniso8601-9.0.1-pyhd8ed1ab_0.tar.bz2 + python: '>=3.7' + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda hash: - md5: 36fba1a639f2d24723c5480345b78553 - sha256: 201c040b6ee0045805a777f75f37a8648eb8dfd4725d62a4fcddc24d7d6c2a9f + md5: 7e9f4612544c8edbfd6afad17f1bd045 + sha256: 668f0825b6c18e4012ca24a0070562b6ec801ebc7008228a428eb52b4038873f category: main optional: false -- name: aniso8601 - version: 9.0.1 +- name: annotated-types + version: 0.7.0 manager: conda platform: osx-arm64 dependencies: - python-dateutil: '' - python: '>=2.7' - url: https://conda.anaconda.org/conda-forge/noarch/aniso8601-9.0.1-pyhd8ed1ab_0.tar.bz2 + python: '>=3.7' + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda hash: - md5: 36fba1a639f2d24723c5480345b78553 - sha256: 201c040b6ee0045805a777f75f37a8648eb8dfd4725d62a4fcddc24d7d6c2a9f + md5: 7e9f4612544c8edbfd6afad17f1bd045 + sha256: 668f0825b6c18e4012ca24a0070562b6ec801ebc7008228a428eb52b4038873f category: main optional: false -- name: aniso8601 - version: 9.0.1 +- name: annotated-types + version: 0.7.0 manager: conda platform: win-64 dependencies: - python-dateutil: '' - python: '>=2.7' - url: https://conda.anaconda.org/conda-forge/noarch/aniso8601-9.0.1-pyhd8ed1ab_0.tar.bz2 + python: '>=3.7' + typing-extensions: '>=4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda hash: - md5: 36fba1a639f2d24723c5480345b78553 - sha256: 201c040b6ee0045805a777f75f37a8648eb8dfd4725d62a4fcddc24d7d6c2a9f + md5: 7e9f4612544c8edbfd6afad17f1bd045 + sha256: 668f0825b6c18e4012ca24a0070562b6ec801ebc7008228a428eb52b4038873f category: main optional: false - name: anyio - version: 4.3.0 + version: 4.4.0 manager: conda platform: linux-64 dependencies: @@ -306,14 +306,14 @@ package: python: '>=3.8' sniffio: '>=1.1' typing_extensions: '>=4.1' - url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda hash: - md5: ac95aa8ed65adfdde51132595c79aade - sha256: 86aca4a31c09f9b4dbdb332cd9a6a7dbab62ca734d3f832651c0ab59c6a7f52e + md5: 1fa97c6e8db1f82c64ff17a5efc4ae8e + sha256: 84ac9429812495f12939ab4994f2634f7cacd254f6234a0c2c0243daed15a7ee category: main optional: false - name: anyio - version: 4.3.0 + version: 4.4.0 manager: conda platform: osx-64 dependencies: @@ -322,10 +322,10 @@ package: typing_extensions: '>=4.1' idna: '>=2.8' exceptiongroup: '>=1.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda hash: - md5: ac95aa8ed65adfdde51132595c79aade - sha256: 86aca4a31c09f9b4dbdb332cd9a6a7dbab62ca734d3f832651c0ab59c6a7f52e + md5: 1fa97c6e8db1f82c64ff17a5efc4ae8e + sha256: 84ac9429812495f12939ab4994f2634f7cacd254f6234a0c2c0243daed15a7ee category: main optional: false - name: anyio @@ -345,7 +345,7 @@ package: category: main optional: false - name: anyio - version: 4.3.0 + version: 4.4.0 manager: conda platform: win-64 dependencies: @@ -354,10 +354,10 @@ package: typing_extensions: '>=4.1' idna: '>=2.8' exceptiongroup: '>=1.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda hash: - md5: ac95aa8ed65adfdde51132595c79aade - sha256: 86aca4a31c09f9b4dbdb332cd9a6a7dbab62ca734d3f832651c0ab59c6a7f52e + md5: 1fa97c6e8db1f82c64ff17a5efc4ae8e + sha256: 84ac9429812495f12939ab4994f2634f7cacd254f6234a0c2c0243daed15a7ee category: main optional: false - name: aom @@ -1566,7 +1566,7 @@ package: libcurl: '>=8.1.2,<9.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-hbc2ea52_17.conda hash: @@ -1584,7 +1584,7 @@ package: aws-crt-cpp: '>=0.20.3,<0.20.4.0a0' libcurl: '>=8.1.2,<9.0a0' libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/aws-sdk-cpp-1.10.57-h6c51782_17.conda hash: @@ -1602,7 +1602,7 @@ package: aws-crt-cpp: '>=0.20.3,<0.20.4.0a0' libcurl: '>=8.1.2,<9.0a0' libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.10.57-h6f3a27c_17.conda hash: @@ -1619,7 +1619,7 @@ package: aws-c-event-stream: '>=0.3.1,<0.3.2.0a0' aws-crt-cpp: '>=0.20.3,<0.20.4.0a0' libcurl: '>=8.1.2,<9.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -1898,54 +1898,6 @@ package: sha256: 845e77ef495376c5c3c328ccfd746ca0ef1978150cae8eae61a300fe7755fb08 category: main optional: false -- name: blinker - version: 1.8.2 - manager: conda - platform: linux-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.8.2-pyhd8ed1ab_0.conda - hash: - md5: cf85c002319c15e9721934104aaa1137 - sha256: 8ca3cd8f78d0607df28c9f76adb9800348f8f2dc8aa49d188a995a0acdc4477d - category: main - optional: false -- name: blinker - version: 1.8.2 - manager: conda - platform: osx-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.8.2-pyhd8ed1ab_0.conda - hash: - md5: cf85c002319c15e9721934104aaa1137 - sha256: 8ca3cd8f78d0607df28c9f76adb9800348f8f2dc8aa49d188a995a0acdc4477d - category: main - optional: false -- name: blinker - version: 1.8.2 - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.8.2-pyhd8ed1ab_0.conda - hash: - md5: cf85c002319c15e9721934104aaa1137 - sha256: 8ca3cd8f78d0607df28c9f76adb9800348f8f2dc8aa49d188a995a0acdc4477d - category: main - optional: false -- name: blinker - version: 1.8.2 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/blinker-1.8.2-pyhd8ed1ab_0.conda - hash: - md5: cf85c002319c15e9721934104aaa1137 - sha256: 8ca3cd8f78d0607df28c9f76adb9800348f8f2dc8aa49d188a995a0acdc4477d - category: main - optional: false - name: blosc version: 1.21.5 manager: conda @@ -1953,7 +1905,7 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -1969,7 +1921,7 @@ package: platform: osx-64 dependencies: libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -1985,7 +1937,7 @@ package: platform: osx-arm64 dependencies: libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -2000,7 +1952,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' ucrt: '>=10.0.20348.0' @@ -2022,7 +1974,7 @@ package: icu: '>=70.1,<71.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/boost-cpp-1.78.0-h5adbc97_2.conda @@ -2039,7 +1991,7 @@ package: bzip2: '>=1.0.8,<2.0a0' icu: '>=70.1,<71.0a0' libcxx: '>=12.0.1' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/boost-cpp-1.78.0-h31500c2_2.conda @@ -2056,7 +2008,7 @@ package: bzip2: '>=1.0.8,<2.0a0' icu: '>=70.1,<71.0a0' libcxx: '>=12.0.1' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/boost-cpp-1.78.0-hf1d6563_2.conda @@ -2071,7 +2023,7 @@ package: platform: win-64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' vc: '>=14.1,<15' vc14_runtime: '>=14.16.27033' zstd: '>=1.5.2,<1.6.0a0' @@ -2405,47 +2357,47 @@ package: category: main optional: false - name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: linux-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda hash: - md5: 2f4327a1cbe7f022401b236e915a5fef - sha256: 91d81bfecdbb142c15066df70cc952590ae8991670198f92c66b62019b251aeb + md5: 847c3c2905cc467cea52c24f9cfa8080 + sha256: 979af0932b2a5a26112044891a2d79e402e5ae8166f50fa48b8ebae47c0a2d65 category: main optional: false - name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: osx-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda hash: - md5: f2eacee8c33c43692f1ccfd33d0f50b1 - sha256: 54a794aedbb4796afeabdf54287b06b1d27f7b13b3814520925f4c2c80f58ca9 + md5: 3c23a8cab15ae51ebc9efdc229fccecf + sha256: ba0614477229fcb0f0666356f2c4686caa66f0ed1446e7c9666ce234abe2bacf category: main optional: false - name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: osx-arm64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda hash: - md5: fb416a1795f18dcc5a038bc2dc54edf9 - sha256: 49bc3439816ac72d0c0e0f144b8cc870fdcc4adec2e861407ec818d8116b2204 + md5: b534f104f102479402f88f73adf750f5 + sha256: f5fd189d48965df396d060eb48628cbd9f083f1a1ea79c5236f60d655c7b9633 category: main optional: false - name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda hash: - md5: 63da060240ab8087b60d1357051ea7d6 - sha256: 4d587088ecccd393fec3420b64f1af4ee1a0e6897a45cfd5ef38055322cea5d0 + md5: 12a3a2b3a00a21bbb390d4de5ad8dd0f + sha256: d872d11558ebeaeb87bcf9086e97c075a1a2dfffed2d0e97570cf197ab29e3d8 category: main optional: false - name: cached-property @@ -2557,7 +2509,7 @@ package: libglib: '>=2.72.1,<3.0a0' libpng: '>=1.6.38,<1.7.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' xorg-libice: '' xorg-libsm: '' @@ -2582,7 +2534,7 @@ package: icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' libpng: '>=1.6.38,<1.7.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' zlib: '>=1.2.12,<1.3.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.16.0-h904041c_1014.tar.bz2 @@ -2602,7 +2554,7 @@ package: icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' libpng: '>=1.6.38,<1.7.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' zlib: '>=1.2.12,<1.3.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.16.0-h73a0509_1014.tar.bz2 @@ -2618,67 +2570,66 @@ package: dependencies: fontconfig: '>=2.13.96,<3.0a0' fonts-conda-ecosystem: '' - freetype: '>=2.12.1,<3.0a0' + freetype: '>=2.10.4,<3.0a0' icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' - libpng: '>=1.6.38,<1.7.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libpng: '>=1.6.37,<1.7.0a0' + libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' - vc: '>=14.2,<15' - vs2015_runtime: '>=14.29.30139' - zlib: '>=1.2.12,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/win-64/cairo-1.16.0-hd694305_1014.tar.bz2 + vc: '>=14.1,<15' + vs2015_runtime: '>=14.16.27033' + url: https://conda.anaconda.org/conda-forge/win-64/cairo-1.16.0-h0ac17fb_1012.tar.bz2 hash: - md5: 91f08ed9ff25a969ddd06237454dae0d - sha256: 9f61fd45d0c9d27bd5e2bf4eeb3662d97691dc7d08b4007060776ce91f1a0d35 + md5: a1ca7ac59e74a41b71675f9293ae8dab + sha256: 1a9e8c5bdcd2b579bd89e0130540cd411a7e9e02115b1b05b3567d9ecfcc99b9 category: main optional: false - name: certifi - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: linux-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda hash: - md5: 0876280e409658fc6f9e75d035960333 - sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54 + md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a + sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 category: main optional: false - name: certifi - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: osx-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda hash: - md5: 0876280e409658fc6f9e75d035960333 - sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54 + md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a + sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 category: main optional: false - name: certifi - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda hash: - md5: 0876280e409658fc6f9e75d035960333 - sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54 + md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a + sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 category: main optional: false - name: certifi - version: 2024.2.2 + version: 2024.6.2 manager: conda platform: win-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda hash: - md5: 0876280e409658fc6f9e75d035960333 - sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54 + md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a + sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 category: main optional: false - name: cffi @@ -2754,7 +2705,7 @@ package: libgcc-ng: '>=12' libgfortran-ng: '' libgfortran5: '>=10.4.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.2.0-hd9d235c_0.conda hash: md5: 8c57a9adbafd87f5eff842abde599cb4 @@ -2770,7 +2721,7 @@ package: libcurl: '>=7.86.0,<9.0a0' libgfortran: 5.* libgfortran5: '>=11.3.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/cfitsio-4.2.0-hd56cc12_0.conda hash: md5: 28e03cefd79aa28ec0e313e5a9c71f5b @@ -2786,7 +2737,7 @@ package: libcurl: '>=7.86.0,<9.0a0' libgfortran: 5.* libgfortran5: '>=11.3.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.2.0-h2f961c4_0.conda hash: md5: 10112a8b1b7b479c7d4e87c9ade892eb @@ -2799,7 +2750,7 @@ package: platform: win-64 dependencies: libcurl: '>=7.86.0,<9.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -3150,7 +3101,7 @@ package: libcurl: 8.1.2 libgcc-ng: '>=12' libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/curl-8.1.2-h409715c_0.conda @@ -3167,7 +3118,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libcurl: 8.1.2 libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/curl-8.1.2-hbee3ae8_0.conda @@ -3184,7 +3135,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libcurl: 8.1.2 libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/curl-8.1.2-h912dcd9_0.conda @@ -3201,7 +3152,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libcurl: 8.1.2 libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -3288,10 +3239,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/cvxopt-1.3.2-py38hf2fec42_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/cvxopt-1.3.2-py38h58748b4_2.conda hash: - md5: dea3c8b30ebb3a623dc34c292de4701b - sha256: 01b3abd8f8fd3fd1f6a8a82ba1fd62e4e9c3b6fa2b81b5677012b2f59ca8ae08 + md5: ab62c4f9f1291a0139ec643aaddb95a8 + sha256: 694d5b6c3bcd2adec3baad68c45d73ce1bbba03b9d4164733d2b543bab836f86 category: main optional: false - name: cycler @@ -3380,10 +3331,10 @@ package: numpy: '>=1.22.4,<2.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/deap-1.4.1-py38h53bb729_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/deap-1.4.1-py38h495e488_2.conda hash: - md5: 9e8c89d6e1902c996822dee282d43812 - sha256: 0214ee104e7a42fe92ee9178a0538d25688a25e6fbf7c3181a3214a3bade0c18 + md5: 5c1d01aecdfe89f0b6a83c853c95d7ba + sha256: 63784e70ddd22b1f3ef3262110e48a0786a60ba4dc6f652ae48137b4e41f119c category: main optional: false - name: deap @@ -3391,14 +3342,15 @@ package: manager: conda platform: osx-64 dependencies: - libcxx: '>=15.0.7' + __osx: '>=10.13' + libcxx: '>=16' numpy: '>=1.22.4,<2.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/deap-1.4.1-py38h7626655_1.conda + url: https://conda.anaconda.org/conda-forge/osx-64/deap-1.4.1-py38h168d7cc_2.conda hash: - md5: 36f811075a8a5e37c1c91f6e127983fa - sha256: f3b3645a317ede1ec075ec727b3a1e4ec6cde55c12561fc1d206562d3f7e6f6b + md5: d9f851e48347b2f99a4a8314d82e7659 + sha256: cfc7abba5bb5b2948a50f7fab811178b4d852393f79294bc3caa69dac3b9057e category: main optional: false - name: deap @@ -3406,14 +3358,15 @@ package: manager: conda platform: osx-arm64 dependencies: - libcxx: '>=15.0.7' + __osx: '>=11.0' + libcxx: '>=16' numpy: '>=1.22.4,<2.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/deap-1.4.1-py38h181dcb6_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/deap-1.4.1-py38h0dc1a42_2.conda hash: - md5: 9c57c5912e416a80bfc41bca1327fae7 - sha256: f84407c56500605bc59c61c9c8049d96d1980c2c6e3f1414235545947d280f3a + md5: 45e63b45728bed4f50a86e1328a91a2d + sha256: fe729e9405e4566dd771cb9b3357073f8cf77dd64f1f07ba5168bd908d9b90b1 category: main optional: false - name: deap @@ -3427,10 +3380,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/deap-1.4.1-py38h0b70109_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/deap-1.4.1-py38hb7c6f16_2.conda hash: - md5: 8cfaf318a8d3e20b5acda1e7ab1be6f4 - sha256: 1bcfd3120cb517f890a360b54f0eecf30cd8576a038cbd4504436e5d40fe0e06 + md5: 72aca163ac7723b55685356b154c4eb7 + sha256: 1e2de5650d4a05a6e46df5fc10219e2236f7ef7a6aaf7c8c96716773b6bab4f6 category: main optional: false - name: debugpy @@ -3636,6 +3589,58 @@ package: sha256: 482b5b566ca559119b504c53df12b08f3962a5ef8e48061d62fd58a47f8f2ec4 category: main optional: false +- name: dnspython + version: 2.6.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8.0,<4.0.0' + sniffio: '' + url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda + hash: + md5: 936e6aadb75534384d11d982fab74b61 + sha256: 0d52c878553e569bccfbd96472c1659fb873bc05e95911b457d35982827626fe + category: main + optional: false +- name: dnspython + version: 2.6.1 + manager: conda + platform: osx-64 + dependencies: + sniffio: '' + python: '>=3.8.0,<4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda + hash: + md5: 936e6aadb75534384d11d982fab74b61 + sha256: 0d52c878553e569bccfbd96472c1659fb873bc05e95911b457d35982827626fe + category: main + optional: false +- name: dnspython + version: 2.6.1 + manager: conda + platform: osx-arm64 + dependencies: + sniffio: '' + python: '>=3.8.0,<4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda + hash: + md5: 936e6aadb75534384d11d982fab74b61 + sha256: 0d52c878553e569bccfbd96472c1659fb873bc05e95911b457d35982827626fe + category: main + optional: false +- name: dnspython + version: 2.6.1 + manager: conda + platform: win-64 + dependencies: + sniffio: '' + python: '>=3.8.0,<4.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda + hash: + md5: 936e6aadb75534384d11d982fab74b61 + sha256: 0d52c878553e569bccfbd96472c1659fb873bc05e95911b457d35982827626fe + category: main + optional: false - name: double-conversion version: 3.2.0 manager: conda @@ -3796,6 +3801,110 @@ package: sha256: 633a6a8db1f9a010cb0619f3446fb61f62dea348b09615ffae9744ab1001c24c category: main optional: false +- name: email-validator + version: 2.1.2 + manager: conda + platform: linux-64 + dependencies: + dnspython: '>=2.0.0' + idna: '>=2.0.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + hash: + md5: 2561eeb8ac8f67259ed898d77c7c97a1 + sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + category: main + optional: false +- name: email-validator + version: 2.1.2 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7' + idna: '>=2.0.0' + dnspython: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + hash: + md5: 2561eeb8ac8f67259ed898d77c7c97a1 + sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + category: main + optional: false +- name: email-validator + version: 2.1.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + idna: '>=2.0.0' + dnspython: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + hash: + md5: 2561eeb8ac8f67259ed898d77c7c97a1 + sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + category: main + optional: false +- name: email-validator + version: 2.1.2 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7' + idna: '>=2.0.0' + dnspython: '>=2.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + hash: + md5: 2561eeb8ac8f67259ed898d77c7c97a1 + sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + category: main + optional: false +- name: email_validator + version: 2.1.2 + manager: conda + platform: linux-64 + dependencies: + email-validator: '>=2.1.2,<2.1.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + hash: + md5: 0b6f091a3677f51ed4c24e346da25237 + sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + category: main + optional: false +- name: email_validator + version: 2.1.2 + manager: conda + platform: osx-64 + dependencies: + email-validator: '>=2.1.2,<2.1.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + hash: + md5: 0b6f091a3677f51ed4c24e346da25237 + sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + category: main + optional: false +- name: email_validator + version: 2.1.2 + manager: conda + platform: osx-arm64 + dependencies: + email-validator: '>=2.1.2,<2.1.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + hash: + md5: 0b6f091a3677f51ed4c24e346da25237 + sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + category: main + optional: false +- name: email_validator + version: 2.1.2 + manager: conda + platform: win-64 + dependencies: + email-validator: '>=2.1.2,<2.1.3.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + hash: + md5: 0b6f091a3677f51ed4c24e346da25237 + sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + category: main + optional: false - name: entrypoints version: '0.4' manager: conda @@ -4093,6 +4202,158 @@ package: sha256: f5a13d4bc591a4dc210954f492dd59a0ecf9b9d2ab28bf2ece755ca8f69ec1b4 category: main optional: false +- name: fastapi + version: 0.111.0 + manager: conda + platform: linux-64 + dependencies: + email_validator: '>=2.0.0' + fastapi-cli: '>=0.0.2' + httpx: '>=0.23.0' + jinja2: '>=2.11.2' + orjson: '>=3.2.1' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + python: '>=3.8' + python-multipart: '>=0.0.7' + starlette: '>=0.37.2,<0.38.0' + typing-extensions: '>=4.8.0' + ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + uvicorn: '>=0.12.0' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + hash: + md5: 7d347962e391cffc68f922c344f7cb3c + sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + category: main + optional: false +- name: fastapi + version: 0.111.0 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + httpx: '>=0.23.0' + python-multipart: '>=0.0.7' + typing-extensions: '>=4.8.0' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + starlette: '>=0.37.2,<0.38.0' + jinja2: '>=2.11.2' + uvicorn: '>=0.12.0' + email_validator: '>=2.0.0' + fastapi-cli: '>=0.0.2' + orjson: '>=3.2.1' + ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + hash: + md5: 7d347962e391cffc68f922c344f7cb3c + sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + category: main + optional: false +- name: fastapi + version: 0.111.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + httpx: '>=0.23.0' + python-multipart: '>=0.0.7' + typing-extensions: '>=4.8.0' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + starlette: '>=0.37.2,<0.38.0' + jinja2: '>=2.11.2' + uvicorn: '>=0.12.0' + email_validator: '>=2.0.0' + fastapi-cli: '>=0.0.2' + orjson: '>=3.2.1' + ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + hash: + md5: 7d347962e391cffc68f922c344f7cb3c + sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + category: main + optional: false +- name: fastapi + version: 0.111.0 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + httpx: '>=0.23.0' + python-multipart: '>=0.0.7' + typing-extensions: '>=4.8.0' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + starlette: '>=0.37.2,<0.38.0' + jinja2: '>=2.11.2' + uvicorn: '>=0.12.0' + email_validator: '>=2.0.0' + fastapi-cli: '>=0.0.2' + orjson: '>=3.2.1' + ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + hash: + md5: 7d347962e391cffc68f922c344f7cb3c + sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + category: main + optional: false +- name: fastapi-cli + version: 0.0.4 + manager: conda + platform: linux-64 + dependencies: + fastapi: '' + python: '>=3.8' + typer: '>=0.12.3' + uvicorn: '>=0.15.0' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + hash: + md5: 2581ef67574e5b5400c0c151cc1c8b15 + sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + category: main + optional: false +- name: fastapi-cli + version: 0.0.4 + manager: conda + platform: osx-64 + dependencies: + fastapi: '' + python: '>=3.8' + uvicorn: '>=0.15.0' + typer: '>=0.12.3' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + hash: + md5: 2581ef67574e5b5400c0c151cc1c8b15 + sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + category: main + optional: false +- name: fastapi-cli + version: 0.0.4 + manager: conda + platform: osx-arm64 + dependencies: + fastapi: '' + python: '>=3.8' + uvicorn: '>=0.15.0' + typer: '>=0.12.3' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + hash: + md5: 2581ef67574e5b5400c0c151cc1c8b15 + sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + category: main + optional: false +- name: fastapi-cli + version: 0.0.4 + manager: conda + platform: win-64 + dependencies: + fastapi: '' + python: '>=3.8' + uvicorn: '>=0.15.0' + typer: '>=0.12.3' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + hash: + md5: 2581ef67574e5b5400c0c151cc1c8b15 + sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + category: main + optional: false - name: ffmpeg version: 5.1.2 manager: conda @@ -4112,7 +4373,7 @@ package: libva: '>=2.17.0,<3.0a0' libvpx: '>=1.11.0,<1.12.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openh264: '>=2.3.1,<2.3.2.0a0' svt-av1: '>=1.4.1,<1.4.2.0a0' x264: '>=1!164.3095,<1!165' @@ -4141,7 +4402,7 @@ package: libopus: '>=1.3.1,<2.0a0' libvpx: '>=1.11.0,<1.12.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openh264: '>=2.3.1,<2.3.2.0a0' svt-av1: '>=1.4.1,<1.4.2.0a0' x264: '>=1!164.3095,<1!165' @@ -4170,7 +4431,7 @@ package: libopus: '>=1.3.1,<2.0a0' libvpx: '>=1.11.0,<1.12.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openh264: '>=2.3.1,<2.3.2.0a0' svt-av1: '>=1.4.1,<1.4.2.0a0' x264: '>=1!164.3095,<1!165' @@ -4194,7 +4455,7 @@ package: freetype: '>=2.12.1,<3.0a0' libopus: '>=1.3.1,<2.0a0' libxml2: '>=2.11.5,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openh264: '>=2.3.1,<2.3.2.0a0' svt-av1: '>=1.4.1,<1.4.2.0a0' ucrt: '>=10.0.20348.0' @@ -4215,12 +4476,12 @@ package: dependencies: libgcc-ng: '>=12' libgfortran-ng: '' - libgfortran5: '>=11.4.0' + libgfortran5: '>=12.3.0' libstdcxx-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hc118613_108.conda + url: https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hf1063bd_110.conda hash: - md5: 6fa90698000b05dfe8ce6515794fe71a - sha256: 1952dbb3c40931fc4608e053e32cbebbdcd8f3ea5b6a050156df6dd66ad64912 + md5: ee3e687b78b778db7b304e5b00a4dca6 + sha256: 3cc58c9d9a8cc0089e3839ae5ff7ba4ddfc6df99d5f6a147fe90ea963bc6fe45 category: main optional: false - name: fftw @@ -4228,14 +4489,15 @@ package: manager: conda platform: osx-64 dependencies: - libcxx: '>=14.0.6' + __osx: '>=10.13' + libcxx: '>=16' libgfortran: 5.* - libgfortran5: '>=12.2.0' - llvm-openmp: '>=14.0.6' - url: https://conda.anaconda.org/conda-forge/osx-64/fftw-3.3.10-nompi_h4fa670e_108.conda + libgfortran5: '>=13.2.0' + llvm-openmp: '>=16.0.6' + url: https://conda.anaconda.org/conda-forge/osx-64/fftw-3.3.10-nompi_h292e606_110.conda hash: - md5: 39132ce6ed3180b42b54d40289cd4157 - sha256: c24ff84b51c148eb1a77e39a54afaad14d86700b75ccab964721ac9691cead93 + md5: e05219cbabb20b406ff0803a3e552419 + sha256: 6f5c64debf2d51f10522d4080b043ec4dc9825a770a4d38c96fa7bf6432b4769 category: main optional: false - name: fftw @@ -4243,14 +4505,15 @@ package: manager: conda platform: osx-arm64 dependencies: - libcxx: '>=14.0.6' + __osx: '>=11.0' + libcxx: '>=16' libgfortran: 5.* - libgfortran5: '>=12.2.0' - llvm-openmp: '>=14.0.6' - url: https://conda.anaconda.org/conda-forge/osx-arm64/fftw-3.3.10-nompi_h3046061_108.conda + libgfortran5: '>=13.2.0' + llvm-openmp: '>=16.0.6' + url: https://conda.anaconda.org/conda-forge/osx-arm64/fftw-3.3.10-nompi_h6637ab6_110.conda hash: - md5: 8b7ac9f19a96f724398017337ff81765 - sha256: eb6afbdbcc8d0da38791f85e3146460b77350ecbdea321168931345647b328d5 + md5: 622f99e8f4820c2ca1b208a3bb6ed5e6 + sha256: ba72f1d9384584c774d4e58ff3174818a20687f817e5edde3e0d23edff88fd72 category: main optional: false - name: fftw @@ -4261,10 +4524,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/fftw-3.3.10-nompi_h38027f0_108.conda + url: https://conda.anaconda.org/conda-forge/win-64/fftw-3.3.10-nompi_h89e6982_110.conda hash: - md5: 09196a7ba69b70d2124aff7b2763035d - sha256: 8db6330c5e1a2da62dd6090750f88f303af95ad151b961f69d83be8cd53e8ada + md5: c1c00a097000feb485afb2e9fa7368fc + sha256: 57b721b6532be4efbd8ba5877126e9d4d26bcff28da9e9689f5801ec528d4ba0 category: main optional: false - name: fiona @@ -4370,346 +4633,94 @@ package: sha256: 6273d55aa255efc332d5d79c5a1aeefa7d3913a6faa8d26eb304cf83fb17d148 category: main optional: false -- name: flask - version: 2.3.3 +- name: folium + version: 0.17.0 manager: conda platform: linux-64 dependencies: - blinker: '>=1.6.2' - click: '>=8.1.3' - importlib-metadata: '>=3.6.0' - itsdangerous: '>=2.1.2' - jinja2: '>=3.1.2' + branca: '>=0.6.0' + jinja2: '>=2.9' + numpy: '' python: '>=3.8' - werkzeug: '>=2.3.7' - url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + requests: '' + xyzservices: '' + url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: - md5: 9b0d29067484a8dfacfae85b8fba81bc - sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + md5: 9b96a3e6e0473b5722fa4fbefcefcded + sha256: d5c4153cad0154112daf0db648afe82ad7930523e2cb9f7379bb2d148fac0537 category: main optional: false -- name: flask - version: 2.3.3 +- name: folium + version: 0.17.0 manager: conda platform: osx-64 dependencies: + numpy: '' + requests: '' + xyzservices: '' python: '>=3.8' - jinja2: '>=3.1.2' - click: '>=8.1.3' - importlib-metadata: '>=3.6.0' - itsdangerous: '>=2.1.2' - blinker: '>=1.6.2' - werkzeug: '>=2.3.7' - url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + jinja2: '>=2.9' + branca: '>=0.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: - md5: 9b0d29067484a8dfacfae85b8fba81bc - sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + md5: 9b96a3e6e0473b5722fa4fbefcefcded + sha256: d5c4153cad0154112daf0db648afe82ad7930523e2cb9f7379bb2d148fac0537 category: main optional: false -- name: flask - version: 2.3.3 +- name: folium + version: 0.17.0 manager: conda platform: osx-arm64 dependencies: + numpy: '' + requests: '' + xyzservices: '' python: '>=3.8' - jinja2: '>=3.1.2' - click: '>=8.1.3' - importlib-metadata: '>=3.6.0' - itsdangerous: '>=2.1.2' - blinker: '>=1.6.2' - werkzeug: '>=2.3.7' - url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + jinja2: '>=2.9' + branca: '>=0.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: - md5: 9b0d29067484a8dfacfae85b8fba81bc - sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + md5: 9b96a3e6e0473b5722fa4fbefcefcded + sha256: d5c4153cad0154112daf0db648afe82ad7930523e2cb9f7379bb2d148fac0537 category: main optional: false -- name: flask - version: 2.3.3 +- name: folium + version: 0.17.0 manager: conda platform: win-64 dependencies: + numpy: '' + requests: '' + xyzservices: '' python: '>=3.8' - jinja2: '>=3.1.2' - click: '>=8.1.3' - importlib-metadata: '>=3.6.0' - itsdangerous: '>=2.1.2' - blinker: '>=1.6.2' - werkzeug: '>=2.3.7' - url: https://conda.anaconda.org/conda-forge/noarch/flask-2.3.3-pyhd8ed1ab_0.conda + jinja2: '>=2.9' + branca: '>=0.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: - md5: 9b0d29067484a8dfacfae85b8fba81bc - sha256: 4f84ffdc5471236e8225db86c7508426b46aa2c3802d58ca40b3c3e174533b39 + md5: 9b96a3e6e0473b5722fa4fbefcefcded + sha256: d5c4153cad0154112daf0db648afe82ad7930523e2cb9f7379bb2d148fac0537 category: main optional: false -- name: flask-cors - version: 4.0.0 +- name: font-ttf-dejavu-sans-mono + version: '2.37' manager: conda platform: linux-64 - dependencies: - flask: '>=0.9' - python: '>=3.6' - six: '' - url: https://conda.anaconda.org/conda-forge/noarch/flask-cors-4.0.0-pyhd8ed1ab_0.conda + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 hash: - md5: 3dc2a99c1c76e3f4307ebaebfda0af4a - sha256: bc23c15ab33e10f931b03e4f2812d30491c27e09ea6e6441c67ee2ed523ee06b + md5: 0c96522c6bdaed4b1566d11387caaf45 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b category: main optional: false -- name: flask-cors - version: 4.0.0 +- name: font-ttf-dejavu-sans-mono + version: '2.37' manager: conda platform: osx-64 - dependencies: - six: '' - python: '>=3.6' - flask: '>=0.9' - url: https://conda.anaconda.org/conda-forge/noarch/flask-cors-4.0.0-pyhd8ed1ab_0.conda + dependencies: {} + url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 hash: - md5: 3dc2a99c1c76e3f4307ebaebfda0af4a - sha256: bc23c15ab33e10f931b03e4f2812d30491c27e09ea6e6441c67ee2ed523ee06b - category: main - optional: false -- name: flask-cors - version: 4.0.0 - manager: conda - platform: osx-arm64 - dependencies: - six: '' - python: '>=3.6' - flask: '>=0.9' - url: https://conda.anaconda.org/conda-forge/noarch/flask-cors-4.0.0-pyhd8ed1ab_0.conda - hash: - md5: 3dc2a99c1c76e3f4307ebaebfda0af4a - sha256: bc23c15ab33e10f931b03e4f2812d30491c27e09ea6e6441c67ee2ed523ee06b - category: main - optional: false -- name: flask-cors - version: 4.0.0 - manager: conda - platform: win-64 - dependencies: - six: '' - python: '>=3.6' - flask: '>=0.9' - url: https://conda.anaconda.org/conda-forge/noarch/flask-cors-4.0.0-pyhd8ed1ab_0.conda - hash: - md5: 3dc2a99c1c76e3f4307ebaebfda0af4a - sha256: bc23c15ab33e10f931b03e4f2812d30491c27e09ea6e6441c67ee2ed523ee06b - category: main - optional: false -- name: flask-restx - version: 1.3.0 - manager: conda - platform: linux-64 - dependencies: - aniso8601: '>=0.82' - flask: '>=0.8,!=2.0.0,<3' - jsonschema: <=4.17.3 - python: '>=3.8' - pytz: '' - werkzeug: '!=2.0.0,<3' - url: https://conda.anaconda.org/conda-forge/noarch/flask-restx-1.3.0-pyhd8ed1ab_0.conda - hash: - md5: ec1a7ca3344d197b7a0a906e2cc4d2f0 - sha256: a33bc9439ecf76d0d02e09c270c9636aea5e7d111a3ec154009242c688fa1cc4 - category: main - optional: false -- name: flask-restx - version: 1.3.0 - manager: conda - platform: osx-64 - dependencies: - pytz: '' - python: '>=3.8' - aniso8601: '>=0.82' - flask: '>=0.8,!=2.0.0,<3' - jsonschema: <=4.17.3 - werkzeug: '!=2.0.0,<3' - url: https://conda.anaconda.org/conda-forge/noarch/flask-restx-1.3.0-pyhd8ed1ab_0.conda - hash: - md5: ec1a7ca3344d197b7a0a906e2cc4d2f0 - sha256: a33bc9439ecf76d0d02e09c270c9636aea5e7d111a3ec154009242c688fa1cc4 - category: main - optional: false -- name: flask-restx - version: 1.3.0 - manager: conda - platform: osx-arm64 - dependencies: - pytz: '' - python: '>=3.8' - aniso8601: '>=0.82' - flask: '>=0.8,!=2.0.0,<3' - jsonschema: <=4.17.3 - werkzeug: '!=2.0.0,<3' - url: https://conda.anaconda.org/conda-forge/noarch/flask-restx-1.3.0-pyhd8ed1ab_0.conda - hash: - md5: ec1a7ca3344d197b7a0a906e2cc4d2f0 - sha256: a33bc9439ecf76d0d02e09c270c9636aea5e7d111a3ec154009242c688fa1cc4 - category: main - optional: false -- name: flask-restx - version: 1.3.0 - manager: conda - platform: win-64 - dependencies: - pytz: '' - python: '>=3.8' - aniso8601: '>=0.82' - flask: '>=0.8,!=2.0.0,<3' - jsonschema: <=4.17.3 - werkzeug: '!=2.0.0,<3' - url: https://conda.anaconda.org/conda-forge/noarch/flask-restx-1.3.0-pyhd8ed1ab_0.conda - hash: - md5: ec1a7ca3344d197b7a0a906e2cc4d2f0 - sha256: a33bc9439ecf76d0d02e09c270c9636aea5e7d111a3ec154009242c688fa1cc4 - category: main - optional: false -- name: flask-socketio - version: 5.3.6 - manager: conda - platform: linux-64 - dependencies: - flask: '>=0.9' - python: '>=3.6' - python-socketio: '>=5.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/flask-socketio-5.3.6-pyhd8ed1ab_0.conda - hash: - md5: ef521fc208ad82733c942d150199cf3e - sha256: f641731d0fa6c26db6dcd3cf1c39a5c27d0e692604ac3927c68a74b2a60fa175 - category: main - optional: false -- name: flask-socketio - version: 5.3.6 - manager: conda - platform: osx-64 - dependencies: - python: '>=3.6' - flask: '>=0.9' - python-socketio: '>=5.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/flask-socketio-5.3.6-pyhd8ed1ab_0.conda - hash: - md5: ef521fc208ad82733c942d150199cf3e - sha256: f641731d0fa6c26db6dcd3cf1c39a5c27d0e692604ac3927c68a74b2a60fa175 - category: main - optional: false -- name: flask-socketio - version: 5.3.6 - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.6' - flask: '>=0.9' - python-socketio: '>=5.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/flask-socketio-5.3.6-pyhd8ed1ab_0.conda - hash: - md5: ef521fc208ad82733c942d150199cf3e - sha256: f641731d0fa6c26db6dcd3cf1c39a5c27d0e692604ac3927c68a74b2a60fa175 - category: main - optional: false -- name: flask-socketio - version: 5.3.6 - manager: conda - platform: win-64 - dependencies: - python: '>=3.6' - flask: '>=0.9' - python-socketio: '>=5.0.2' - url: https://conda.anaconda.org/conda-forge/noarch/flask-socketio-5.3.6-pyhd8ed1ab_0.conda - hash: - md5: ef521fc208ad82733c942d150199cf3e - sha256: f641731d0fa6c26db6dcd3cf1c39a5c27d0e692604ac3927c68a74b2a60fa175 - category: main - optional: false -- name: folium - version: 0.16.0 - manager: conda - platform: linux-64 - dependencies: - branca: '>=0.6.0' - jinja2: '>=2.9' - numpy: '' - python: '>=3.7' - requests: '' - xyzservices: '' - url: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda - hash: - md5: cb1d2aa705a5b1f0fbdabd1beebce205 - sha256: 9696ffafd873a40815312e9ea245a863b7796b73dd2759f93174cd65d6bf2144 - category: main - optional: false -- name: folium - version: 0.16.0 - manager: conda - platform: osx-64 - dependencies: - numpy: '' - requests: '' - xyzservices: '' - python: '>=3.7' - jinja2: '>=2.9' - branca: '>=0.6.0' - url: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda - hash: - md5: cb1d2aa705a5b1f0fbdabd1beebce205 - sha256: 9696ffafd873a40815312e9ea245a863b7796b73dd2759f93174cd65d6bf2144 - category: main - optional: false -- name: folium - version: 0.16.0 - manager: conda - platform: osx-arm64 - dependencies: - numpy: '' - requests: '' - xyzservices: '' - python: '>=3.7' - jinja2: '>=2.9' - branca: '>=0.6.0' - url: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda - hash: - md5: cb1d2aa705a5b1f0fbdabd1beebce205 - sha256: 9696ffafd873a40815312e9ea245a863b7796b73dd2759f93174cd65d6bf2144 - category: main - optional: false -- name: folium - version: 0.16.0 - manager: conda - platform: win-64 - dependencies: - numpy: '' - requests: '' - xyzservices: '' - python: '>=3.7' - jinja2: '>=2.9' - branca: '>=0.6.0' - url: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda - hash: - md5: cb1d2aa705a5b1f0fbdabd1beebce205 - sha256: 9696ffafd873a40815312e9ea245a863b7796b73dd2759f93174cd65d6bf2144 - category: main - optional: false -- name: font-ttf-dejavu-sans-mono - version: '2.37' - manager: conda - platform: linux-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - hash: - md5: 0c96522c6bdaed4b1566d11387caaf45 - sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b - category: main - optional: false -- name: font-ttf-dejavu-sans-mono - version: '2.37' - manager: conda - platform: osx-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - hash: - md5: 0c96522c6bdaed4b1566d11387caaf45 - sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + md5: 0c96522c6bdaed4b1566d11387caaf45 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b category: main optional: false - name: font-ttf-dejavu-sans-mono @@ -4875,7 +4886,7 @@ package: freetype: '>=2.12.1,<3.0a0' libgcc-ng: '>=12' libuuid: '>=2.32.1,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda hash: md5: 0f69b688f52ff6da70bccb7ff7001d1d @@ -4889,7 +4900,7 @@ package: dependencies: expat: '>=2.5.0,<3.0a0' freetype: '>=2.12.1,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.14.2-h5bb23bf_0.conda hash: md5: 86cc5867dfbee4178118392bae4a3c89 @@ -4903,7 +4914,7 @@ package: dependencies: expat: '>=2.5.0,<3.0a0' freetype: '>=2.12.1,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda hash: md5: f77d47ddb6d3cc5b39b9bdf65635afbb @@ -4918,7 +4929,7 @@ package: expat: '>=2.5.0,<3.0a0' freetype: '>=2.12.1,<3.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -5037,7 +5048,7 @@ package: category: main optional: false - name: fonttools - version: 4.51.0 + version: 4.53.0 manager: conda platform: linux-64 dependencies: @@ -5047,46 +5058,48 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.51.0-py38h01eb140_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.0-py38hfb59056_0.conda hash: - md5: f285ccf73f9e81de1acc5aa2e5c0b154 - sha256: cefd45bc15feabc8a598e40bc08bc019a1cf5037b25c2076f920636399e984eb + md5: 521c0726875843ca5c7224c6134c1750 + sha256: c8de15a92018b1fc9a1b3da1467736f0a97a4b06e555f309672b4141de50758f category: main optional: false - name: fonttools - version: 4.51.0 + version: 4.53.0 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' brotli: '' munkres: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.51.0-py38hae2e43d_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.0-py38hc718529_0.conda hash: - md5: fcf081549579a55b0af4f8be384ac651 - sha256: c3903c33cd20f211c659d1be2c9c2269c616dc270006fcd0f012f117c2b1e000 + md5: ee68cefbf0ea3272d8161ed391cae81c + sha256: 71d61b872cee2f80c4f439b653a330814962ef6802f73b68ba1f0d6852c4e287 category: main optional: false - name: fonttools - version: 4.51.0 + version: 4.53.0 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' brotli: '' munkres: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.51.0-py38h336bac9_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.0-py38h3237794_0.conda hash: - md5: 97b0111773ec93960b58dfef11d8c2a6 - sha256: f8366d2ce04279b85a99c4ec9b388062ae5f3accd357f46e89b0f4a9a9cd6be7 + md5: 73832ed97fd30d0d7ca00128e386511c + sha256: 20bda6d44636e9a2263c199d690d8d18fad57b9ad1c9f1b3292f30c5b65cf38c category: main optional: false - name: fonttools - version: 4.51.0 + version: 4.53.0 manager: conda platform: win-64 dependencies: @@ -5098,10 +5111,10 @@ package: unicodedata2: '>=14.0.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.51.0-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.0-py38h4cb3324_0.conda hash: - md5: cfcb2080ff4dca7adb1e469b66a49e58 - sha256: cecf732722dd8c4dff70660fe2cf1d318c703aefba2f49097cdb510f74affe85 + md5: 1f605daf43f19302f8e347f3fce32b98 + sha256: bbe1e465ba56da6dea5e391a4c7f000b45547781b5d8701bebdf510c54ee122b category: main optional: false - name: fqdn @@ -5170,7 +5183,7 @@ package: libstdcxx-ng: '>=12' libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openexr: '>=3.1.5,<3.2.0a0' openjpeg: '>=2.5.0,<3.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/freeimage-3.18.0-hca5c823_12.conda @@ -5192,7 +5205,7 @@ package: libraw: '>=0.21.1,<0.22.0a0' libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openexr: '>=3.1.5,<3.2.0a0' openjpeg: '>=2.5.0,<3.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/freeimage-3.18.0-h4fbe5d5_12.conda @@ -5214,7 +5227,7 @@ package: libraw: '>=0.21.1,<0.22.0a0' libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openexr: '>=3.1.5,<3.2.0a0' openjpeg: '>=2.5.0,<3.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/freeimage-3.18.0-ha6e172d_12.conda @@ -5235,7 +5248,7 @@ package: libraw: '>=0.21.1,<0.22.0a0' libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openexr: '>=3.1.5,<3.2.0a0' openjpeg: '>=2.5.0,<3.0a0' ucrt: '>=10.0.20348.0' @@ -5254,7 +5267,7 @@ package: dependencies: libgcc-ng: '>=12' libpng: '>=1.6.39,<1.7.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda hash: md5: 9ae35c3d96db2c94ce0cef86efdfa2cb @@ -5267,7 +5280,7 @@ package: platform: osx-64 dependencies: libpng: '>=1.6.39,<1.7.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/freetype-2.12.1-h60636b9_2.conda hash: md5: 25152fce119320c980e5470e64834b50 @@ -5280,7 +5293,7 @@ package: platform: osx-arm64 dependencies: libpng: '>=1.6.39,<1.7.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda hash: md5: e6085e516a3e304ce41a8ee08b9b89ad @@ -5293,7 +5306,7 @@ package: platform: win-64 dependencies: libpng: '>=1.6.39,<1.7.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -5682,7 +5695,7 @@ package: libgcc-ng: '>=12' libstdcxx-ng: '>=12' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/linux-64/geotiff-1.7.1-h7a142b4_6.conda @@ -5699,7 +5712,7 @@ package: jpeg: '>=9e,<10a' libcxx: '>=14.0.6' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-64/geotiff-1.7.1-hd690177_6.conda @@ -5716,7 +5729,7 @@ package: jpeg: '>=9e,<10a' libcxx: '>=14.0.6' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-arm64/geotiff-1.7.1-hdcdc974_6.conda @@ -5732,7 +5745,7 @@ package: dependencies: jpeg: '>=9e,<10a' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -5875,143 +5888,6 @@ package: sha256: e3621dc3d48399c89bf0dd512a6a398d354429b3b84219473d674aa56e0feef2 category: main optional: false -- name: gevent - version: 22.10.2 - manager: conda - platform: linux-64 - dependencies: - c-ares: '>=1.18.1,<2.0a0' - cffi: '>=1.11.5' - greenlet: '>=2.0.0' - libev: '>=4.33,<4.34.0a0' - libgcc-ng: '>=12' - libuv: '>=1.44.2,<2.0a0' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - zope.event: '' - zope.interface: '' - url: https://conda.anaconda.org/conda-forge/linux-64/gevent-22.10.2-py38h0fd6f59_0.tar.bz2 - hash: - md5: 336decf8d44e69ea415fc6880d8c8f12 - sha256: 7779b4b17a2fe38f3f42ba7cef800fe5c4e882a26dc3a5d43c0eecad4be2b3ef - category: main - optional: false -- name: gevent - version: 22.10.2 - manager: conda - platform: osx-64 - dependencies: - c-ares: '>=1.18.1,<2.0a0' - cffi: '>=1.11.5' - greenlet: '>=2.0.0' - libev: '>=4.33,<4.34.0a0' - libuv: '>=1.44.2,<2.0a0' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - zope.event: '' - zope.interface: '' - url: https://conda.anaconda.org/conda-forge/osx-64/gevent-22.10.2-py38h417038f_0.tar.bz2 - hash: - md5: eae32a6b4cb34afcc60bd2f947e706e7 - sha256: a7327d0c671297606e330706f20c76c840ea3eb0af2e64ded2ca1ee11b4d08e6 - category: main - optional: false -- name: gevent - version: 22.10.2 - manager: conda - platform: osx-arm64 - dependencies: - c-ares: '>=1.18.1,<2.0a0' - cffi: '>=1.11.5' - greenlet: '>=2.0.0' - libev: '>=4.33,<4.34.0a0' - libuv: '>=1.44.2,<2.0a0' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - zope.event: '' - zope.interface: '' - url: https://conda.anaconda.org/conda-forge/osx-arm64/gevent-22.10.2-py38h4163cb6_0.tar.bz2 - hash: - md5: 08da3adb6758d415c757b4441a782b7f - sha256: c313cca4fa9f1ba46c13afdb1e911b6d1c08f3e0b15ad9afece068d3f1d0e84d - category: main - optional: false -- name: gevent - version: 23.9.0.post1 - manager: conda - platform: win-64 - dependencies: - cffi: '>=1.11.5' - greenlet: '>=2.0.0' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - zope.event: '' - zope.interface: '' - url: https://conda.anaconda.org/conda-forge/win-64/gevent-23.9.0.post1-py38h91455d4_1.conda - hash: - md5: 7ec5e9dea283470bb165c9c9227baab1 - sha256: e979cfbab3176c3f64f376723b242808b94a7d0d3d0c2e37a2f81e640cf97aaa - category: main - optional: false -- name: gevent-websocket - version: 0.10.1 - manager: conda - platform: linux-64 - dependencies: - gevent: '' - python: '' - url: https://conda.anaconda.org/conda-forge/noarch/gevent-websocket-0.10.1-py_0.tar.bz2 - hash: - md5: 25b4b60b6ea50368cd90b75b4d00c711 - sha256: 4d8edcacf879eaa3be559c08dd6916907270701ced18f290fba622f992d00c07 - category: main - optional: false -- name: gevent-websocket - version: 0.10.1 - manager: conda - platform: osx-64 - dependencies: - python: '' - gevent: '' - url: https://conda.anaconda.org/conda-forge/noarch/gevent-websocket-0.10.1-py_0.tar.bz2 - hash: - md5: 25b4b60b6ea50368cd90b75b4d00c711 - sha256: 4d8edcacf879eaa3be559c08dd6916907270701ced18f290fba622f992d00c07 - category: main - optional: false -- name: gevent-websocket - version: 0.10.1 - manager: conda - platform: osx-arm64 - dependencies: - python: '' - gevent: '' - url: https://conda.anaconda.org/conda-forge/noarch/gevent-websocket-0.10.1-py_0.tar.bz2 - hash: - md5: 25b4b60b6ea50368cd90b75b4d00c711 - sha256: 4d8edcacf879eaa3be559c08dd6916907270701ced18f290fba622f992d00c07 - category: main - optional: false -- name: gevent-websocket - version: 0.10.1 - manager: conda - platform: win-64 - dependencies: - python: '' - gevent: '' - url: https://conda.anaconda.org/conda-forge/noarch/gevent-websocket-0.10.1-py_0.tar.bz2 - hash: - md5: 25b4b60b6ea50368cd90b75b4d00c711 - sha256: 4d8edcacf879eaa3be559c08dd6916907270701ced18f290fba622f992d00c07 - category: main - optional: false - name: gflags version: 2.2.2 manager: conda @@ -6093,7 +5969,7 @@ package: libexpat: '>=2.5.0,<3.0a0' libgcc-ng: '>=12' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' pcre2: '>=10.40,<10.41.0a0' perl: 5.* @@ -6113,7 +5989,7 @@ package: gettext: '' libexpat: '>=2.5.0,<3.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' pcre2: '>=10.40,<10.41.0a0' perl: 5.* @@ -6132,7 +6008,7 @@ package: gettext: '' libexpat: '>=2.5.0,<3.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' pcre2: '>=10.40,<10.41.0a0' perl: 5.* @@ -6143,14 +6019,14 @@ package: category: main optional: false - name: git - version: 2.45.1 + version: 2.45.2 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/git-2.45.1-h57928b3_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/git-2.45.2-h57928b3_1.conda hash: - md5: c5f7b7a642fbee7b4dec32476e7368f9 - sha256: ceaf6c5837dc5f6ecdeb09fa51f0167b738908839832b267e654af934cd4b6e1 + md5: 92dba9a3e8b104b54d08b3f3ed4700d2 + sha256: 87e76594216c26d1cb34bd011f8170d1a3b4269a3ae510776baf7edaf718b493 category: main optional: false - name: gl2ps @@ -6198,14 +6074,15 @@ package: manager: conda platform: win-64 dependencies: - libpng: '>=1.6.37,<1.7.0a0' - vc: '>=14.1,<15.0a0' - vs2015_runtime: '>=14.16.27012' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-h0597ee9_0.tar.bz2 + libpng: '>=1.6.43,<1.7.0a0' + libzlib: '>=1.3.1,<2.0a0' + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-had7236b_1.conda hash: - md5: 9f17f1b93f610b4bea2a256d528fe8f6 - sha256: 6d4f45a6c4021c439b846356effac330d01a95a606e2eab9b5bd0cbdb1875b64 + md5: 033491c5cb1ce4e915238307f0136fa0 + sha256: 5a18f0aa963adb4402dbce93516f40756beaa206e82c56592aafb1eb88060ba5 category: main optional: false - name: glew @@ -6271,7 +6148,7 @@ package: libgcc-ng: '>=12' libglib: 2.78.1 libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '*' url: https://conda.anaconda.org/conda-forge/linux-64/glib-2.78.1-hfc55251_0.conda hash: @@ -6289,7 +6166,7 @@ package: glib-tools: 2.78.1 libcxx: '>=16.0.6' libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '*' url: https://conda.anaconda.org/conda-forge/osx-64/glib-2.78.1-hf4d7fad_0.conda hash: @@ -6307,7 +6184,7 @@ package: glib-tools: 2.78.1 libcxx: '>=16.0.6' libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '*' url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.78.1-h9e231a4_0.conda hash: @@ -6323,7 +6200,7 @@ package: gettext: '>=0.21.1,<1.0a0' glib-tools: 2.78.1 libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '*' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -6342,7 +6219,7 @@ package: libgcc-ng: '>=12' libglib: 2.78.1 libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.78.1-hfc55251_0.conda hash: md5: 5b4fe75a68cbb95350f47bb9a707b53b @@ -6357,7 +6234,7 @@ package: __osx: '>=10.9' libcxx: '>=16.0.6' libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.78.1-hf4d7fad_0.conda hash: md5: be4782cc6efc35b7ccbe38fedf33d6d9 @@ -6372,7 +6249,7 @@ package: __osx: '>=10.9' libcxx: '>=16.0.6' libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.78.1-h9e231a4_0.conda hash: md5: be84d40c3b9d17f553618abffd6150a2 @@ -6385,7 +6262,7 @@ package: platform: win-64 dependencies: libglib: 2.78.1 - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -6588,87 +6465,28 @@ package: sha256: 0595b009f20f8f60f13a6398e7cdcbd2acea5f986633adcf85f5a2283c992add category: main optional: false -- name: greenlet - version: 3.0.3 +- name: gsl + version: '2.7' manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=12' - libstdcxx-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.0.3-py38h17151c0_0.conda + libblas: '>=3.8.0,<4.0a0' + libcblas: '>=3.8.0,<4.0a0' + libgcc-ng: '>=9.3.0' + url: https://conda.anaconda.org/conda-forge/linux-64/gsl-2.7-he838d99_0.tar.bz2 hash: - md5: 96428abcd2b3b8e945f8b26e6d9f82f8 - sha256: 62d86c248b8bafa4b89e3b316e2f650972d75510a3b3527310d45e5782003dc3 + md5: fec079ba39c9cca093bf4c00001825de + sha256: 132a918b676dd1f533d7c6f95e567abf7081a6ea3251c3280de35ef600e0da87 category: main optional: false -- name: greenlet - version: 3.0.3 +- name: gsl + version: '2.7' manager: conda platform: osx-64 dependencies: - libcxx: '>=15' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/greenlet-3.0.3-py38h1f5f77c_0.conda - hash: - md5: fa563e578538779bc90107be78316b10 - sha256: de238c14d1c79bdb07443e0fb30f514e0ebb3993940786a2a8e811ad4d5b3d32 - category: main - optional: false -- name: greenlet - version: 3.0.3 - manager: conda - platform: osx-arm64 - dependencies: - libcxx: '>=15' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/greenlet-3.0.3-py38hb9fa5a8_0.conda - hash: - md5: 66e1e0db23eb4b8843db5ad8480932f7 - sha256: 463e4c164d1db8e5be09041104473df1e30f42b1d2c74187f265f4c7ba4db68c - category: main - optional: false -- name: greenlet - version: 3.0.3 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/greenlet-3.0.3-py38hd3f51b4_0.conda - hash: - md5: 798a156023b05a5b248d7b27dacac0aa - sha256: 5bd77bac94472bf6ac05816d6245eea556167f2c550aa27468158f3898f9f015 - category: main - optional: false -- name: gsl - version: '2.7' - manager: conda - platform: linux-64 - dependencies: - libblas: '>=3.8.0,<4.0a0' - libcblas: '>=3.8.0,<4.0a0' - libgcc-ng: '>=9.3.0' - url: https://conda.anaconda.org/conda-forge/linux-64/gsl-2.7-he838d99_0.tar.bz2 - hash: - md5: fec079ba39c9cca093bf4c00001825de - sha256: 132a918b676dd1f533d7c6f95e567abf7081a6ea3251c3280de35ef600e0da87 - category: main - optional: false -- name: gsl - version: '2.7' - manager: conda - platform: osx-64 - dependencies: - libblas: '>=3.8.0,<4.0a0' - libcblas: '>=3.8.0,<4.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/gsl-2.7-h93259b0_0.tar.bz2 + libblas: '>=3.8.0,<4.0a0' + libcblas: '>=3.8.0,<4.0a0' + url: https://conda.anaconda.org/conda-forge/osx-64/gsl-2.7-h93259b0_0.tar.bz2 hash: md5: b4942b1ee2a52fd67f446074488d774d sha256: 8550d64004810fa0b5f552d1f21f9fe51483cd30d2d3200d7b0c5e324f7e6995 @@ -6718,7 +6536,7 @@ package: libstdcxx-ng: '>=12' libvorbis: '>=1.3.7,<1.4.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.22.0-h4243ec0_2.conda hash: md5: 0d0c6604c8ac4ad5e51efa7bb58da05c @@ -6739,7 +6557,7 @@ package: libopus: '>=1.3.1,<2.0a0' libpng: '>=1.6.39,<1.7.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/gst-plugins-base-1.22.7-hd283e88_0.conda hash: md5: 6f0f588e82330893016aa084d3ae74a1 @@ -6760,7 +6578,7 @@ package: libopus: '>=1.3.1,<2.0a0' libpng: '>=1.6.39,<1.7.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.22.7-h040e9b9_0.conda hash: md5: 4513b630afd54796bc14a984a372a74d @@ -6777,7 +6595,7 @@ package: libglib: '>=2.78.1,<3.0a0' libogg: '>=1.3.4,<1.4.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -7133,7 +6951,7 @@ package: jpeg: '>=9e,<10a' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h9772cbc_5.tar.bz2 hash: @@ -7148,7 +6966,7 @@ package: dependencies: jpeg: '>=9e,<10a' libcxx: '>=14.0.4' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-64/hdf4-4.2.15-h7aa5921_5.tar.bz2 hash: @@ -7163,7 +6981,7 @@ package: dependencies: jpeg: '>=9e,<10a' libcxx: '>=14.0.4' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-arm64/hdf4-4.2.15-h1a38d6a_5.tar.bz2 hash: @@ -7177,7 +6995,7 @@ package: platform: win-64 dependencies: jpeg: '>=9e,<10a' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -7199,7 +7017,7 @@ package: libgfortran-ng: '' libgfortran5: '>=10.4.0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.7,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.12.2-nompi_h4df4325_101.conda hash: @@ -7217,7 +7035,7 @@ package: libcxx: '>=13.0.1' libgfortran: 5.* libgfortran5: '>=9.5.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.7,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.12.2-nompi_h48135f9_101.conda hash: @@ -7235,7 +7053,7 @@ package: libcxx: '>=13.0.1' libgfortran: 5.* libgfortran5: '>=11.3.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.7,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.12.2-nompi_ha7af310_101.conda hash: @@ -7250,7 +7068,7 @@ package: dependencies: libaec: '>=1.0.6,<2.0a0' libcurl: '>=7.86.0,<9.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.7,<4.0a0' vc: '>=14.1,<15' vs2015_runtime: '>=14.16.27033' @@ -7597,7 +7415,7 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/imath-3.1.6-h6239696_1.conda hash: md5: ccd8714dc2b97f582ed0f8d7092c0ad5 @@ -7610,7 +7428,7 @@ package: platform: osx-64 dependencies: libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/imath-3.1.6-hbc0c0cd_1.conda hash: md5: 14b541e6ba0d755c0cefcd32c591ab0d @@ -7623,7 +7441,7 @@ package: platform: osx-arm64 dependencies: libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/imath-3.1.6-hb5ab8b9_1.conda hash: md5: 61ed8a7b19ea1fea241df94073ae5594 @@ -7635,7 +7453,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -7854,14 +7672,14 @@ package: manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_965.conda + url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda hash: - md5: c66eb2fd33b999ccc258aef85689758e - sha256: 7b029e476ad6d401d645636ee3e4b40130bfcc9534f7415209dd5b666c6dd292 + md5: 35d7ea07ad6c878bd7240d2d6c1b8657 + sha256: 77465396f2636c8b3b3a587f1636ee35c17a73e2a2c7e0ea0957b05f84704cf3 category: main optional: false - name: ipykernel - version: 6.29.3 + version: 6.29.4 manager: conda platform: linux-64 dependencies: @@ -7879,14 +7697,14 @@ package: pyzmq: '>=24' tornado: '>=6.1' traitlets: '>=5.4.0' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyhd33586a_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh3099207_0.conda hash: - md5: e0deff12c601ce5cb7476f93718f3168 - sha256: 0314f15e666fd9a4fb653aae37d2cf4dc6bc3a18c0d9c2671a6a0783146adcfa + md5: 36baf4c745655019de1f29df2535a72b + sha256: 202ab54ddc21011bf7ed7c8fa705767c9e7735a52281b010516faf3924bf0584 category: main optional: false - name: ipykernel - version: 6.29.3 + version: 6.29.4 manager: conda platform: osx-64 dependencies: @@ -7905,14 +7723,14 @@ package: comm: '>=0.1.1' traitlets: '>=5.4.0' pyzmq: '>=24' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyh3cd1d5f_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda hash: - md5: 28e74fca8d8abf09c1ed0d190a17e307 - sha256: ef2f9c1d83afd693db3793c368c5c6afcd37a416958ece490a2e1fbcd85012eb + md5: 1e991f9ed4a81d3482d46edbeb54721a + sha256: 634d840cf7ab02a31b164f7eca0e855b2b9aa9b3aff52a64b758bbbaf44a31de category: main optional: false - name: ipykernel - version: 6.29.3 + version: 6.29.4 manager: conda platform: osx-arm64 dependencies: @@ -7931,21 +7749,21 @@ package: comm: '>=0.1.1' traitlets: '>=5.4.0' pyzmq: '>=24' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyh3cd1d5f_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda hash: - md5: 28e74fca8d8abf09c1ed0d190a17e307 - sha256: ef2f9c1d83afd693db3793c368c5c6afcd37a416958ece490a2e1fbcd85012eb + md5: 1e991f9ed4a81d3482d46edbeb54721a + sha256: 634d840cf7ab02a31b164f7eca0e855b2b9aa9b3aff52a64b758bbbaf44a31de category: main optional: false - name: ipykernel - version: 6.29.3 + version: 6.29.4 manager: conda platform: win-64 dependencies: packaging: '' psutil: '' - nest-asyncio: '' __win: '' + nest-asyncio: '' python: '>=3.8' tornado: '>=6.1' jupyter_client: '>=6.1.12' @@ -7956,10 +7774,10 @@ package: comm: '>=0.1.1' traitlets: '>=5.4.0' pyzmq: '>=24' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyha63f2e9_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh4bbf305_0.conda hash: - md5: d86f243bdd45a8019050e7326ed7bb2e - sha256: 93ff46322a2512e9fb4ba456b1f0120d2f628a4b851f3102561a351e528d24d0 + md5: 899877a9ae762c02f2142b0531bee6a4 + sha256: c97cda9457c782ef6e52ec45ce48bd4a36cfa6ae1546b1de99b5cedc467dc341 category: main optional: false - name: ipython @@ -8112,54 +7930,6 @@ package: sha256: 7bb5c4d994361022f47a807b5e7d101b3dce16f7dd8a0af6ffad9f479d346493 category: main optional: false -- name: itsdangerous - version: 2.2.0 - manager: conda - platform: linux-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.2.0-pyhd8ed1ab_0.conda - hash: - md5: ff7ca04134ee8dde1d7cf491a78ef7c7 - sha256: 4e933e36e9b0401b62ea8fd63393827ebeb4250de77a56687afb387d504523c5 - category: main - optional: false -- name: itsdangerous - version: 2.2.0 - manager: conda - platform: osx-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.2.0-pyhd8ed1ab_0.conda - hash: - md5: ff7ca04134ee8dde1d7cf491a78ef7c7 - sha256: 4e933e36e9b0401b62ea8fd63393827ebeb4250de77a56687afb387d504523c5 - category: main - optional: false -- name: itsdangerous - version: 2.2.0 - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.2.0-pyhd8ed1ab_0.conda - hash: - md5: ff7ca04134ee8dde1d7cf491a78ef7c7 - sha256: 4e933e36e9b0401b62ea8fd63393827ebeb4250de77a56687afb387d504523c5 - category: main - optional: false -- name: itsdangerous - version: 2.2.0 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/itsdangerous-2.2.0-pyhd8ed1ab_0.conda - hash: - md5: ff7ca04134ee8dde1d7cf491a78ef7c7 - sha256: 4e933e36e9b0401b62ea8fd63393827ebeb4250de77a56687afb387d504523c5 - category: main - optional: false - name: jack version: 1.9.22 manager: conda @@ -8513,131 +8283,187 @@ package: category: main optional: false - name: jsonpointer - version: '2.4' + version: 3.0.0 manager: conda platform: linux-64 dependencies: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py38h578d9bd_3.conda + url: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py38h578d9bd_0.conda hash: - md5: ed4beead725b2b8c6673d4d7338bce78 - sha256: 5004ee83f7b0259d11923a0f15e79af6b3e3e114e03191cbc0e751f787ddbcaf + md5: 35f7346da8d31ccef2c97db678b2c390 + sha256: 9baad51bb9b480e4aeaf339fdf2b81bfa760644976016abc4b32631646ddbcb8 category: main optional: false - name: jsonpointer - version: '2.4' + version: 3.0.0 manager: conda platform: osx-64 dependencies: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-2.4-py38h50d1736_3.conda + url: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py38h50d1736_0.conda hash: - md5: 587da7fcb04fb5d49d7caf0f0010e17f - sha256: f706894de91a7c453fb8509172251d4cf99f30e0461c57a0405eac9c477faed3 + md5: 8429abfb14ccf0f973007dadbe929718 + sha256: c6735f29bd293e4fb5bac93c9f32ddb624a5d08395126f9a5043c001a34d3687 category: main optional: false - name: jsonpointer - version: '2.4' + version: 3.0.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-2.4-py38h10201cd_3.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-3.0.0-py38h10201cd_0.conda hash: - md5: a2358babcb4baaa338eb94cc3683816b - sha256: 2c87d5e8891b482451fa64043eee38fcca704769ad55d44b3a258f751329adb5 + md5: 0d49467654ebf56e1b0634211338489c + sha256: 53efde5fdd02debf3dd2a6cb168f00f0860b2b1a63e3e7aed2d1602b530f72c7 category: main optional: false - name: jsonpointer - version: '2.4' + version: 3.0.0 manager: conda platform: win-64 dependencies: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-2.4-py38haa244fe_3.conda + url: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py38haa244fe_0.conda hash: - md5: 4a682a2f267deb4c541d23ee3213f56e - sha256: d598a96a1c235c4ccbb32165c9d0bc24cc96c049c015876e442b5456c0fb9f54 + md5: ce0e5c52020f888c05a9a27370daa175 + sha256: b85ef836cabc3e117e5619360ce9fc6c3e43e0c9001267804e5648e8161f1176 category: main optional: false - name: jsonschema - version: 4.17.3 + version: 4.22.0 manager: conda platform: linux-64 dependencies: - attrs: '>=17.4.0' - importlib-metadata: '' + attrs: '>=22.2.0' importlib_resources: '>=1.4.0' + jsonschema-specifications: '>=2023.03.6' pkgutil-resolve-name: '>=1.3.10' - pyrsistent: '!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0' - python: '>=3.7' - typing_extensions: '' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.17.3-pyhd8ed1ab_0.conda + python: '>=3.8' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 723268a468177cd44568eb8f794e0d80 - sha256: 4f68a23430d1afc5c9b41c46fbac0ade33c0bf57a293c646bfdd6dc65350eada + md5: b9661a4b1200d6bc7d8a4cdafdc91468 + sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a category: main optional: false - name: jsonschema - version: 4.17.3 + version: 4.22.0 manager: conda platform: osx-64 dependencies: - typing_extensions: '' - importlib-metadata: '' - python: '>=3.7' + python: '>=3.8' + attrs: '>=22.2.0' importlib_resources: '>=1.4.0' - attrs: '>=17.4.0' - pyrsistent: '!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0' pkgutil-resolve-name: '>=1.3.10' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.17.3-pyhd8ed1ab_0.conda + jsonschema-specifications: '>=2023.03.6' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 723268a468177cd44568eb8f794e0d80 - sha256: 4f68a23430d1afc5c9b41c46fbac0ade33c0bf57a293c646bfdd6dc65350eada + md5: b9661a4b1200d6bc7d8a4cdafdc91468 + sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a category: main optional: false - name: jsonschema - version: 4.17.3 + version: 4.22.0 manager: conda platform: osx-arm64 dependencies: - typing_extensions: '' - importlib-metadata: '' - python: '>=3.7' + python: '>=3.8' + attrs: '>=22.2.0' importlib_resources: '>=1.4.0' - attrs: '>=17.4.0' - pyrsistent: '!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0' pkgutil-resolve-name: '>=1.3.10' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.17.3-pyhd8ed1ab_0.conda + jsonschema-specifications: '>=2023.03.6' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 723268a468177cd44568eb8f794e0d80 - sha256: 4f68a23430d1afc5c9b41c46fbac0ade33c0bf57a293c646bfdd6dc65350eada + md5: b9661a4b1200d6bc7d8a4cdafdc91468 + sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a category: main optional: false - name: jsonschema - version: 4.17.3 + version: 4.22.0 manager: conda platform: win-64 dependencies: - typing_extensions: '' - importlib-metadata: '' - python: '>=3.7' + python: '>=3.8' + attrs: '>=22.2.0' importlib_resources: '>=1.4.0' - attrs: '>=17.4.0' - pyrsistent: '!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0' pkgutil-resolve-name: '>=1.3.10' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.17.3-pyhd8ed1ab_0.conda + jsonschema-specifications: '>=2023.03.6' + referencing: '>=0.28.4' + rpds-py: '>=0.7.1' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda + hash: + md5: b9661a4b1200d6bc7d8a4cdafdc91468 + sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a + category: main + optional: false +- name: jsonschema-specifications + version: 2023.12.1 + manager: conda + platform: linux-64 + dependencies: + importlib_resources: '>=1.4.0' + python: '>=3.8' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda + hash: + md5: a0e4efb5f35786a05af4809a2fb1f855 + sha256: a9630556ddc3121c0be32f4cbf792dd9102bd380d5cd81d57759d172cf0c2da2 + category: main + optional: false +- name: jsonschema-specifications + version: 2023.12.1 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + importlib_resources: '>=1.4.0' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda + hash: + md5: a0e4efb5f35786a05af4809a2fb1f855 + sha256: a9630556ddc3121c0be32f4cbf792dd9102bd380d5cd81d57759d172cf0c2da2 + category: main + optional: false +- name: jsonschema-specifications + version: 2023.12.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + importlib_resources: '>=1.4.0' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda + hash: + md5: a0e4efb5f35786a05af4809a2fb1f855 + sha256: a9630556ddc3121c0be32f4cbf792dd9102bd380d5cd81d57759d172cf0c2da2 + category: main + optional: false +- name: jsonschema-specifications + version: 2023.12.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + importlib_resources: '>=1.4.0' + referencing: '>=0.31.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda hash: - md5: 723268a468177cd44568eb8f794e0d80 - sha256: 4f68a23430d1afc5c9b41c46fbac0ade33c0bf57a293c646bfdd6dc65350eada + md5: a0e4efb5f35786a05af4809a2fb1f855 + sha256: a9630556ddc3121c0be32f4cbf792dd9102bd380d5cd81d57759d172cf0c2da2 category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.17.3 + version: 4.22.0 manager: conda platform: linux-64 dependencies: @@ -8645,20 +8471,20 @@ package: idna: '' isoduration: '' jsonpointer: '>1.13' - jsonschema: '>=4.17.3,<4.17.4.0a0' + jsonschema: '>=4.22.0,<4.22.1.0a0' python: '' rfc3339-validator: '' rfc3986-validator: '>0.1.0' uri-template: '' webcolors: '>=1.11' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.17.3-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 7a709748e93f0b2c33d6b5b676b6d9d0 - sha256: 767da9c47d64e1dc826d3173e46ff6fd4e858c94ff61d67ff4f976c7bc9502a2 + md5: 32ab666927ee17b9468c2c72bbd7ba1b + sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.17.3 + version: 4.22.0 manager: conda platform: osx-64 dependencies: @@ -8671,15 +8497,15 @@ package: jsonpointer: '>1.13' webcolors: '>=1.11' rfc3986-validator: '>0.1.0' - jsonschema: '>=4.17.3,<4.17.4.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.17.3-pyhd8ed1ab_0.conda + jsonschema: '>=4.22.0,<4.22.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 7a709748e93f0b2c33d6b5b676b6d9d0 - sha256: 767da9c47d64e1dc826d3173e46ff6fd4e858c94ff61d67ff4f976c7bc9502a2 + md5: 32ab666927ee17b9468c2c72bbd7ba1b + sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.17.3 + version: 4.22.0 manager: conda platform: osx-arm64 dependencies: @@ -8692,15 +8518,15 @@ package: jsonpointer: '>1.13' webcolors: '>=1.11' rfc3986-validator: '>0.1.0' - jsonschema: '>=4.17.3,<4.17.4.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.17.3-pyhd8ed1ab_0.conda + jsonschema: '>=4.22.0,<4.22.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 7a709748e93f0b2c33d6b5b676b6d9d0 - sha256: 767da9c47d64e1dc826d3173e46ff6fd4e858c94ff61d67ff4f976c7bc9502a2 + md5: 32ab666927ee17b9468c2c72bbd7ba1b + sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.17.3 + version: 4.22.0 manager: conda platform: win-64 dependencies: @@ -8713,11 +8539,11 @@ package: jsonpointer: '>1.13' webcolors: '>=1.11' rfc3986-validator: '>0.1.0' - jsonschema: '>=4.17.3,<4.17.4.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.17.3-pyhd8ed1ab_0.conda + jsonschema: '>=4.22.0,<4.22.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda hash: - md5: 7a709748e93f0b2c33d6b5b676b6d9d0 - sha256: 767da9c47d64e1dc826d3173e46ff6fd4e858c94ff61d67ff4f976c7bc9502a2 + md5: 32ab666927ee17b9468c2c72bbd7ba1b + sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d category: main optional: false - name: jupyter-lsp @@ -8777,7 +8603,7 @@ package: category: main optional: false - name: jupyter_client - version: 8.6.1 + version: 8.6.2 manager: conda platform: linux-64 dependencies: @@ -8788,14 +8614,14 @@ package: pyzmq: '>=23.0' tornado: '>=6.2' traitlets: '>=5.3' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: - md5: c03972cfce69ad913d520c652e5ed908 - sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 + md5: 3cdbb2fa84490e5fd44c9f9806c0d292 + sha256: 634f065cdd1d0aacd4bb6848ebf240dcebc8578135d65f4ad4aa42b2276c4e0c category: main optional: false - name: jupyter_client - version: 8.6.1 + version: 8.6.2 manager: conda platform: osx-64 dependencies: @@ -8806,14 +8632,14 @@ package: traitlets: '>=5.3' pyzmq: '>=23.0' tornado: '>=6.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: - md5: c03972cfce69ad913d520c652e5ed908 - sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 + md5: 3cdbb2fa84490e5fd44c9f9806c0d292 + sha256: 634f065cdd1d0aacd4bb6848ebf240dcebc8578135d65f4ad4aa42b2276c4e0c category: main optional: false - name: jupyter_client - version: 8.6.1 + version: 8.6.2 manager: conda platform: osx-arm64 dependencies: @@ -8824,14 +8650,14 @@ package: traitlets: '>=5.3' pyzmq: '>=23.0' tornado: '>=6.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: - md5: c03972cfce69ad913d520c652e5ed908 - sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 + md5: 3cdbb2fa84490e5fd44c9f9806c0d292 + sha256: 634f065cdd1d0aacd4bb6848ebf240dcebc8578135d65f4ad4aa42b2276c4e0c category: main optional: false - name: jupyter_client - version: 8.6.1 + version: 8.6.2 manager: conda platform: win-64 dependencies: @@ -8842,10 +8668,10 @@ package: traitlets: '>=5.3' pyzmq: '>=23.0' tornado: '>=6.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: - md5: c03972cfce69ad913d520c652e5ed908 - sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 + md5: 3cdbb2fa84490e5fd44c9f9806c0d292 + sha256: 634f065cdd1d0aacd4bb6848ebf240dcebc8578135d65f4ad4aa42b2276c4e0c category: main optional: false - name: jupyter_core @@ -8910,79 +8736,83 @@ package: category: main optional: false - name: jupyter_events - version: 0.6.3 + version: 0.10.0 manager: conda platform: linux-64 dependencies: - jsonschema-with-format-nongpl: '>=3.2' - python: '>=3.7' + jsonschema-with-format-nongpl: '>=4.18.0' + python: '>=3.8' python-json-logger: '>=2.0.4' pyyaml: '>=5.3' + referencing: '' rfc3339-validator: '' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.6.3-pyhd8ed1ab_1.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: - md5: 2ac0d00a0fb3f1a4c81c460ba56bb23b - sha256: 457e05bfcd6a37fbb8b4a44a500be7512e23bf1ef507e46fbd07497c217a2787 + md5: ed45423c41b3da15ea1df39b1f80c2ca + sha256: cd3f41dc093162a41d4bae171e40a1b9b115c4d488e9bb837a8fa9d084931fb9 category: main optional: false - name: jupyter_events - version: 0.6.3 + version: 0.10.0 manager: conda platform: osx-64 dependencies: + referencing: '' rfc3339-validator: '' - python: '>=3.7' + python: '>=3.8' pyyaml: '>=5.3' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' python-json-logger: '>=2.0.4' - jsonschema-with-format-nongpl: '>=3.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.6.3-pyhd8ed1ab_1.conda + jsonschema-with-format-nongpl: '>=4.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: - md5: 2ac0d00a0fb3f1a4c81c460ba56bb23b - sha256: 457e05bfcd6a37fbb8b4a44a500be7512e23bf1ef507e46fbd07497c217a2787 + md5: ed45423c41b3da15ea1df39b1f80c2ca + sha256: cd3f41dc093162a41d4bae171e40a1b9b115c4d488e9bb837a8fa9d084931fb9 category: main optional: false - name: jupyter_events - version: 0.6.3 + version: 0.10.0 manager: conda platform: osx-arm64 dependencies: + referencing: '' rfc3339-validator: '' - python: '>=3.7' + python: '>=3.8' pyyaml: '>=5.3' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' python-json-logger: '>=2.0.4' - jsonschema-with-format-nongpl: '>=3.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.6.3-pyhd8ed1ab_1.conda + jsonschema-with-format-nongpl: '>=4.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: - md5: 2ac0d00a0fb3f1a4c81c460ba56bb23b - sha256: 457e05bfcd6a37fbb8b4a44a500be7512e23bf1ef507e46fbd07497c217a2787 + md5: ed45423c41b3da15ea1df39b1f80c2ca + sha256: cd3f41dc093162a41d4bae171e40a1b9b115c4d488e9bb837a8fa9d084931fb9 category: main optional: false - name: jupyter_events - version: 0.6.3 + version: 0.10.0 manager: conda platform: win-64 dependencies: + referencing: '' rfc3339-validator: '' - python: '>=3.7' + python: '>=3.8' pyyaml: '>=5.3' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' python-json-logger: '>=2.0.4' - jsonschema-with-format-nongpl: '>=3.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.6.3-pyhd8ed1ab_1.conda + jsonschema-with-format-nongpl: '>=4.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: - md5: 2ac0d00a0fb3f1a4c81c460ba56bb23b - sha256: 457e05bfcd6a37fbb8b4a44a500be7512e23bf1ef507e46fbd07497c217a2787 + md5: ed45423c41b3da15ea1df39b1f80c2ca + sha256: cd3f41dc093162a41d4bae171e40a1b9b115c4d488e9bb837a8fa9d084931fb9 category: main optional: false - name: jupyter_server - version: 2.10.0 + version: 2.14.1 manager: conda platform: linux-64 dependencies: @@ -8991,7 +8821,7 @@ package: jinja2: '' jupyter_client: '>=7.4.4' jupyter_core: '>=4.12,!=5.0.*' - jupyter_events: '>=0.6.0' + jupyter_events: '>=0.9.0' jupyter_server_terminals: '' nbconvert-core: '>=6.4.4' nbformat: '>=5.3.0' @@ -9005,14 +8835,14 @@ package: tornado: '>=6.2.0' traitlets: '>=5.6.0' websocket-client: '' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.10.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda hash: - md5: 016d56f5d81b9364d1da5f4895a2a9f8 - sha256: 0b9a72f28ff8a12e6ea0ae43d3ea93e288074d29348c5fc6fbb3a5e5e18b2ecd + md5: 174af03c6e6038edd32021a48aa003c4 + sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c category: main optional: false - name: jupyter_server - version: 2.10.0 + version: 2.14.1 manager: conda platform: osx-64 dependencies: @@ -9027,18 +8857,18 @@ package: terminado: '>=0.8.3' jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' - nbconvert-core: '>=6.4.4' pyzmq: '>=24' + nbconvert-core: '>=6.4.4' jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' traitlets: '>=5.6.0' - jupyter_events: '>=0.6.0' anyio: '>=3.1.0' send2trash: '>=1.8.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.10.0-pyhd8ed1ab_0.conda + jupyter_events: '>=0.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda hash: - md5: 016d56f5d81b9364d1da5f4895a2a9f8 - sha256: 0b9a72f28ff8a12e6ea0ae43d3ea93e288074d29348c5fc6fbb3a5e5e18b2ecd + md5: 174af03c6e6038edd32021a48aa003c4 + sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c category: main optional: false - name: jupyter_server @@ -9058,8 +8888,8 @@ package: terminado: '>=0.8.3' jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' - nbconvert-core: '>=6.4.4' pyzmq: '>=24' + nbconvert-core: '>=6.4.4' anyio: '>=3.1.0,<4' jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' @@ -9072,7 +8902,7 @@ package: category: main optional: false - name: jupyter_server - version: 2.10.0 + version: 2.14.1 manager: conda platform: win-64 dependencies: @@ -9087,18 +8917,18 @@ package: terminado: '>=0.8.3' jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' - nbconvert-core: '>=6.4.4' pyzmq: '>=24' + nbconvert-core: '>=6.4.4' jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' traitlets: '>=5.6.0' - jupyter_events: '>=0.6.0' anyio: '>=3.1.0' send2trash: '>=1.8.2' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.10.0-pyhd8ed1ab_0.conda + jupyter_events: '>=0.9.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda hash: - md5: 016d56f5d81b9364d1da5f4895a2a9f8 - sha256: 0b9a72f28ff8a12e6ea0ae43d3ea93e288074d29348c5fc6fbb3a5e5e18b2ecd + md5: 174af03c6e6038edd32021a48aa003c4 + sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c category: main optional: false - name: jupyter_server_terminals @@ -9154,7 +8984,7 @@ package: category: main optional: false - name: jupyterlab - version: 4.1.6 + version: 4.2.2 manager: conda platform: linux-64 dependencies: @@ -9167,21 +8997,22 @@ package: jupyter-lsp: '>=2.0.0' jupyter_core: '' jupyter_server: '>=2.4.0,<3' - jupyterlab_server: '>=2.19.0,<3' + jupyterlab_server: '>=2.27.1,<3' notebook-shim: '>=0.2' packaging: '' python: '>=3.8' + setuptools: '>=40.1.0' tomli: '>=1.2.2' tornado: '>=6.2.0' traitlets: '' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.6-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda hash: - md5: 8b0a6b8edbaef9796d2b925c63441b8e - sha256: fe935cccc5766b0212ce66fdb91db7068d89c88a1b916f067b16b86fb352d7a5 + md5: 405a9d330af26391c8001d56b3ef4239 + sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 category: main optional: false - name: jupyterlab - version: 4.1.6 + version: 4.2.2 manager: conda platform: osx-64 dependencies: @@ -9190,25 +9021,26 @@ package: jupyter_core: '' python: '>=3.8' tornado: '>=6.2.0' - jinja2: '>=3.0.3' tomli: '>=1.2.2' + jinja2: '>=3.0.3' importlib_metadata: '>=4.8.3' jupyter_server: '>=2.4.0,<3' importlib_resources: '>=1.4' jupyter-lsp: '>=2.0.0' async-lru: '>=1.0.0' notebook-shim: '>=0.2' - jupyterlab_server: '>=2.19.0,<3' + setuptools: '>=40.1.0' httpx: '>=0.25.0' + jupyterlab_server: '>=2.27.1,<3' ipykernel: '>=6.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.6-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda hash: - md5: 8b0a6b8edbaef9796d2b925c63441b8e - sha256: fe935cccc5766b0212ce66fdb91db7068d89c88a1b916f067b16b86fb352d7a5 + md5: 405a9d330af26391c8001d56b3ef4239 + sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 category: main optional: false - name: jupyterlab - version: 4.1.6 + version: 4.2.2 manager: conda platform: osx-arm64 dependencies: @@ -9217,25 +9049,26 @@ package: jupyter_core: '' python: '>=3.8' tornado: '>=6.2.0' - jinja2: '>=3.0.3' tomli: '>=1.2.2' + jinja2: '>=3.0.3' importlib_metadata: '>=4.8.3' jupyter_server: '>=2.4.0,<3' importlib_resources: '>=1.4' jupyter-lsp: '>=2.0.0' async-lru: '>=1.0.0' notebook-shim: '>=0.2' - jupyterlab_server: '>=2.19.0,<3' + setuptools: '>=40.1.0' httpx: '>=0.25.0' + jupyterlab_server: '>=2.27.1,<3' ipykernel: '>=6.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.6-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda hash: - md5: 8b0a6b8edbaef9796d2b925c63441b8e - sha256: fe935cccc5766b0212ce66fdb91db7068d89c88a1b916f067b16b86fb352d7a5 + md5: 405a9d330af26391c8001d56b3ef4239 + sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 category: main optional: false - name: jupyterlab - version: 4.1.6 + version: 4.2.2 manager: conda platform: win-64 dependencies: @@ -9244,21 +9077,22 @@ package: jupyter_core: '' python: '>=3.8' tornado: '>=6.2.0' - jinja2: '>=3.0.3' tomli: '>=1.2.2' + jinja2: '>=3.0.3' importlib_metadata: '>=4.8.3' jupyter_server: '>=2.4.0,<3' importlib_resources: '>=1.4' jupyter-lsp: '>=2.0.0' async-lru: '>=1.0.0' notebook-shim: '>=0.2' - jupyterlab_server: '>=2.19.0,<3' + setuptools: '>=40.1.0' httpx: '>=0.25.0' + jupyterlab_server: '>=2.27.1,<3' ipykernel: '>=6.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.6-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda hash: - md5: 8b0a6b8edbaef9796d2b925c63441b8e - sha256: fe935cccc5766b0212ce66fdb91db7068d89c88a1b916f067b16b86fb352d7a5 + md5: 405a9d330af26391c8001d56b3ef4239 + sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 category: main optional: false - name: jupyterlab_pygments @@ -9314,7 +9148,7 @@ package: category: main optional: false - name: jupyterlab_server - version: 2.24.0 + version: 2.27.2 manager: conda platform: linux-64 dependencies: @@ -9322,75 +9156,75 @@ package: importlib-metadata: '>=4.8.3' jinja2: '>=3.0.3' json5: '>=0.9.0' - jsonschema: '>=4.17.3' + jsonschema: '>=4.18' jupyter_server: '>=1.21,<3' packaging: '>=21.3' - python: '>=3.7' - requests: '>=2.28' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.24.0-pyhd8ed1ab_0.conda + python: '>=3.8' + requests: '>=2.31' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda hash: - md5: 327bfe1c99154f02259d29810bd70afc - sha256: 7084223bb168268ba93334fc27410885bdc6e537020d6a91ab0f46f37a3f3ded + md5: d1cb7b113daaadd89e5aa6a32b28bf0d + sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 category: main optional: false - name: jupyterlab_server - version: 2.24.0 + version: 2.27.2 manager: conda platform: osx-64 dependencies: - python: '>=3.7' + python: '>=3.8' packaging: '>=21.3' jinja2: '>=3.0.3' importlib-metadata: '>=4.8.3' - requests: '>=2.28' + requests: '>=2.31' jupyter_server: '>=1.21,<3' - jsonschema: '>=4.17.3' babel: '>=2.10' json5: '>=0.9.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.24.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.18' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda hash: - md5: 327bfe1c99154f02259d29810bd70afc - sha256: 7084223bb168268ba93334fc27410885bdc6e537020d6a91ab0f46f37a3f3ded + md5: d1cb7b113daaadd89e5aa6a32b28bf0d + sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 category: main optional: false - name: jupyterlab_server - version: 2.24.0 + version: 2.27.2 manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' + python: '>=3.8' packaging: '>=21.3' jinja2: '>=3.0.3' importlib-metadata: '>=4.8.3' - requests: '>=2.28' + requests: '>=2.31' jupyter_server: '>=1.21,<3' - jsonschema: '>=4.17.3' babel: '>=2.10' json5: '>=0.9.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.24.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.18' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda hash: - md5: 327bfe1c99154f02259d29810bd70afc - sha256: 7084223bb168268ba93334fc27410885bdc6e537020d6a91ab0f46f37a3f3ded + md5: d1cb7b113daaadd89e5aa6a32b28bf0d + sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 category: main optional: false - name: jupyterlab_server - version: 2.24.0 + version: 2.27.2 manager: conda platform: win-64 dependencies: - python: '>=3.7' + python: '>=3.8' packaging: '>=21.3' jinja2: '>=3.0.3' importlib-metadata: '>=4.8.3' - requests: '>=2.28' + requests: '>=2.31' jupyter_server: '>=1.21,<3' - jsonschema: '>=4.17.3' babel: '>=2.10' json5: '>=0.9.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.24.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.18' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda hash: - md5: 327bfe1c99154f02259d29810bd70afc - sha256: 7084223bb168268ba93334fc27410885bdc6e537020d6a91ab0f46f37a3f3ded + md5: d1cb7b113daaadd89e5aa6a32b28bf0d + sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 category: main optional: false - name: jxrlib @@ -9721,10 +9555,10 @@ package: manager: conda platform: linux-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda hash: - md5: 10569984e7db886e4f1abc2b47ad79a1 - sha256: ef969eee228cfb71e55146eaecc6af065f468cb0bc0a5239bc053b39db0b5f09 + md5: b80f2f396ca2c28b8c14c437a4ed1e74 + sha256: 764b6950aceaaad0c67ef925417594dd14cd2e22fff864aeef455ac259263d15 category: main optional: false - name: lerc @@ -9898,7 +9732,7 @@ package: libstdcxx-ng: '>=12' libthrift: '>=0.18.1,<0.18.2.0a0' libutf8proc: '>=2.8.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.1.1,<4.0a0' orc: '>=1.9.0,<1.9.1.0a0' @@ -9930,7 +9764,7 @@ package: libprotobuf: '>=4.23.3,<4.23.4.0a0' libthrift: '>=0.18.1,<0.18.2.0a0' libutf8proc: '>=2.8.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.1.1,<4.0a0' orc: '>=1.9.0,<1.9.1.0a0' @@ -9961,7 +9795,7 @@ package: libprotobuf: '>=4.23.3,<4.23.4.0a0' libthrift: '>=0.18.1,<0.18.2.0a0' libutf8proc: '>=2.8.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.1.1,<4.0a0' orc: '>=1.9.0,<1.9.1.0a0' @@ -9992,7 +9826,7 @@ package: libprotobuf: '>=4.23.3,<4.23.4.0a0' libthrift: '>=0.18.1,<0.18.2.0a0' libutf8proc: '>=2.8.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.1.1,<4.0a0' orc: '>=1.9.0,<1.9.1.0a0' @@ -10413,7 +10247,7 @@ package: dependencies: libclang13: 15.0.7 libxml2: '>=2.12.6,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -10456,7 +10290,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -10525,7 +10359,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h36d4200_3.conda hash: md5: c9f4416a34bc91e0eb029f912c68f81f @@ -10541,7 +10375,7 @@ package: libgcc-ng: '>=12' libnghttp2: '>=1.52.0,<2.0a0' libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.1.2-h409715c_0.conda @@ -10558,7 +10392,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libnghttp2: '>=1.52.0,<2.0a0' libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.1.2-hbee3ae8_0.conda @@ -10575,7 +10409,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libnghttp2: '>=1.52.0,<2.0a0' libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.1.2-h912dcd9_0.conda @@ -10591,7 +10425,7 @@ package: dependencies: krb5: '>=1.20.1,<1.21.0a0' libssh2: '>=1.10.0,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -10687,16 +10521,16 @@ package: category: main optional: false - name: libdrm - version: 2.4.120 + version: 2.4.121 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' libpciaccess: '>=0.18,<0.19.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.120-hd590300_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.121-h4ab18f5_0.conda hash: - md5: 7c3071bdf1d28b331a06bda6e85ab607 - sha256: 8622f52e517418ae7234081fac14a3caa8aec5d1ee5f881ca1f3b194d81c3150 + md5: 3bcee3436b1effa9a3caee2b74175c08 + sha256: ad6b2b83f53b1ff524e5cd9617674658d97bdfdf1c9a118c011dfaf1d6ac039b category: main optional: false - name: libedit @@ -10936,10 +10770,10 @@ package: dependencies: _libgcc_mutex: '0.1' _openmp_mutex: '>=4.5' - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda hash: - md5: 72ec1b1b04c4d15d4204ece1ecea5978 - sha256: 62af2b89acbe74a21606c8410c276e57309c0a2ab8a9e8639e3c8131c0b60c92 + md5: 0b3b218a596bb4c3854cc9ee799f94e5 + sha256: bbdd49b5a191105cf4bf82a59d611afa1e8568efa556dd988e4e5d0efc3058b1 category: main optional: false - name: libgcrypt @@ -10990,7 +10824,7 @@ package: libuuid: '>=2.32.1,<3.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openjpeg: '>=2.5.0,<3.0a0' openssl: '>=3.0.8,<4.0a0' @@ -11040,7 +10874,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openjpeg: '>=2.5.0,<3.0a0' openssl: '>=3.0.8,<4.0a0' @@ -11090,7 +10924,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openjpeg: '>=2.5.0,<3.0a0' openssl: '>=3.0.8,<4.0a0' @@ -11137,7 +10971,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openjpeg: '>=2.5.0,<3.0a0' openssl: '>=3.0.8,<4.0a0' @@ -11294,10 +11128,10 @@ package: platform: linux-64 dependencies: libgfortran5: 13.2.0 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_7.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda hash: - md5: 1b84f26d9f4f6026e179e7805d5a15cd - sha256: a588e69f96b8e0983a8cdfdbf1dc75eb48189f5420ec71150c8d8cdc0a811a9b + md5: 4c3e460d6acf8e43e4ce8bf405187eb7 + sha256: f91aa928161201f189057c90db1508def36bef6329ebb29a71d8064b180250dd category: main optional: false - name: libgfortran5 @@ -11306,10 +11140,10 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=13.2.0' - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-hca663fb_7.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_11.conda hash: - md5: c0bd771f09a326fdcd95a60b617795bf - sha256: 754ab038115edce550fdccdc9ddf7dead2fa8346b8cdd4428c59ae1e83293978 + md5: c485da4fdb454539f852a90ae06e9bb7 + sha256: de8535b5fb39a78f4b7473b88c400c922ae063f29500c097743b480fd0a4f326 category: main optional: false - name: libgfortran5 @@ -11346,7 +11180,7 @@ package: libgcc-ng: '>=12' libiconv: '>=1.17,<2.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' pcre2: '>=10.40,<10.41.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.1-hebfc3b9_0.conda hash: @@ -11364,7 +11198,7 @@ package: libcxx: '>=16.0.6' libffi: '>=3.4,<4.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' pcre2: '>=10.40,<10.41.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.78.1-h6d9ecee_0.conda hash: @@ -11382,7 +11216,7 @@ package: libcxx: '>=16.0.6' libffi: '>=3.4,<4.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' pcre2: '>=10.40,<10.41.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.1-hd9b11f9_0.conda hash: @@ -11398,7 +11232,7 @@ package: gettext: '>=0.21.1,<1.0a0' libffi: '>=3.4,<4.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' pcre2: '>=10.40,<10.41.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -11428,10 +11262,10 @@ package: platform: linux-64 dependencies: _libgcc_mutex: '0.1' - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda hash: - md5: abf3fec87c2563697defa759dec3d639 - sha256: 781444fa069d3b50e8ed667b750571cacda785761c7fc2a89ece1ac49693d4ad + md5: 8c462ced2af33648195dc9459f331f31 + sha256: f4112111fa350bcd8d6d354cdde3426751a579add88fa523f6483c714821e681 category: main optional: false - name: libgoogle-cloud @@ -11535,7 +11369,7 @@ package: libgcc-ng: '>=12' libprotobuf: '>=4.23.3,<4.23.4.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' re2: '>=2023.3.2,<2023.3.3.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.56.2-h3905398_1.conda @@ -11554,7 +11388,7 @@ package: libabseil: '>=20230125.3,<20230126.0a0' libcxx: '>=15.0.7' libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' re2: '>=2023.3.2,<2023.3.3.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libgrpc-1.56.2-he6801ca_1.conda @@ -11572,7 +11406,7 @@ package: libabseil: '>=20230125.3,<20230126.0a0' libcxx: '>=15.0.7' libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' re2: '>=2023.3.2,<2023.3.3.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libgrpc-1.56.2-h9075ed4_1.conda @@ -11589,7 +11423,7 @@ package: c-ares: '>=1.19.1,<2.0a0' libabseil: '>=20230125.3,<20230126.0a0' libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' re2: '>=2023.3.2,<2023.3.3.0a0' ucrt: '>=10.0.20348.0' @@ -11620,15 +11454,15 @@ package: manager: conda platform: win-64 dependencies: - libxml2: '>=2.12.6,<3.0a0' + libxml2: '>=2.12.7,<3.0a0' pthreads-win32: '' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.10.0-default_h2fffb23_1000.conda + url: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.10.0-default_h8125262_1001.conda hash: - md5: ee944f0d41d9e2048f9d7492c1623ca3 - sha256: e0d75da50e67a81e3cb37e2ee3b0d6ddc6543ec0f7b3828f884558552a1c4d93 + md5: e761885eb4c181074d172220d46319a0 + sha256: 7f1aa1b071269df72e88297c046ec153b7f9a81e6f135d2da4401c96f41b5052 category: main optional: false - name: libiconv @@ -11802,7 +11636,7 @@ package: libexpat: '>=2.5.0,<3.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' uriparser: '>=0.9.7,<1.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-h01aab08_1016.conda hash: @@ -11817,7 +11651,7 @@ package: dependencies: libcxx: '>=15.0.7' libexpat: '>=2.5.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' uriparser: '>=0.9.7,<1.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libkml-1.3.0-hab3ca0e_1016.conda hash: @@ -11832,7 +11666,7 @@ package: dependencies: libcxx: '>=15.0.7' libexpat: '>=2.5.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' uriparser: '>=0.9.7,<1.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-h4f02115_1016.conda hash: @@ -11846,7 +11680,7 @@ package: platform: win-64 dependencies: libexpat: '>=2.5.0,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' uriparser: '>=0.9.7,<1.0a0' vc: '>=14.2,<15' @@ -11911,7 +11745,7 @@ package: platform: osx-64 dependencies: libcxx: '>=12.a0' - libzlib: '>=1.2.11,<1.3.0a0' + libzlib: '>=1.2.11,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libllvm13-13.0.1-h64f94b2_2.tar.bz2 hash: md5: bac1c6f12f44f40e19274e6e04e9bad5 @@ -11925,7 +11759,7 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libllvm14-14.0.6-hcd5def8_4.conda hash: md5: 73301c133ded2bf71906aa2104edae8b @@ -11938,7 +11772,7 @@ package: platform: osx-64 dependencies: libcxx: '>=15' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libllvm14-14.0.6-hc8e404f_4.conda hash: md5: ed06753e2ba7c66ed0ca7f19578fcb68 @@ -11951,7 +11785,7 @@ package: platform: osx-arm64 dependencies: libcxx: '>=15' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm14-14.0.6-hd1a9a77_4.conda hash: md5: 9f3dce5d26ea56a9000cd74c034582bd @@ -11966,7 +11800,7 @@ package: libgcc-ng: '>=12' libstdcxx-ng: '>=12' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libllvm15-15.0.7-hadd5161_1.conda hash: @@ -11988,7 +11822,7 @@ package: libstdcxx-ng: '>=12' libxml2: '>=2.10.3,<3.0.0a0' libzip: '>=1.9.2,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.1-nompi_h34a3ff0_101.conda hash: @@ -12009,7 +11843,7 @@ package: libcxx: '>=14.0.6' libxml2: '>=2.10.3,<3.0.0a0' libzip: '>=1.9.2,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.1-nompi_h56690a0_101.conda hash: @@ -12030,7 +11864,7 @@ package: libcxx: '>=14.0.6' libxml2: '>=2.10.3,<3.0.0a0' libzip: '>=1.9.2,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.1-nompi_h232cb48_101.conda hash: @@ -12050,7 +11884,7 @@ package: jpeg: '>=9e,<10a' libxml2: '>=2.10.3,<3.0.0a0' libzip: '>=1.9.2,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -12070,7 +11904,7 @@ package: libev: '>=4.33,<4.34.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.4,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_0.conda hash: @@ -12087,7 +11921,7 @@ package: c-ares: '>=1.21.0,<2.0a0' libcxx: '>=16.0.6' libev: '>=4.33,<4.34.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.4,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.58.0-h64cf6d3_0.conda hash: @@ -12104,7 +11938,7 @@ package: c-ares: '>=1.21.0,<2.0a0' libcxx: '>=16.0.6' libev: '>=4.33,<4.34.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.4,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.58.0-ha4dd798_0.conda hash: @@ -12290,7 +12124,7 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda hash: md5: 009981dd9cfcaa4dbfa25ffaed86bcae @@ -12302,7 +12136,7 @@ package: manager: conda platform: osx-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.43-h92b6c6a_0.conda hash: md5: 65dcddb15965c9de2c0365cb14910532 @@ -12314,7 +12148,7 @@ package: manager: conda platform: osx-arm64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.43-h091b4b1_0.conda hash: md5: 77e684ca58d82cae9deebafb95b1a2b8 @@ -12326,7 +12160,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -12343,7 +12177,7 @@ package: dependencies: krb5: '>=1.20.1,<1.21.0a0' libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<3.2.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libpq-15.2-hb675445_0.conda hash: @@ -12357,7 +12191,7 @@ package: platform: osx-64 dependencies: krb5: '>=1.20.1,<1.21.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<3.2.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libpq-15.2-h3640bf0_0.conda hash: @@ -12371,7 +12205,7 @@ package: platform: osx-arm64 dependencies: krb5: '>=1.20.1,<1.21.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<3.2.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libpq-15.2-h1a28acd_0.conda hash: @@ -12385,7 +12219,7 @@ package: platform: win-64 dependencies: krb5: '>=1.20.1,<1.21.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<3.2.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -12404,7 +12238,7 @@ package: libabseil: '>=20230125.3,<20230126.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.23.3-hd1fb520_1.conda hash: md5: 78c10e8637a6f8d377f9989327d0267d @@ -12418,7 +12252,7 @@ package: dependencies: libabseil: '>=20230125.3,<20230126.0a0' libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libprotobuf-4.23.3-h5feb325_1.conda hash: md5: 4b9dd0dfe441ea2b3588b582e820ad36 @@ -12432,7 +12266,7 @@ package: dependencies: libabseil: '>=20230125.3,<20230126.0a0' libcxx: '>=15.0.7' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-4.23.3-hf32f9b9_1.conda hash: md5: cdbf60d61de5e619297def60107a00c3 @@ -12445,7 +12279,7 @@ package: platform: win-64 dependencies: libabseil: '>=20230125.3,<20230126.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' @@ -12491,8 +12325,8 @@ package: python: '>=3.8' pandas: '>=1.4' scipy: '>=1.8' - numpy: '>=1.3' shapely: '>=2.0' + numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/libpysal-4.8.0-pyhd8ed1ab_1.conda hash: md5: ea5d04d8018c1f2ba75a1fd3c30e830b @@ -12513,8 +12347,8 @@ package: python: '>=3.8' pandas: '>=1.4' scipy: '>=1.8' - numpy: '>=1.3' shapely: '>=2.0' + numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/libpysal-4.8.0-pyhd8ed1ab_1.conda hash: md5: ea5d04d8018c1f2ba75a1fd3c30e830b @@ -12535,8 +12369,8 @@ package: python: '>=3.8' pandas: '>=1.4' scipy: '>=1.8' - numpy: '>=1.3' shapely: '>=2.0' + numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/libpysal-4.8.0-pyhd8ed1ab_1.conda hash: md5: ea5d04d8018c1f2ba75a1fd3c30e830b @@ -12553,7 +12387,7 @@ package: lcms2: '>=2.14,<3.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libraw-0.21.1-h89bc310_0.conda hash: md5: a86ff358d5725b53c87c0b8d2d8f68b5 @@ -12568,7 +12402,7 @@ package: jpeg: '>=9e,<10a' lcms2: '>=2.14,<3.0a0' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libraw-0.21.1-h7aa5921_0.conda hash: md5: 9bf754077ae0418cbfaca41d12175f75 @@ -12583,7 +12417,7 @@ package: jpeg: '>=9e,<10a' lcms2: '>=2.14,<3.0a0' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libraw-0.21.1-h1a38d6a_0.conda hash: md5: 620239c119b661bab66d37ad2468779c @@ -12597,7 +12431,7 @@ package: dependencies: jpeg: '>=9e,<10a' lcms2: '>=2.14,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -12729,57 +12563,57 @@ package: category: main optional: false - name: libspatialindex - version: 1.9.3 + version: 2.0.0 manager: conda platform: linux-64 dependencies: __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-1.9.3-he02047a_5.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.0.0-he02047a_0.conda hash: - md5: 659e6a5c5c7a811bd99e26375cb798b9 - sha256: 7ebebb444d6ca90d7fec78cf57289d0f22d93fd7ebdca9fc46f3c4e724b7b819 + md5: e7d2dcd1a058149ff9731a8dca39566e + sha256: 997a4fa13864dcb35ac9dfe87ed70fb3e9509dd071fa1951ac7f184e7ffcde5d category: main optional: false - name: libspatialindex - version: 1.9.3 + version: 2.0.0 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' libcxx: '>=16' - url: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-1.9.3-hf036a51_5.conda + url: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-2.0.0-hf036a51_0.conda hash: - md5: 256095bb52866eb63eba439b38f4c437 - sha256: ca339b16e824ec27a43692557fc30a5ea93422b93c3e98307dfed2a6a84e7baa + md5: bc0fc87124943452971c04425ce8c524 + sha256: 3ccd90ec2601ae38d72548c273018d8957afc36ae91d6ac95b1a4fc6fddbb9e1 category: main optional: false - name: libspatialindex - version: 1.9.3 + version: 2.0.0 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' libcxx: '>=16' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-1.9.3-h00cdb27_5.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.0.0-h00cdb27_0.conda hash: - md5: d2d54252bba0dd6cc740c9c3ff3fbce6 - sha256: 6220aacc140ea36c2c02a8a3979718c77b8ed6352bcfed5772df050000b28cff + md5: 774e9c4f835cb9b9fee3c3af9cfe0c28 + sha256: 111087f37e3ab7aff44c1870c94ccb67a87fd4924be13ca56042f36f1d18f8bf category: main optional: false - name: libspatialindex - version: 1.9.3 + version: 2.0.0 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-1.9.3-h5a68840_5.conda + url: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.0.0-h5a68840_0.conda hash: - md5: 97adbac1bbefbc8007bc9b47902fda68 - sha256: aba140efc10a8f3dd0895a6bb581df50f325de381785a30efb42728f4755ac85 + md5: 667559340fdf805ee1652de7b73e2b59 + sha256: 7802e6c51d59bc7e062841c525d772656708cdc44e42b6556493d345f08d7e50 category: main optional: false - name: libspatialite @@ -12794,7 +12628,7 @@ package: libsqlite: '>=3.40.0,<4.0a0' libstdcxx-ng: '>=12' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' sqlite: '' zlib: '' @@ -12816,7 +12650,7 @@ package: librttopo: '>=1.1.0,<1.2.0a0' libsqlite: '>=3.40.0,<4.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' sqlite: '' zlib: '' @@ -12838,7 +12672,7 @@ package: librttopo: '>=1.1.0,<1.2.0a0' libsqlite: '>=3.40.0,<4.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' sqlite: '' zlib: '' @@ -12858,7 +12692,7 @@ package: librttopo: '>=1.1.0,<1.2.0a0' libsqlite: '>=3.40.0,<4.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' proj: '>=9.1.1,<9.1.2.0a0' sqlite: '' ucrt: '>=10.0.20348.0' @@ -12872,54 +12706,56 @@ package: category: main optional: false - name: libsqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + libzlib: '>=1.2.13,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda hash: - md5: b3316cbe90249da4f8e84cd66e1cc55b - sha256: e2273d6860eadcf714a759ffb6dc24a69cfd01f2a0ea9d6c20f86049b9334e0c + md5: 18aa975d2094c34aef978060ae7da7d8 + sha256: daee3f68786231dad457d0dfde3f7f1f9a7f2018adabdbb864226775101341a8 category: main optional: false - name: libsqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: osx-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda + __osx: '>=10.13' + libzlib: '>=1.2.13,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda hash: - md5: 68e462226209f35182ef66eda0f794ff - sha256: 4d44b68fb29dcbc2216a8cae0b274b02ef9b4ae05d1d0f785362ed30b91c9b52 + md5: 5dadfbc1a567fe6e475df4ce3148be09 + sha256: 63af1a9e3284c7e4952364bafe7267e41e2d9d8bcc0e85a4ea4b0ec02d3693f6 category: main optional: false - name: libsqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: osx-arm64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda + __osx: '>=11.0' + libzlib: '>=1.2.13,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda hash: - md5: c8c1186c7f3351f6ffddb97b1f54fc58 - sha256: 4337f466eb55bbdc74e168b52ec8c38f598e3664244ec7a2536009036e2066cc + md5: 12300188028c9bc02da965128b91b517 + sha256: 73048f9cb8647d3d3bfe6021c0b7d663e12cffbe9b4f31bd081e713b0a9ad8f9 category: main optional: false - name: libsqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda hash: - md5: 73f5dc8e2d55d9a1e14b11f49c3b4a28 - sha256: 06ec75faa51d7ec6d5db98889e869b579a9df19d7d3d9baff8359627da4a3b7e + md5: 951b0a3a463932e17414cd9f047fa03d + sha256: 662bd7e0d63c5b8c31cca19b91649e798319b93568a2ba8d1375efb91eeb251b category: main optional: false - name: libssh2 @@ -12928,7 +12764,7 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda hash: @@ -12941,7 +12777,7 @@ package: manager: conda platform: osx-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda hash: @@ -12954,7 +12790,7 @@ package: manager: conda platform: osx-arm64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda hash: @@ -12967,7 +12803,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -12982,11 +12818,12 @@ package: version: 13.2.0 manager: conda platform: linux-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_7.conda + dependencies: + libgcc-ng: 13.2.0 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda hash: - md5: 53ebd4c833fa01cb2c6353e99f905406 - sha256: 35f1e08be0a84810c9075f5bd008495ac94e6c5fe306dfe4b34546f11fed850f + md5: eaa8ea74083fb4a78ae19e431e556003 + sha256: e03f0f2712f45a85234016bcc5afa76023e31e00a2e74d8819a1b3bdf091fdb0 category: main optional: false - name: libsystemd0 @@ -13109,7 +12946,7 @@ package: libevent: '>=2.1.10,<2.1.11.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h5e4af38_0.conda hash: @@ -13124,7 +12961,7 @@ package: dependencies: libcxx: '>=15.0.7' libevent: '>=2.1.12,<2.1.13.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libthrift-0.18.1-h88b220a_2.conda hash: @@ -13139,7 +12976,7 @@ package: dependencies: libcxx: '>=15.0.7' libevent: '>=2.1.12,<2.1.13.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libthrift-0.18.1-ha061701_2.conda hash: @@ -13153,7 +12990,7 @@ package: platform: win-64 dependencies: libevent: '>=2.1.12,<2.1.13.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.1,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -13175,7 +13012,7 @@ package: libgcc-ng: '>=12' libstdcxx-ng: '>=12' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.5.0-h6adf6a1_2.conda @@ -13194,7 +13031,7 @@ package: libcxx: '>=14.0.6' libdeflate: '>=1.17,<1.18.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.5.0-hee9004a_2.conda @@ -13213,7 +13050,7 @@ package: libcxx: '>=14.0.6' libdeflate: '>=1.17,<1.18.0a0' libwebp-base: '>=1.2.4,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' zstd: '>=1.5.2,<1.6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.5.0-h5dffbdd_2.conda @@ -13230,7 +13067,7 @@ package: jpeg: '>=9e,<10a' lerc: '>=4.0.0,<5.0a0' libdeflate: '>=1.17,<1.18.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -13645,7 +13482,7 @@ package: icu: '>=70.1,<71.0a0' libgcc-ng: '>=12' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.10.3-hca2bb57_4.conda hash: @@ -13660,7 +13497,7 @@ package: dependencies: icu: '>=70.1,<71.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.10.3-h201ad9d_4.conda hash: @@ -13675,7 +13512,7 @@ package: dependencies: icu: '>=70.1,<71.0a0' libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' xz: '>=5.2.6,<6.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.10.3-h67585b2_4.conda hash: @@ -13689,14 +13526,14 @@ package: platform: win-64 dependencies: libiconv: '>=1.17,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_1.conda hash: - md5: 1451be68a5549561979125c1827b79ed - sha256: e246fefa745b56c022063ba1b69ff2965f280c6eee3de9821184e7c8f2475eab + md5: 7ab2653cc21c44a1370ef3b409261b3d + sha256: aef096aa784e61f860fab08974c6260836bf05d742fb69f304f0e9b7d557c99a category: main optional: false - name: libzip @@ -13706,7 +13543,7 @@ package: dependencies: bzip2: '>=1.0.8,<2.0a0' libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda hash: @@ -13720,7 +13557,7 @@ package: platform: osx-64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.10.1-hc158999_3.conda hash: @@ -13734,7 +13571,7 @@ package: platform: osx-arm64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.10.1-ha0bc3c6_3.conda hash: @@ -13748,7 +13585,7 @@ package: platform: win-64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.2,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -13765,70 +13602,72 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda hash: - md5: f36c115f1ee199da648e0597ec2047ad - sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4 + md5: 27329162c0dc732bcf67a4e0cd488125 + sha256: 8ced4afed6322172182af503f21725d072a589a6eb918f8a58135c1e00d35980 category: main optional: false - name: libzlib version: 1.2.13 manager: conda platform: osx-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda + dependencies: + __osx: '>=10.13' + url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h87427d6_6.conda hash: - md5: 4a3ad23f6e16f99c04e166767193d700 - sha256: fc58ad7f47ffea10df1f2165369978fba0a1cc32594aad778f5eec725f334867 + md5: c0ef3c38a80c02ae1d86588c055184fc + sha256: 1c70fca0720685242b5c68956f310665c7ed43f04807aa4227322eee7925881c category: main optional: false - name: libzlib version: 1.2.13 manager: conda platform: osx-arm64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda + dependencies: + __osx: '>=11.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-hfb2fe0b_6.conda hash: - md5: 1a47f5236db2e06a320ffa0392f81bd8 - sha256: ab1c8aefa2d54322a63aaeeefe9cf877411851738616c4068e0dccc66b9c758a + md5: 9c4e121cd926cab631bd1c4a61d18b17 + sha256: 8b29a2386d99b8f58178951dcf19117b532cd9c4aa07623bf1667eae99755d32 category: main optional: false - name: libzlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda + url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda hash: - md5: 5fdb9c6a113b6b6cb5e517fd972d5f41 - sha256: c161822ee8130b71e08b6d282b9919c1de2c5274b29921a867bca0f7d30cad26 + md5: d4483ca8afc57ddf1f6dded53b36c17f + sha256: b13846a54a15243e15f96fec06b526d8155adc6a1ac2b6ed47a88f6a71a94b68 category: main optional: false - name: llvm-openmp - version: 18.1.5 + version: 18.1.7 manager: conda platform: osx-64 dependencies: - __osx: '>=10.9' - url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.5-h39e0ece_0.conda + __osx: '>=10.13' + url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.7-h15ab845_0.conda hash: - md5: ee12a644568269838b91f901b2537425 - sha256: 9efba1424726d83271727c494138ad1d519d5fed301f1ee5825019eae56f5570 + md5: 57440310d92e93efd808c75fec50f94d + sha256: 66ab0feed5ed7ace0d9327bc7ae47500afb81ef51e6ef10a478af9d65dd60ac6 category: main optional: false - name: llvm-openmp - version: 18.1.5 + version: 18.1.7 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.5-hde57baf_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.7-hde57baf_0.conda hash: - md5: 5b0ef7f8e9f413cbfd53573da96cae1b - sha256: c9ecaaa3d83215753a54f66038480582eff632196ed0df7763ca320154d00526 + md5: 2f651f8977594cc74852fa280785187a + sha256: 30121bc3ebf134d69bcb24ab1270bfa2beeb0ae59579b8acb67a38e3531c05d1 category: main optional: false - name: llvmlite @@ -13839,7 +13678,7 @@ package: libgcc-ng: '>=12' libllvm14: '>=14.0.6,<14.1.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* url: https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.40.1-py38h94a1851_0.conda @@ -13855,7 +13694,7 @@ package: dependencies: libcxx: '>=15.0.7' libllvm14: '>=14.0.6,<14.1.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* url: https://conda.anaconda.org/conda-forge/osx-64/llvmlite-0.40.1-py38hf646772_0.conda @@ -13871,7 +13710,7 @@ package: dependencies: libcxx: '>=15.0.7' libllvm14: '>=14.0.6,<14.1.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* url: https://conda.anaconda.org/conda-forge/osx-arm64/llvmlite-0.40.1-py38h761d82c_0.conda @@ -13885,7 +13724,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* ucrt: '>=10.0.20348.0' @@ -14138,6 +13977,58 @@ package: sha256: 78aadbd9953976678b6e3298ac26a63cf9390a8794db3ff71f3fe5b6d13a35ca category: main optional: false +- name: markdown-it-py + version: 3.0.0 + manager: conda + platform: linux-64 + dependencies: + mdurl: '>=0.1,<1' + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: 93a8e71256479c62074356ef6ebf501b + sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962 + category: main + optional: false +- name: markdown-it-py + version: 3.0.0 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + mdurl: '>=0.1,<1' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: 93a8e71256479c62074356ef6ebf501b + sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962 + category: main + optional: false +- name: markdown-it-py + version: 3.0.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + mdurl: '>=0.1,<1' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: 93a8e71256479c62074356ef6ebf501b + sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962 + category: main + optional: false +- name: markdown-it-py + version: 3.0.0 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + mdurl: '>=0.1,<1' + url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda + hash: + md5: 93a8e71256479c62074356ef6ebf501b + sha256: c041b0eaf7a6af3344d5dd452815cdc148d6284fec25a4fa3f4263b3a021e962 + category: main + optional: false - name: markupsafe version: 2.1.5 manager: conda @@ -14417,6 +14308,54 @@ package: sha256: 7ea68676ea35fbb095420bbcc1c82c4767b8be7bb56abb6989b7f89d957a3bab category: main optional: false +- name: mdurl + version: 0.1.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda + hash: + md5: 776a8dd9e824f77abac30e6ef43a8f7a + sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1 + category: main + optional: false +- name: mdurl + version: 0.1.2 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda + hash: + md5: 776a8dd9e824f77abac30e6ef43a8f7a + sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1 + category: main + optional: false +- name: mdurl + version: 0.1.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda + hash: + md5: 776a8dd9e824f77abac30e6ef43a8f7a + sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1 + category: main + optional: false +- name: mdurl + version: 0.1.2 + manager: conda + platform: win-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda + hash: + md5: 776a8dd9e824f77abac30e6ef43a8f7a + sha256: 64073dfb6bb429d52fff30891877b48c7ec0f89625b1bf844905b66a81cce6e1 + category: main + optional: false - name: metis version: 5.1.0 manager: conda @@ -14895,7 +14834,7 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-common: 8.0.33 openssl: '>=3.1.4,<4.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -14912,7 +14851,7 @@ package: dependencies: __osx: '>=10.9' libcxx: '>=16.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-common: 8.0.33 openssl: '>=3.1.4,<4.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -14929,7 +14868,7 @@ package: dependencies: __osx: '>=10.9' libcxx: '>=16.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-common: 8.0.33 openssl: '>=3.1.4,<4.0a0' zstd: '>=1.5.5,<1.6.0a0' @@ -15025,10 +14964,10 @@ package: python: '>=3.8' tinycss2: '' traitlets: '>=5.0' - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: - md5: 43d9cd74e3950ab09cbddf36f1706b9f - sha256: aa5bf61e42c63cec2b2c33e66cd0bb064846d62dd60f6ac62ae0d2bf17583900 + md5: e2d2abb421c13456a9a9f80272fdf543 + sha256: 074d858c5808e0a832acc0da37cd70de1565e8d6e17a62d5a11b3902b5e78319 category: main optional: false - name: nbconvert-core @@ -15053,10 +14992,10 @@ package: pygments: '>=2.4.1' nbclient: '>=0.5.0' mistune: '>=2.0.3,<4' - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: - md5: 43d9cd74e3950ab09cbddf36f1706b9f - sha256: aa5bf61e42c63cec2b2c33e66cd0bb064846d62dd60f6ac62ae0d2bf17583900 + md5: e2d2abb421c13456a9a9f80272fdf543 + sha256: 074d858c5808e0a832acc0da37cd70de1565e8d6e17a62d5a11b3902b5e78319 category: main optional: false - name: nbconvert-core @@ -15081,10 +15020,10 @@ package: pygments: '>=2.4.1' nbclient: '>=0.5.0' mistune: '>=2.0.3,<4' - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: - md5: 43d9cd74e3950ab09cbddf36f1706b9f - sha256: aa5bf61e42c63cec2b2c33e66cd0bb064846d62dd60f6ac62ae0d2bf17583900 + md5: e2d2abb421c13456a9a9f80272fdf543 + sha256: 074d858c5808e0a832acc0da37cd70de1565e8d6e17a62d5a11b3902b5e78319 category: main optional: false - name: nbconvert-core @@ -15109,10 +15048,10 @@ package: pygments: '>=2.4.1' nbclient: '>=0.5.0' mistune: '>=2.0.3,<4' - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: - md5: 43d9cd74e3950ab09cbddf36f1706b9f - sha256: aa5bf61e42c63cec2b2c33e66cd0bb064846d62dd60f6ac62ae0d2bf17583900 + md5: e2d2abb421c13456a9a9f80272fdf543 + sha256: 074d858c5808e0a832acc0da37cd70de1565e8d6e17a62d5a11b3902b5e78319 category: main optional: false - name: nbformat @@ -15399,7 +15338,7 @@ package: libgcc-ng: '>=12' libstdcxx-ng: '>=12' libuv: '>=1.44.2,<1.45.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/linux-64/nodejs-18.15.0-h8d033a5_0.conda @@ -15416,7 +15355,7 @@ package: icu: '>=70.1,<71.0a0' libcxx: '>=14.0.6' libuv: '>=1.44.2,<1.45.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-64/nodejs-18.15.0-hd0c9b3c_0.conda @@ -15433,7 +15372,7 @@ package: icu: '>=70.1,<71.0a0' libcxx: '>=14.0.6' libuv: '>=1.44.2,<1.45.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' zlib: '' url: https://conda.anaconda.org/conda-forge/osx-arm64/nodejs-18.15.0-h26a3f6d_0.conda @@ -15454,71 +15393,71 @@ package: category: main optional: false - name: notebook - version: 7.1.3 + version: 7.2.1 manager: conda platform: linux-64 dependencies: jupyter_server: '>=2.4.0,<3' - jupyterlab: '>=4.1.1,<4.2' - jupyterlab_server: '>=2.22.1,<3' + jupyterlab: '>=4.2.0,<4.3' + jupyterlab_server: '>=2.27.1,<3' notebook-shim: '>=0.2,<0.3' python: '>=3.8' tornado: '>=6.2.0' - url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.1.3-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: - md5: a4b1e12d54210fa80f3eb3fc270f2480 - sha256: 8ae08577df126ee1d583dcde59708928cca04ae405b1f38610a4bd44287f0e8e + md5: 08fa71a038c2cac2e636a5a456df15d5 + sha256: 6b23256e63225ff15b0d5e91d49111936df05748bb31afa321b29556087f85f4 category: main optional: false - name: notebook - version: 7.1.3 + version: 7.2.1 manager: conda platform: osx-64 dependencies: python: '>=3.8' tornado: '>=6.2.0' jupyter_server: '>=2.4.0,<3' - jupyterlab_server: '>=2.22.1,<3' notebook-shim: '>=0.2,<0.3' - jupyterlab: '>=4.1.1,<4.2' - url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.1.3-pyhd8ed1ab_0.conda + jupyterlab_server: '>=2.27.1,<3' + jupyterlab: '>=4.2.0,<4.3' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: - md5: a4b1e12d54210fa80f3eb3fc270f2480 - sha256: 8ae08577df126ee1d583dcde59708928cca04ae405b1f38610a4bd44287f0e8e + md5: 08fa71a038c2cac2e636a5a456df15d5 + sha256: 6b23256e63225ff15b0d5e91d49111936df05748bb31afa321b29556087f85f4 category: main optional: false - name: notebook - version: 7.1.3 + version: 7.2.1 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' tornado: '>=6.2.0' jupyter_server: '>=2.4.0,<3' - jupyterlab_server: '>=2.22.1,<3' notebook-shim: '>=0.2,<0.3' - jupyterlab: '>=4.1.1,<4.2' - url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.1.3-pyhd8ed1ab_0.conda + jupyterlab_server: '>=2.27.1,<3' + jupyterlab: '>=4.2.0,<4.3' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: - md5: a4b1e12d54210fa80f3eb3fc270f2480 - sha256: 8ae08577df126ee1d583dcde59708928cca04ae405b1f38610a4bd44287f0e8e + md5: 08fa71a038c2cac2e636a5a456df15d5 + sha256: 6b23256e63225ff15b0d5e91d49111936df05748bb31afa321b29556087f85f4 category: main optional: false - name: notebook - version: 7.1.3 + version: 7.2.1 manager: conda platform: win-64 dependencies: python: '>=3.8' tornado: '>=6.2.0' jupyter_server: '>=2.4.0,<3' - jupyterlab_server: '>=2.22.1,<3' notebook-shim: '>=0.2,<0.3' - jupyterlab: '>=4.1.1,<4.2' - url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.1.3-pyhd8ed1ab_0.conda + jupyterlab_server: '>=2.27.1,<3' + jupyterlab: '>=4.2.0,<4.3' + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: - md5: a4b1e12d54210fa80f3eb3fc270f2480 - sha256: 8ae08577df126ee1d583dcde59708928cca04ae405b1f38610a4bd44287f0e8e + md5: 08fa71a038c2cac2e636a5a456df15d5 + sha256: 6b23256e63225ff15b0d5e91d49111936df05748bb31afa321b29556087f85f4 category: main optional: false - name: notebook-shim @@ -15619,7 +15558,7 @@ package: libgcc-ng: '>=12' libsqlite: '>=3.45.3,<4.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nspr: '>=4.35,<5.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/nss-3.100-hca3bf56_0.conda hash: @@ -15635,7 +15574,7 @@ package: __osx: '>=10.13' libcxx: '>=16' libsqlite: '>=3.45.3,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nspr: '>=4.35,<5.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/nss-3.100-h6606ded_0.conda hash: @@ -15651,7 +15590,7 @@ package: __osx: '>=11.0' libcxx: '>=16' libsqlite: '>=3.45.3,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nspr: '>=4.35,<5.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.100-hc6e9f88_0.conda hash: @@ -15939,7 +15878,7 @@ package: imath: '>=3.1.5,<3.1.7.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/openexr-3.1.5-h0cdce71_2.conda hash: md5: 81da9b5c5aab30123e70d093bb4b3bdb @@ -15953,7 +15892,7 @@ package: dependencies: imath: '>=3.1.5,<3.1.7.0a0' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/openexr-3.1.5-h07d71dc_2.conda hash: md5: b52f840cde373f3a43708f4f932fed6e @@ -15967,7 +15906,7 @@ package: dependencies: imath: '>=3.1.5,<3.1.7.0a0' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/openexr-3.1.5-h25aad90_2.conda hash: md5: 1628221798073b879119ad9fde295826 @@ -15980,7 +15919,7 @@ package: platform: win-64 dependencies: imath: '>=3.1.5,<3.1.7.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -16050,7 +15989,7 @@ package: libpng: '>=1.6.39,<1.7.0a0' libstdcxx-ng: '>=12' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-hfec8fc6_2.conda hash: md5: 5ce6a42505c6e9e6151c54c3ec8d68ea @@ -16065,7 +16004,7 @@ package: libcxx: '>=14.0.6' libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.0-h13ac156_2.conda hash: md5: 299a29af9ac9f550ad459d655739280b @@ -16080,7 +16019,7 @@ package: libcxx: '>=14.0.6' libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.0-hbc2ba62_2.conda hash: md5: c3e184f0810a4614863569488b1ac709 @@ -16094,7 +16033,7 @@ package: dependencies: libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -16105,7 +16044,7 @@ package: category: main optional: false - name: openpyxl - version: 3.1.2 + version: 3.1.4 manager: conda platform: linux-64 dependencies: @@ -16113,42 +16052,42 @@ package: libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/openpyxl-3.1.2-py38h01eb140_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/openpyxl-3.1.4-py38h01eb140_0.conda hash: - md5: c4b769398a33fef331e912cf006b61f9 - sha256: d84cececd617f5c3c76c916fbd1dc57dd8c5d1a6f05700ef46fb4f2922094334 + md5: 324fb946900098065e7652a2519beda4 + sha256: 2963608e93b3041637ea0848e2bf84a0c9b8661431d4ab608dd1e01d2a2a101b category: main optional: false - name: openpyxl - version: 3.1.2 + version: 3.1.4 manager: conda platform: osx-64 dependencies: et_xmlfile: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/openpyxl-3.1.2-py38hcafd530_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/openpyxl-3.1.4-py38h51c390a_0.conda hash: - md5: b28918cf9d230e01fd01bc3392896c4f - sha256: 24af5585fa5d0ac0e825ccfafe002ddf520fa7de36457ef0955194b9b4f56e68 + md5: 5108ae9ccba756038615e1b06e27c27a + sha256: 287227ef116a33b97b3274c8a7645c144ce99e9d9fcc11c62252f240f690d794 category: main optional: false - name: openpyxl - version: 3.1.2 + version: 3.1.4 manager: conda platform: osx-arm64 dependencies: et_xmlfile: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/openpyxl-3.1.2-py38hb192615_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/openpyxl-3.1.4-py38had79a0c_0.conda hash: - md5: 974a0418923595d7349e31bb5e2dc176 - sha256: e80c883a4fd4dc0acce49492cb0b74576b4c3340675a6911e5a6897246793012 + md5: 9aae42212b31d50654efe50ae99fb6a9 + sha256: 1c7f509afd99fe08e2bfb96827df976c274817e97864ddb916a06c5e43d47115 category: main optional: false - name: openpyxl - version: 3.1.2 + version: 3.1.4 manager: conda platform: win-64 dependencies: @@ -16158,51 +16097,53 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/openpyxl-3.1.2-py38h91455d4_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/openpyxl-3.1.4-py38h91455d4_0.conda hash: - md5: 136e6ce65a3996b0f6286157425ddc0e - sha256: 8b04579aa00c6fad103f8a3b40a472f5a4dcdf6513075be21b3c3e3835abd394 + md5: d20f23f9a2a55558a52335f051f79e5d + sha256: 8789256475984597c54fe8f981c645be05af7cc652c74b7f772bb7c35534e603 category: main optional: false - name: openssl - version: 3.1.5 + version: 3.1.6 manager: conda platform: linux-64 dependencies: ca-certificates: '' libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.5-hd590300_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.6-h4ab18f5_0.conda hash: - md5: a6057a9b8f0bba4ab6ee3347a9b26b94 - sha256: 7f526336b39354c6ce18ead094efa0cb30b5747f252658cda3b23d0c9659e84e + md5: 371a0089f4c14239ecb919cf6d44b1ac + sha256: a666d9a71dd6a809c30c51f54df2f11f57e98f5d0edbd0a5f4940e892a076d77 category: main optional: false - name: openssl - version: 3.1.5 + version: 3.1.6 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' ca-certificates: '' - url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.1.5-hd75f5a5_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.1.6-h87427d6_0.conda hash: - md5: 15ec6b74c8c13b4fe3e261358b025b35 - sha256: 3808dfed712d797940c3d500292d0f023079a37104d4c1cdd0b294ed8d3e366f + md5: 588a4776e7997ee70bbc20553a88aa78 + sha256: 416901b2cf4a32d5627e0430cdf7752b7159c1759602103b84967b83259842ed category: main optional: false - name: openssl - version: 3.1.5 + version: 3.1.6 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' ca-certificates: '' - url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.1.5-h0d3ecfb_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.1.6-hfb2fe0b_0.conda hash: - md5: b0c17f6573cad81dbb35478b136f9c24 - sha256: 4bbe811bdf42cddd7bcf58c69951463c75de0b2fd505216f3b863550334aea3a + md5: 7438db81bc079230533e1238729ad6c5 + sha256: b40d6377bf5d0a357fd422de4be36732203d30c7cb1057e62afde182fe1f85dd category: main optional: false - name: openssl - version: 3.1.5 + version: 3.1.6 manager: conda platform: win-64 dependencies: @@ -16210,10 +16151,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.1.5-hcfcfb64_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.1.6-h2466b09_0.conda hash: - md5: 52b195d405023a270ab99448685f5f82 - sha256: e2ef8bd57a9b2fa46a80589e2ca988a7ef947b547e79b352acda9992987748ae + md5: 346201b080690d2b770a874d4ffa8180 + sha256: c1e5b2e5bbb693b9ddec975f2142fdb31707dd93e919e4cde92221ebab5720a0 category: main optional: false - name: orc @@ -16224,7 +16165,7 @@ package: libgcc-ng: '>=12' libprotobuf: '>=4.23.3,<4.23.4.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.2,<1.6.0a0' @@ -16241,7 +16182,7 @@ package: dependencies: libcxx: '>=15.0.7' libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.2,<1.6.0a0' @@ -16258,7 +16199,7 @@ package: dependencies: libcxx: '>=15.0.7' libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' zstd: '>=1.5.2,<1.6.0a0' @@ -16274,7 +16215,7 @@ package: platform: win-64 dependencies: libprotobuf: '>=4.23.3,<4.23.4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' snappy: '>=1.1.10,<1.2.0a0' ucrt: '>=10.0.20348.0' @@ -16287,6 +16228,61 @@ package: sha256: 05d5c8075c7b96868f056b6f38ffaf63bb9a119928f926f6913caade5b60db5e category: main optional: false +- name: orjson + version: 3.10.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/orjson-3.10.4-py38h31a4407_0.conda + hash: + md5: 7567de9ac0921ede5354462e7f2d069c + sha256: 3f78982926735e2ab67a77efe22f0c4149f66f9f8edb8f82e8c4f5df54470297 + category: main + optional: false +- name: orjson + version: 3.10.4 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/orjson-3.10.4-py38h2c15f49_0.conda + hash: + md5: bd899fa24071082e021593c95373b66d + sha256: ce5d9061d9f294c3cf3ac4b725b8f11c550f648244d47bcab0f3aa4d5dcf6f9e + category: main + optional: false +- name: orjson + version: 3.10.4 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/orjson-3.10.4-py38h186058e_0.conda + hash: + md5: b946c628b49ef67d725a8606415e7a2d + sha256: fe728309cece3ba21aeff932750c05b252247c2df85c9074fa5f59fd605b56c6 + category: main + optional: false +- name: orjson + version: 3.10.4 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/win-64/orjson-3.10.4-py38h5267af6_0.conda + hash: + md5: 1aa711fd0fe698c9474c7f4a3a63138b + sha256: da67ff90d3dc76a5dac3e63e4cca264a77aa20a808f5dd83a2557702801d7d49 + category: main + optional: false - name: osmnx version: 1.8.1 manager: conda @@ -16476,51 +16472,51 @@ package: category: main optional: false - name: packaging - version: '24.0' + version: '24.1' manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda hash: - md5: 248f521b64ce055e7feae3105e7abeb8 - sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a + md5: cbe1bb1f21567018ce595d9c2be0f0db + sha256: 36aca948219e2c9fdd6d80728bcc657519e02f06c2703d8db3446aec67f51d81 category: main optional: false - name: packaging - version: '24.0' + version: '24.1' manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda hash: - md5: 248f521b64ce055e7feae3105e7abeb8 - sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a + md5: cbe1bb1f21567018ce595d9c2be0f0db + sha256: 36aca948219e2c9fdd6d80728bcc657519e02f06c2703d8db3446aec67f51d81 category: main optional: false - name: packaging - version: '24.0' + version: '24.1' manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda hash: - md5: 248f521b64ce055e7feae3105e7abeb8 - sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a + md5: cbe1bb1f21567018ce595d9c2be0f0db + sha256: 36aca948219e2c9fdd6d80728bcc657519e02f06c2703d8db3446aec67f51d81 category: main optional: false - name: packaging - version: '24.0' + version: '24.1' manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda hash: - md5: 248f521b64ce055e7feae3105e7abeb8 - sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a + md5: cbe1bb1f21567018ce595d9c2be0f0db + sha256: 36aca948219e2c9fdd6d80728bcc657519e02f06c2703d8db3446aec67f51d81 category: main optional: false - name: pandas @@ -16821,7 +16817,7 @@ package: dependencies: bzip2: '>=1.0.8,<2.0a0' libgcc-ng: '>=12' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.40-hc3806b6_0.tar.bz2 hash: md5: 69e2c796349cd9b273890bee0febfe1b @@ -16834,7 +16830,7 @@ package: platform: osx-64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.40-h1c4e4bc_0.tar.bz2 hash: md5: e0f80c8f3a0352a54eddfe59cd2b25b1 @@ -16847,7 +16843,7 @@ package: platform: osx-arm64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.40-hb34f9b4_0.tar.bz2 hash: md5: 721b7288270bafc83586b0f01c2a67f2 @@ -16860,7 +16856,7 @@ package: platform: win-64 dependencies: bzip2: '>=1.0.8,<2.0a0' - libzlib: '>=1.2.12,<1.3.0a0' + libzlib: '>=1.2.12,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vs2015_runtime: '>=14.29.30139' @@ -17004,7 +17000,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openjpeg: '>=2.5.0,<3.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* @@ -17026,7 +17022,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openjpeg: '>=2.5.0,<3.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* @@ -17048,7 +17044,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openjpeg: '>=2.5.0,<3.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* @@ -17070,7 +17066,7 @@ package: libtiff: '>=4.5.0,<4.6.0a0' libwebp-base: '>=1.2.4,<2.0a0' libxcb: '>=1.13,<1.14.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openjpeg: '>=2.5.0,<3.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* @@ -17368,7 +17364,7 @@ package: category: main optional: false - name: pooch - version: 1.8.1 + version: 1.8.2 manager: conda platform: linux-64 dependencies: @@ -17376,14 +17372,14 @@ package: platformdirs: '>=2.5.0' python: '>=3.7' requests: '>=2.19.0' - url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: - md5: d15917f33140f8d2ac9ca44db7ec8a25 - sha256: 63f95e626754f5e05e74f39c0f4866aa8bd40b933eef336077978d365d66ca7b + md5: 8dab97d8a9616e07d779782995710aed + sha256: f2ee98740ac62ff46700c3cae8a18c78bdb3d6dd80832c6e691e789b844830d8 category: main optional: false - name: pooch - version: 1.8.1 + version: 1.8.2 manager: conda platform: osx-64 dependencies: @@ -17391,14 +17387,14 @@ package: packaging: '>=20.0' requests: '>=2.19.0' platformdirs: '>=2.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: - md5: d15917f33140f8d2ac9ca44db7ec8a25 - sha256: 63f95e626754f5e05e74f39c0f4866aa8bd40b933eef336077978d365d66ca7b + md5: 8dab97d8a9616e07d779782995710aed + sha256: f2ee98740ac62ff46700c3cae8a18c78bdb3d6dd80832c6e691e789b844830d8 category: main optional: false - name: pooch - version: 1.8.1 + version: 1.8.2 manager: conda platform: osx-arm64 dependencies: @@ -17406,14 +17402,14 @@ package: packaging: '>=20.0' requests: '>=2.19.0' platformdirs: '>=2.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: - md5: d15917f33140f8d2ac9ca44db7ec8a25 - sha256: 63f95e626754f5e05e74f39c0f4866aa8bd40b933eef336077978d365d66ca7b + md5: 8dab97d8a9616e07d779782995710aed + sha256: f2ee98740ac62ff46700c3cae8a18c78bdb3d6dd80832c6e691e789b844830d8 category: main optional: false - name: pooch - version: 1.8.1 + version: 1.8.2 manager: conda platform: win-64 dependencies: @@ -17421,10 +17417,10 @@ package: packaging: '>=20.0' requests: '>=2.19.0' platformdirs: '>=2.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: - md5: d15917f33140f8d2ac9ca44db7ec8a25 - sha256: 63f95e626754f5e05e74f39c0f4866aa8bd40b933eef336077978d365d66ca7b + md5: 8dab97d8a9616e07d779782995710aed + sha256: f2ee98740ac62ff46700c3cae8a18c78bdb3d6dd80832c6e691e789b844830d8 category: main optional: false - name: poppler @@ -17447,7 +17443,7 @@ package: libpng: '>=1.6.39,<1.7.0a0' libstdcxx-ng: '>=12' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nss: '>=3.88,<4.0a0' openjpeg: '>=2.5.0,<3.0a0' poppler-data: '' @@ -17476,7 +17472,7 @@ package: libiconv: '>=1.17,<2.0a0' libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nss: '>=3.88,<4.0a0' openjpeg: '>=2.5.0,<3.0a0' poppler-data: '' @@ -17505,7 +17501,7 @@ package: libiconv: '>=1.17,<2.0a0' libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' nss: '>=3.88,<4.0a0' openjpeg: '>=2.5.0,<3.0a0' poppler-data: '' @@ -17533,7 +17529,7 @@ package: libiconv: '>=1.17,<2.0a0' libpng: '>=1.6.39,<1.7.0a0' libtiff: '>=4.5.0,<4.6.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openjpeg: '>=2.5.0,<3.0a0' poppler-data: '' ucrt: '>=10.0.20348.0' @@ -17598,7 +17594,7 @@ package: libgcc-ng: '>=12' libpq: '15.2' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<4.0a0' readline: '>=8.1.2,<9.0a0' tzcode: '' @@ -17618,7 +17614,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libpq: '15.2' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<4.0a0' readline: '>=8.1.2,<9.0a0' tzcode: '' @@ -17638,7 +17634,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libpq: '15.2' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<4.0a0' readline: '>=8.1.2,<9.0a0' tzcode: '' @@ -17658,7 +17654,7 @@ package: krb5: '>=1.20.1,<1.21.0a0' libpq: '15.3' libxml2: '>=2.11.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.0,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -17882,103 +17878,103 @@ package: category: main optional: false - name: prompt-toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: linux-64 dependencies: python: '>=3.7' wcwidth: '' - url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: - md5: 0bf64bf10eee21f46ac83c161917fa86 - sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16 + md5: 1247c861065d227781231950e14fe817 + sha256: d93ac5853e398aaa10f0dd7addd64b411f94ace1f9104d619cd250e19a5ac5b4 category: main optional: false - name: prompt-toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: osx-64 dependencies: wcwidth: '' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: - md5: 0bf64bf10eee21f46ac83c161917fa86 - sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16 + md5: 1247c861065d227781231950e14fe817 + sha256: d93ac5853e398aaa10f0dd7addd64b411f94ace1f9104d619cd250e19a5ac5b4 category: main optional: false - name: prompt-toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: osx-arm64 dependencies: wcwidth: '' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: - md5: 0bf64bf10eee21f46ac83c161917fa86 - sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16 + md5: 1247c861065d227781231950e14fe817 + sha256: d93ac5853e398aaa10f0dd7addd64b411f94ace1f9104d619cd250e19a5ac5b4 category: main optional: false - name: prompt-toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: win-64 dependencies: wcwidth: '' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: - md5: 0bf64bf10eee21f46ac83c161917fa86 - sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16 + md5: 1247c861065d227781231950e14fe817 + sha256: d93ac5853e398aaa10f0dd7addd64b411f94ace1f9104d619cd250e19a5ac5b4 category: main optional: false - name: prompt_toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: linux-64 dependencies: - prompt-toolkit: '>=3.0.42,<3.0.43.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + prompt-toolkit: '>=3.0.47,<3.0.48.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda hash: - md5: 85a2189ecd2fcdd86e92b2d4ea8fe461 - sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d + md5: 3e0c82ddcfe27eb4ae77f887cfd9f45b + sha256: 081ef6c9fbc280940c8d65683371795a8876cd4994b3fbdd0ccda7cc3ee87f74 category: main optional: false - name: prompt_toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: osx-64 dependencies: - prompt-toolkit: '>=3.0.42,<3.0.43.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + prompt-toolkit: '>=3.0.47,<3.0.48.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda hash: - md5: 85a2189ecd2fcdd86e92b2d4ea8fe461 - sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d + md5: 3e0c82ddcfe27eb4ae77f887cfd9f45b + sha256: 081ef6c9fbc280940c8d65683371795a8876cd4994b3fbdd0ccda7cc3ee87f74 category: main optional: false - name: prompt_toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: osx-arm64 dependencies: - prompt-toolkit: '>=3.0.42,<3.0.43.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + prompt-toolkit: '>=3.0.47,<3.0.48.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda hash: - md5: 85a2189ecd2fcdd86e92b2d4ea8fe461 - sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d + md5: 3e0c82ddcfe27eb4ae77f887cfd9f45b + sha256: 081ef6c9fbc280940c8d65683371795a8876cd4994b3fbdd0ccda7cc3ee87f74 category: main optional: false - name: prompt_toolkit - version: 3.0.42 + version: 3.0.47 manager: conda platform: win-64 dependencies: - prompt-toolkit: '>=3.0.42,<3.0.43.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + prompt-toolkit: '>=3.0.47,<3.0.48.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda hash: - md5: 85a2189ecd2fcdd86e92b2d4ea8fe461 - sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d + md5: 3e0c82ddcfe27eb4ae77f887cfd9f45b + sha256: 081ef6c9fbc280940c8d65683371795a8876cd4994b3fbdd0ccda7cc3ee87f74 category: main optional: false - name: psutil @@ -18540,6 +18536,128 @@ package: sha256: 406001ebf017688b1a1554b49127ca3a4ac4626ec0fd51dc75ffa4415b720b64 category: main optional: false +- name: pydantic + version: 2.7.4 + manager: conda + platform: linux-64 + dependencies: + annotated-types: '>=0.4.0' + pydantic-core: 2.18.4 + python: '>=3.7' + typing-extensions: '>=4.6.1' + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + hash: + md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 + sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + category: main + optional: false +- name: pydantic + version: 2.7.4 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.1' + annotated-types: '>=0.4.0' + pydantic-core: 2.18.4 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + hash: + md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 + sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + category: main + optional: false +- name: pydantic + version: 2.7.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.1' + annotated-types: '>=0.4.0' + pydantic-core: 2.18.4 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + hash: + md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 + sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + category: main + optional: false +- name: pydantic + version: 2.7.4 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7' + typing-extensions: '>=4.6.1' + annotated-types: '>=0.4.0' + pydantic-core: 2.18.4 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + hash: + md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 + sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + category: main + optional: false +- name: pydantic-core + version: 2.18.4 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing-extensions: '>=4.6.0,!=4.7.0' + url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.4-py38h31a4407_0.conda + hash: + md5: 70e3a9f41eed4af00034a0927c36d09a + sha256: a8f6fbce9f4ed00371a8beee8b2b18b931c76ed795435f4ae68e29b032dd7583 + category: main + optional: false +- name: pydantic-core + version: 2.18.4 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing-extensions: '>=4.6.0,!=4.7.0' + url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.4-py38h2c15f49_0.conda + hash: + md5: a309f1a13d51e35670e9f024933af351 + sha256: 88911f8585d7c31853a24859036c82270306e1c7db66115215ddf8ec7e735a6c + category: main + optional: false +- name: pydantic-core + version: 2.18.4 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing-extensions: '>=4.6.0,!=4.7.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.4-py38h186058e_0.conda + hash: + md5: 47c3a719453bcf59dae095c7e27855c0 + sha256: 16851b8531654aa58ea3bf164d129da834a77e80bf056af1d4e1063b88bae0aa + category: main + optional: false +- name: pydantic-core + version: 2.18.4 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing-extensions: '>=4.6.0,!=4.7.0' + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.4-py38h2e0ef18_0.conda + hash: + md5: 9e531114195444f790af7c877ae40bad + sha256: 60ff0f8f015195b479f0498d2fcb898c1d12837e9787c211e350151f21689ce2 + category: main + optional: false - name: pygments version: 2.18.0 manager: conda @@ -18589,33 +18707,35 @@ package: category: main optional: false - name: pyobjc-core - version: '10.2' + version: 10.3.1 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libffi: '>=3.4,<4.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* setuptools: '' - url: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-10.2-py38h37016ba_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-10.3.1-py38h39ae85e_0.conda hash: - md5: 929652fa773bf841f11d25c3e2594995 - sha256: 1fb035bb9f9ee24bbd64289edc05b5696d3370afdaa26c5b9d132e1ec311b358 + md5: 0f28b9438a4e34eedc9161bed9ca90f3 + sha256: 7a64d079f87b6600282d6be7b7ce3b0279b776f6117a485866a35eab22d6405f category: main optional: false - name: pyobjc-framework-cocoa - version: '10.2' + version: 10.3.1 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libffi: '>=3.4,<4.0a0' - pyobjc-core: 10.2.* + pyobjc-core: 10.3.1.* python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-10.2-py38h37016ba_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-framework-cocoa-10.3.1-py38h39ae85e_0.conda hash: - md5: ef32eeb9ce04dadbfaa1a350c2d060ea - sha256: e133322ff5ff2d9c6278e096f024491ef477505d7034c620e13c77216d83fe3f + md5: 892605ba2858937c8dddce0319ed5108 + sha256: 2b80783a507f2d704ab7ff8152e211c564281c6ac2a64cb51af2ae64dfd75266 category: main optional: false - name: pyparsing @@ -18804,62 +18924,6 @@ package: sha256: a915c7a5f07d9fd9ef97237209d0d8b702edb24766535efd3da58d4de7c7eea5 category: main optional: false -- name: pyrsistent - version: 0.20.0 - manager: conda - platform: linux-64 - dependencies: - libgcc-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/pyrsistent-0.20.0-py38h01eb140_0.conda - hash: - md5: ff3d93675ba4026f33a6ca0348f5a324 - sha256: 99f879461313a4a62e6495a397d517d1b01151d70a3e25023d205bd6ad0a5dc7 - category: main - optional: false -- name: pyrsistent - version: 0.20.0 - manager: conda - platform: osx-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/pyrsistent-0.20.0-py38hae2e43d_0.conda - hash: - md5: c568725e645b82bacadbfa3602c9497a - sha256: db4d33555cd0824435b9667c18da5cd45e9dcc61850d58444532f6852510dee8 - category: main - optional: false -- name: pyrsistent - version: 0.20.0 - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/pyrsistent-0.20.0-py38h336bac9_0.conda - hash: - md5: ff86a0eb7fa71fb1028b0f40799c992f - sha256: 18c1a37b9c0325cadce8758c56e245a3cc0e470220dcffacc27e0338bff7d2af - category: main - optional: false -- name: pyrsistent - version: 0.20.0 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/pyrsistent-0.20.0-py38h91455d4_0.conda - hash: - md5: e15aa0c79c1cdc6161e228204ee5fc74 - sha256: cb14ad975285269979f3e11cca66318358e15c08e8caa73f0e850a4efc04abf9 - category: main - optional: false - name: pysocks version: 1.7.1 manager: conda @@ -18925,7 +18989,7 @@ package: libnsl: '>=2.0.0,<2.1.0a0' libsqlite: '>=3.43.0,<4.0a0' libuuid: '>=2.38.1,<3.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ncurses: '>=6.4,<7.0a0' openssl: '>=3.1.3,<4.0a0' readline: '>=8.2,<9.0a0' @@ -18945,7 +19009,7 @@ package: bzip2: '>=1.0.8,<2.0a0' libffi: '>=3.4,<4.0a0' libsqlite: '>=3.43.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ncurses: '>=6.4,<7.0a0' openssl: '>=3.1.3,<4.0a0' readline: '>=8.2,<9.0a0' @@ -18965,7 +19029,7 @@ package: bzip2: '>=1.0.8,<2.0a0' libffi: '>=3.4,<4.0a0' libsqlite: '>=3.43.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ncurses: '>=6.4,<7.0a0' openssl: '>=3.1.3,<4.0a0' readline: '>=8.2,<9.0a0' @@ -18985,7 +19049,7 @@ package: bzip2: '>=1.0.8,<2.0a0' libffi: '>=3.4,<4.0a0' libsqlite: '>=3.43.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.1.3,<4.0a0' tk: '>=8.6.13,<8.7.0a0' vc: '>=14.1,<15' @@ -19050,103 +19114,103 @@ package: category: main optional: false - name: python-engineio - version: 4.8.2 + version: 4.9.1 manager: conda platform: linux-64 dependencies: python: '>=3.6' simple-websocket: '>=0.10.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.8.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.9.1-pyhd8ed1ab_0.conda hash: - md5: 517918f17b050da47a8ccad8e31a91e7 - sha256: 79cda67b834ec235be5a8a875d681d2fe1637c09bd056a303b5423f10676ed99 + md5: 14eac7853ce0afb52fab40521d8ed9f7 + sha256: 6c08cddefa3c848b084990dd9bce861af1b6ebe18a82c671531eed5530cd4289 category: main optional: false - name: python-engineio - version: 4.8.2 + version: 4.9.1 manager: conda platform: osx-64 dependencies: python: '>=3.6' simple-websocket: '>=0.10.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.8.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.9.1-pyhd8ed1ab_0.conda hash: - md5: 517918f17b050da47a8ccad8e31a91e7 - sha256: 79cda67b834ec235be5a8a875d681d2fe1637c09bd056a303b5423f10676ed99 + md5: 14eac7853ce0afb52fab40521d8ed9f7 + sha256: 6c08cddefa3c848b084990dd9bce861af1b6ebe18a82c671531eed5530cd4289 category: main optional: false - name: python-engineio - version: 4.8.2 + version: 4.9.1 manager: conda platform: osx-arm64 dependencies: python: '>=3.6' simple-websocket: '>=0.10.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.8.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.9.1-pyhd8ed1ab_0.conda hash: - md5: 517918f17b050da47a8ccad8e31a91e7 - sha256: 79cda67b834ec235be5a8a875d681d2fe1637c09bd056a303b5423f10676ed99 + md5: 14eac7853ce0afb52fab40521d8ed9f7 + sha256: 6c08cddefa3c848b084990dd9bce861af1b6ebe18a82c671531eed5530cd4289 category: main optional: false - name: python-engineio - version: 4.8.2 + version: 4.9.1 manager: conda platform: win-64 dependencies: python: '>=3.6' simple-websocket: '>=0.10.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.8.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-engineio-4.9.1-pyhd8ed1ab_0.conda hash: - md5: 517918f17b050da47a8ccad8e31a91e7 - sha256: 79cda67b834ec235be5a8a875d681d2fe1637c09bd056a303b5423f10676ed99 + md5: 14eac7853ce0afb52fab40521d8ed9f7 + sha256: 6c08cddefa3c848b084990dd9bce861af1b6ebe18a82c671531eed5530cd4289 category: main optional: false - name: python-fastjsonschema - version: 2.19.1 + version: 2.20.0 manager: conda platform: linux-64 dependencies: python: '>=3.3' - url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda hash: - md5: 4d3ceee3af4b0f9a1f48f57176bf8625 - sha256: 38b2db169d65cc5595e3ce63294c4fdb6a242ecf71f70b3ad8cad3bd4230d82f + md5: b98d2018c01ce9980c03ee2850690fab + sha256: 7d8c931b89c9980434986b4deb22c2917b58d9936c3974139b9c10ae86fdfe60 category: main optional: false - name: python-fastjsonschema - version: 2.19.1 + version: 2.20.0 manager: conda platform: osx-64 dependencies: python: '>=3.3' - url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda hash: - md5: 4d3ceee3af4b0f9a1f48f57176bf8625 - sha256: 38b2db169d65cc5595e3ce63294c4fdb6a242ecf71f70b3ad8cad3bd4230d82f + md5: b98d2018c01ce9980c03ee2850690fab + sha256: 7d8c931b89c9980434986b4deb22c2917b58d9936c3974139b9c10ae86fdfe60 category: main optional: false - name: python-fastjsonschema - version: 2.19.1 + version: 2.20.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.3' - url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda hash: - md5: 4d3ceee3af4b0f9a1f48f57176bf8625 - sha256: 38b2db169d65cc5595e3ce63294c4fdb6a242ecf71f70b3ad8cad3bd4230d82f + md5: b98d2018c01ce9980c03ee2850690fab + sha256: 7d8c931b89c9980434986b4deb22c2917b58d9936c3974139b9c10ae86fdfe60 category: main optional: false - name: python-fastjsonschema - version: 2.19.1 + version: 2.20.0 manager: conda platform: win-64 dependencies: python: '>=3.3' - url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda hash: - md5: 4d3ceee3af4b0f9a1f48f57176bf8625 - sha256: 38b2db169d65cc5595e3ce63294c4fdb6a242ecf71f70b3ad8cad3bd4230d82f + md5: b98d2018c01ce9980c03ee2850690fab + sha256: 7d8c931b89c9980434986b4deb22c2917b58d9936c3974139b9c10ae86fdfe60 category: main optional: false - name: python-json-logger @@ -19197,60 +19261,108 @@ package: sha256: 4790787fe1f4e8da616edca4acf6a4f8ed4e7c6967aa31b920208fc8f95efcca category: main optional: false +- name: python-multipart + version: 0.0.9 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.9-pyhd8ed1ab_0.conda + hash: + md5: 0eef653965f0fed2013924d08089f371 + sha256: 026467128031bd667c4a32555ae07e922d5caed257e4815c44e7338887bbd56a + category: main + optional: false +- name: python-multipart + version: 0.0.9 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.9-pyhd8ed1ab_0.conda + hash: + md5: 0eef653965f0fed2013924d08089f371 + sha256: 026467128031bd667c4a32555ae07e922d5caed257e4815c44e7338887bbd56a + category: main + optional: false +- name: python-multipart + version: 0.0.9 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.9-pyhd8ed1ab_0.conda + hash: + md5: 0eef653965f0fed2013924d08089f371 + sha256: 026467128031bd667c4a32555ae07e922d5caed257e4815c44e7338887bbd56a + category: main + optional: false +- name: python-multipart + version: 0.0.9 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/python-multipart-0.0.9-pyhd8ed1ab_0.conda + hash: + md5: 0eef653965f0fed2013924d08089f371 + sha256: 026467128031bd667c4a32555ae07e922d5caed257e4815c44e7338887bbd56a + category: main + optional: false - name: python-socketio - version: 5.11.2 + version: 5.11.3 manager: conda platform: linux-64 dependencies: bidict: '>=0.21.0' python: '>=3.8' python-engineio: '>=4.8.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: - md5: 08c4689825cdf902fc643a6a0934068e - sha256: 620ccfb5a976b120940ad2a90c9c5d302804762617d5f60014ba83dd5a022373 + md5: 78e3caeea4f35550e3bcab8aff208644 + sha256: a4eeb36dd0f9f9f7a3b4e7141b3cd11c47d4399b296f98b9001b7b3bf21fccac category: main optional: false - name: python-socketio - version: 5.11.2 + version: 5.11.3 manager: conda platform: osx-64 dependencies: python: '>=3.8' bidict: '>=0.21.0' python-engineio: '>=4.8.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: - md5: 08c4689825cdf902fc643a6a0934068e - sha256: 620ccfb5a976b120940ad2a90c9c5d302804762617d5f60014ba83dd5a022373 + md5: 78e3caeea4f35550e3bcab8aff208644 + sha256: a4eeb36dd0f9f9f7a3b4e7141b3cd11c47d4399b296f98b9001b7b3bf21fccac category: main optional: false - name: python-socketio - version: 5.11.2 + version: 5.11.3 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' bidict: '>=0.21.0' python-engineio: '>=4.8.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: - md5: 08c4689825cdf902fc643a6a0934068e - sha256: 620ccfb5a976b120940ad2a90c9c5d302804762617d5f60014ba83dd5a022373 + md5: 78e3caeea4f35550e3bcab8aff208644 + sha256: a4eeb36dd0f9f9f7a3b4e7141b3cd11c47d4399b296f98b9001b7b3bf21fccac category: main optional: false - name: python-socketio - version: 5.11.2 + version: 5.11.3 manager: conda platform: win-64 dependencies: python: '>=3.8' bidict: '>=0.21.0' python-engineio: '>=4.8.0' - url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: - md5: 08c4689825cdf902fc643a6a0934068e - sha256: 620ccfb5a976b120940ad2a90c9c5d302804762617d5f60014ba83dd5a022373 + md5: 78e3caeea4f35550e3bcab8aff208644 + sha256: a4eeb36dd0f9f9f7a3b4e7141b3cd11c47d4399b296f98b9001b7b3bf21fccac category: main optional: false - name: python-tzdata @@ -19661,7 +19773,7 @@ package: libxcb: '>=1.13,<1.14.0a0' libxkbcommon: '>=1.0.3,<2.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-libs: '>=8.0.32,<8.1.0a0' nspr: '>=4.35,<5.0a0' nss: '>=3.82,<4.0a0' @@ -19695,7 +19807,7 @@ package: libpng: '>=1.6.39,<1.7.0a0' libpq: '>=15.1,<16.0a0' libsqlite: '>=3.40.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-libs: '>=8.0.31,<8.1.0a0' nspr: '>=4.35,<5.0a0' nss: '>=3.78,<4.0a0' @@ -19723,7 +19835,7 @@ package: libpng: '>=1.6.39,<1.7.0a0' libpq: '>=15.1,<16.0a0' libsqlite: '>=3.40.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' mysql-libs: '>=8.0.31,<8.1.0a0' nspr: '>=4.35,<5.0a0' nss: '>=3.78,<4.0a0' @@ -19749,7 +19861,7 @@ package: libglib: '>=2.74.1,<3.0a0' libpng: '>=1.6.39,<1.7.0a0' libsqlite: '>=3.40.0,<4.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' openssl: '>=3.0.8,<4.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' @@ -20019,68 +20131,124 @@ package: sha256: a1dfa679ac3f6007362386576a704ad2d0d7a02e98f5d0b115f207a2da63e884 category: main optional: false +- name: referencing + version: 0.35.1 + manager: conda + platform: linux-64 + dependencies: + attrs: '>=22.2.0' + python: '>=3.8' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda + hash: + md5: 0fc8b52192a8898627c3efae1003e9f6 + sha256: be8d6d9e86b1a3fef5424127ff81782f8ca63d3058980859609f6f1ecdd34cb3 + category: main + optional: false +- name: referencing + version: 0.35.1 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + attrs: '>=22.2.0' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda + hash: + md5: 0fc8b52192a8898627c3efae1003e9f6 + sha256: be8d6d9e86b1a3fef5424127ff81782f8ca63d3058980859609f6f1ecdd34cb3 + category: main + optional: false +- name: referencing + version: 0.35.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + attrs: '>=22.2.0' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda + hash: + md5: 0fc8b52192a8898627c3efae1003e9f6 + sha256: be8d6d9e86b1a3fef5424127ff81782f8ca63d3058980859609f6f1ecdd34cb3 + category: main + optional: false +- name: referencing + version: 0.35.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + attrs: '>=22.2.0' + rpds-py: '>=0.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda + hash: + md5: 0fc8b52192a8898627c3efae1003e9f6 + sha256: be8d6d9e86b1a3fef5424127ff81782f8ca63d3058980859609f6f1ecdd34cb3 + category: main + optional: false - name: requests - version: 2.31.0 + version: 2.32.3 manager: conda platform: linux-64 dependencies: certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' idna: '>=2.5,<4' - python: '>=3.7' + python: '>=3.8' urllib3: '>=1.21.1,<3' - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: - md5: a30144e4156cdbb236f99ebb49828f8b - sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + md5: 5ede4753180c7a550a443c430dc8ab52 + sha256: 5845ffe82a6fa4d437a2eae1e32a1ad308d7ad349f61e337c0a890fe04c513cc category: main optional: false - name: requests - version: 2.31.0 + version: 2.32.3 manager: conda platform: osx-64 dependencies: - python: '>=3.7' + python: '>=3.8' idna: '>=2.5,<4' certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' urllib3: '>=1.21.1,<3' - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: - md5: a30144e4156cdbb236f99ebb49828f8b - sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + md5: 5ede4753180c7a550a443c430dc8ab52 + sha256: 5845ffe82a6fa4d437a2eae1e32a1ad308d7ad349f61e337c0a890fe04c513cc category: main optional: false - name: requests - version: 2.31.0 + version: 2.32.3 manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' + python: '>=3.8' idna: '>=2.5,<4' certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' urllib3: '>=1.21.1,<3' - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: - md5: a30144e4156cdbb236f99ebb49828f8b - sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + md5: 5ede4753180c7a550a443c430dc8ab52 + sha256: 5845ffe82a6fa4d437a2eae1e32a1ad308d7ad349f61e337c0a890fe04c513cc category: main optional: false - name: requests - version: 2.31.0 + version: 2.32.3 manager: conda platform: win-64 dependencies: - python: '>=3.7' + python: '>=3.8' idna: '>=2.5,<4' certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' urllib3: '>=1.21.1,<3' - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: - md5: a30144e4156cdbb236f99ebb49828f8b - sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad + md5: 5ede4753180c7a550a443c430dc8ab52 + sha256: 5845ffe82a6fa4d437a2eae1e32a1ad308d7ad349f61e337c0a890fe04c513cc category: main optional: false - name: rfc3339-validator @@ -20183,18 +20351,136 @@ package: sha256: 2a5b495a1de0f60f24d8a74578ebc23b24aa53279b1ad583755f223097c41c37 category: main optional: false +- name: rich + version: 13.7.1 + manager: conda + platform: linux-64 + dependencies: + markdown-it-py: '>=2.2.0' + pygments: '>=2.13.0,<3.0.0' + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda + hash: + md5: ba445bf767ae6f0d959ff2b40c20912b + sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667 + category: main + optional: false +- name: rich + version: 13.7.1 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + pygments: '>=2.13.0,<3.0.0' + markdown-it-py: '>=2.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda + hash: + md5: ba445bf767ae6f0d959ff2b40c20912b + sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667 + category: main + optional: false +- name: rich + version: 13.7.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + pygments: '>=2.13.0,<3.0.0' + markdown-it-py: '>=2.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda + hash: + md5: ba445bf767ae6f0d959ff2b40c20912b + sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667 + category: main + optional: false +- name: rich + version: 13.7.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7.0' + typing_extensions: '>=4.0.0,<5.0.0' + pygments: '>=2.13.0,<3.0.0' + markdown-it-py: '>=2.2.0' + url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda + hash: + md5: ba445bf767ae6f0d959ff2b40c20912b + sha256: 2b26d58aa59e46f933c3126367348651b0dab6e0bf88014e857415bb184a4667 + category: main + optional: false +- name: rpds-py + version: 0.18.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.18.1-py38h31a4407_0.conda + hash: + md5: cf9114ac315a75ef2cbb68c4fcbb5559 + sha256: f892a7a48b54dc982f0921e6878c2feee5304726151075dca91aeab059652ad5 + category: main + optional: false +- name: rpds-py + version: 0.18.1 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.18.1-py38h2c15f49_0.conda + hash: + md5: 208479e5daacf3cdeed1baf811b7b7d7 + sha256: 3f3ff557b564de1a81cc2e5c849887a9fb190dd417605ba154f5f2eb047da09b + category: main + optional: false +- name: rpds-py + version: 0.18.1 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.18.1-py38h186058e_0.conda + hash: + md5: 49de491baa738aa885652276f228e6f5 + sha256: b3cbca052f28426d56cccbf1b0b92d074d6aa5a8801a20428f7e234a4acfd490 + category: main + optional: false +- name: rpds-py + version: 0.18.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.18.1-py38h2e0ef18_0.conda + hash: + md5: 59e7e8163e8e8eff0d5d51591879e8d8 + sha256: 4e098feccfd60abb17f9f64fa21ea87db357907d5e16c03c347290da69a29e34 + category: main + optional: false - name: rtree version: 1.2.0 manager: conda platform: linux-64 dependencies: - libspatialindex: '>=1.9.3,<1.9.4.0a0' + libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py38h02d302b_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py38hcf07b61_1.conda hash: - md5: 04bcc0eaa990f0461a36189d2ac90269 - sha256: f6fc9650a93ed0e92946fc9e8e97ae0cd28f714fba51855cb941642ad57a2a34 + md5: eba2af11ad65758b20ea379f925bebaa + sha256: f40795a4f818bcec13cb15a2b23f3014ec1d2d28f6cb8e94f2e76ed6579403eb category: main optional: false - name: rtree @@ -20202,13 +20488,13 @@ package: manager: conda platform: osx-64 dependencies: - libspatialindex: '>=1.9.3,<1.9.4.0a0' + libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py38hc59ffc2_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py38h2d351f8_1.conda hash: - md5: ac7f8e6bca6f898b13c4c13fbcd785d9 - sha256: 1db78d2ee154ed9233d29c71bd7cced3a96e375a653b61a0b9b7765be06521e1 + md5: 00295fe0031c1b6160f96ed2fab4050c + sha256: e70e23345261a99fa0cb174dfdc04ffe76a76087f8f4be9fa7992a849d885516 category: main optional: false - name: rtree @@ -20216,13 +20502,13 @@ package: manager: conda platform: osx-arm64 dependencies: - libspatialindex: '>=1.9.3,<1.9.4.0a0' + libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py38hb34dff0_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py38h7841be0_1.conda hash: - md5: 6f9fb368165858a8d34ac036596b3546 - sha256: 478a8f9d959bc5b0d92cad4822d730090e6b9e5b4ee13ec64ce4cb70f9f01542 + md5: 0b91970b11d93f330b6b4d746d45bc84 + sha256: db3aeeaeac6dd03cb908a4240ab5d7f76f20e4e69e23a537e22e5bab106bdc00 category: main optional: false - name: rtree @@ -20230,13 +20516,13 @@ package: manager: conda platform: win-64 dependencies: - libspatialindex: '>=1.9.3,<1.9.4.0a0' + libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py38h8b54edf_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py38ha8ef549_1.conda hash: - md5: 968b1cdb76e1549b09066fda19bddf5c - sha256: c350e6f6220d6ef485c310c6e3eed37eb41910581c4fb49a94f0ffe38620e62b + md5: 87e570febe511a49a784797e0e44a68b + sha256: 40754ecf98cbd473fd589aa7a1aa9dc6b3304cbaa729c40a9add53770f871edc category: main optional: false - name: s2n @@ -20545,51 +20831,51 @@ package: category: main optional: false - name: setuptools - version: 69.5.1 + version: 70.1.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda hash: - md5: 7462280d81f639363e6e63c81276bd9e - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 + md5: 258e66f95f814d51ada2a1fe9274039b + sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 category: main optional: false - name: setuptools - version: 69.5.1 + version: 70.1.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda hash: - md5: 7462280d81f639363e6e63c81276bd9e - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 + md5: 258e66f95f814d51ada2a1fe9274039b + sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 category: main optional: false - name: setuptools - version: 69.5.1 + version: 70.1.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda hash: - md5: 7462280d81f639363e6e63c81276bd9e - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 + md5: 258e66f95f814d51ada2a1fe9274039b + sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 category: main optional: false - name: setuptools - version: 69.5.1 + version: 70.1.0 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda hash: - md5: 7462280d81f639363e6e63c81276bd9e - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 + md5: 258e66f95f814d51ada2a1fe9274039b + sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 category: main optional: false - name: shapely @@ -20656,6 +20942,54 @@ package: sha256: 4ee91f54b17a65f9a34505f723b87c5d8c1021a1753d85b498470c3e33a2643f category: main optional: false +- name: shellingham + version: 1.5.4 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_0.conda + hash: + md5: d08db09a552699ee9e7eec56b4eb3899 + sha256: 3c49a0a101c41b7cf6ac05a1872d7a1f91f1b6d02eecb4a36b605a19517862bb + category: main + optional: false +- name: shellingham + version: 1.5.4 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_0.conda + hash: + md5: d08db09a552699ee9e7eec56b4eb3899 + sha256: 3c49a0a101c41b7cf6ac05a1872d7a1f91f1b6d02eecb4a36b605a19517862bb + category: main + optional: false +- name: shellingham + version: 1.5.4 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_0.conda + hash: + md5: d08db09a552699ee9e7eec56b4eb3899 + sha256: 3c49a0a101c41b7cf6ac05a1872d7a1f91f1b6d02eecb4a36b605a19517862bb + category: main + optional: false +- name: shellingham + version: 1.5.4 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_0.conda + hash: + md5: d08db09a552699ee9e7eec56b4eb3899 + sha256: 3c49a0a101c41b7cf6ac05a1872d7a1f91f1b6d02eecb4a36b605a19517862bb + category: main + optional: false - name: simple-websocket version: 1.0.0 manager: conda @@ -20997,64 +21331,66 @@ package: category: main optional: false - name: sqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' - libsqlite: 3.45.3 - libzlib: '>=1.2.13,<1.3.0a0' - ncurses: '>=6.4.20240210,<7.0a0' + libsqlite: 3.46.0 + libzlib: '>=1.2.13,<2.0a0' + ncurses: '>=6.5,<7.0a0' readline: '>=8.2,<9.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.45.3-h2c6b66d_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.0-h6d4b2fc_0.conda hash: - md5: be7d70f2db41b674733667bdd69bd000 - sha256: 945ac702e2bd8cc59cc780dfc37c18255d5e538c8433dc290c0edbad2bcbaeb4 + md5: 77ea8dff5cf8550cc8f5629a6af56323 + sha256: e849d576e52bf3e6fc5786f89b7d76978f2e2438587826c95570324cb572e52b category: main optional: false - name: sqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: osx-64 dependencies: - libsqlite: 3.45.3 - libzlib: '>=1.2.13,<1.3.0a0' - ncurses: '>=6.4.20240210,<7.0a0' + __osx: '>=10.13' + libsqlite: 3.46.0 + libzlib: '>=1.2.13,<2.0a0' + ncurses: '>=6.5,<7.0a0' readline: '>=8.2,<9.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.45.3-h7461747_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.46.0-h28673e1_0.conda hash: - md5: 4d9a56087e6150e84b94087a8c0fdf98 - sha256: 73ab284ff41dd6aeb69f7a8a014018fbf8b019fd261ff4190fd5813b62d07b16 + md5: b76e50276ebb3131cb84aac8123ca75d + sha256: 7d868d34348615450c43cb4737b44987a0e45fdf4759502b323494dc8c931409 category: main optional: false - name: sqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: osx-arm64 dependencies: - libsqlite: 3.45.3 - libzlib: '>=1.2.13,<1.3.0a0' - ncurses: '>=6.4.20240210,<7.0a0' + __osx: '>=11.0' + libsqlite: 3.46.0 + libzlib: '>=1.2.13,<2.0a0' + ncurses: '>=6.5,<7.0a0' readline: '>=8.2,<9.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.45.3-hf2abe2d_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.0-h5838104_0.conda hash: - md5: 95ba63aee059cdfc10b7e3ee1dd4c15d - sha256: 1d618ce2622e2e976f8f28ede2f14ae20f19f64eda706d9eda6419393c48015a + md5: 05c5dc8cd793dcfc5849d0569da9b175 + sha256: e13b719f70b3a20f40b59f814d32483ae8cd95fef83224127b10091828026f7d category: main optional: false - name: sqlite - version: 3.45.3 + version: 3.46.0 manager: conda platform: win-64 dependencies: - libsqlite: 3.45.3 + libsqlite: 3.46.0 ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.45.3-hcfcfb64_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.46.0-h2466b09_0.conda hash: - md5: ef090bf29a90a1371888385e405a3a6f - sha256: 9815ad33780f8679d21507ffd6e12184da47eab7b945b2e5df35e8af686aafe6 + md5: f60e557d64002fe9955b929226adf81d + sha256: 204edea00bb813d1e3da31dcd8caf1cb355ded08be3065ca53dea066bf75b827 category: main optional: false - name: stack_data @@ -21117,6 +21453,62 @@ package: sha256: a58433e75229bec39f3be50c02efbe9b7083e53a1f31d8ee247564f370191eec category: main optional: false +- name: starlette + version: 0.37.2 + manager: conda + platform: linux-64 + dependencies: + anyio: <5,>=3.4.0 + python: '>=3.8' + typing_extensions: '>=3.10.0' + url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda + hash: + md5: 7e5550dfa3ed2c2019988cbb9f8302ea + sha256: de3c43075fdc33c90cd8034e440638904268c46023dc2b14921a8355415dc40e + category: main + optional: false +- name: starlette + version: 0.37.2 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + typing_extensions: '>=3.10.0' + anyio: <5,>=3.4.0 + url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda + hash: + md5: 7e5550dfa3ed2c2019988cbb9f8302ea + sha256: de3c43075fdc33c90cd8034e440638904268c46023dc2b14921a8355415dc40e + category: main + optional: false +- name: starlette + version: 0.37.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + typing_extensions: '>=3.10.0' + anyio: <5,>=3.4.0 + url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda + hash: + md5: 7e5550dfa3ed2c2019988cbb9f8302ea + sha256: de3c43075fdc33c90cd8034e440638904268c46023dc2b14921a8355415dc40e + category: main + optional: false +- name: starlette + version: 0.37.2 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + typing_extensions: '>=3.10.0' + anyio: <5,>=3.4.0 + url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda + hash: + md5: 7e5550dfa3ed2c2019988cbb9f8302ea + sha256: de3c43075fdc33c90cd8034e440638904268c46023dc2b14921a8355415dc40e + category: main + optional: false - name: statsmodels version: 0.14.1 manager: conda @@ -21398,10 +21790,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-h91493d7_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_1.conda hash: - md5: 21745fdd12f01b41178596143cbecffd - sha256: 621926aae93513408bdca3dd21c97e2aa8ba7dcd2c400dab804fb0ce7da1387b + md5: e98333643abc739ebea1bac97a479828 + sha256: 87461c83a4f0d4f119af7368f20c47bbe0c27d963a7c22a3d08c71075077f855 category: main optional: false - name: tbb-devel @@ -21451,58 +21843,58 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-h3ec46f0_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-hb551fcf_1.conda hash: - md5: e8c5055e2db5703c42e03f6187131976 - sha256: 13aa63966cb49c4a5ce4efbec61e111a876a91d6dbfe4d4be9dd44d951ef3587 + md5: ce48530b0800c691735f1b96c36cb842 + sha256: 0dac2867318c12575eb73e65aa9babd2fff1ec37068d0cc5d3fa942873af75bc category: main optional: false - name: tenacity - version: 8.3.0 + version: 8.4.1 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda hash: - md5: 216cfa8e32bcd1447646768351df6059 - sha256: e5dff7fb47fdb919d3b9f26d504abf3a0e0136a6c9d8651e7591a89542f64a53 + md5: 2fcb668e39c694ece9a7748e3fad1a7e + sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f category: main optional: false - name: tenacity - version: 8.3.0 + version: 8.4.1 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda hash: - md5: 216cfa8e32bcd1447646768351df6059 - sha256: e5dff7fb47fdb919d3b9f26d504abf3a0e0136a6c9d8651e7591a89542f64a53 + md5: 2fcb668e39c694ece9a7748e3fad1a7e + sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f category: main optional: false - name: tenacity - version: 8.3.0 + version: 8.4.1 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda hash: - md5: 216cfa8e32bcd1447646768351df6059 - sha256: e5dff7fb47fdb919d3b9f26d504abf3a0e0136a6c9d8651e7591a89542f64a53 + md5: 2fcb668e39c694ece9a7748e3fad1a7e + sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f category: main optional: false - name: tenacity - version: 8.3.0 + version: 8.4.1 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.3.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda hash: - md5: 216cfa8e32bcd1447646768351df6059 - sha256: e5dff7fb47fdb919d3b9f26d504abf3a0e0136a6c9d8651e7591a89542f64a53 + md5: 2fcb668e39c694ece9a7748e3fad1a7e + sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f category: main optional: false - name: terminado @@ -21622,7 +22014,7 @@ package: curl: '' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.0.7,<4.0a0' zlib: '' @@ -21641,7 +22033,7 @@ package: bzip2: '>=1.0.8,<2.0a0' curl: '' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.0.7,<4.0a0' zlib: '' @@ -21660,7 +22052,7 @@ package: bzip2: '>=1.0.8,<2.0a0' curl: '' libcxx: '>=14.0.6' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.0.7,<4.0a0' zlib: '' @@ -21678,7 +22070,7 @@ package: dependencies: bzip2: '>=1.0.8,<2.0a0' curl: '' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' lz4-c: '>=1.9.3,<1.10.0a0' openssl: '>=3.0.7,<4.0a0' ucrt: '>=10.0.20348.0' @@ -21693,75 +22085,77 @@ package: category: main optional: false - name: timezonefinder - version: 6.4.1 + version: 6.5.2 manager: conda platform: linux-64 dependencies: cffi: '>=1.15.1,<2' h3-py: '>=3.7.6,<4' libgcc-ng: '>=12' - numpy: <1.25 + numpy: '>=1.21,<3' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* setuptools: '>=65.5' - url: https://conda.anaconda.org/conda-forge/linux-64/timezonefinder-6.4.1-py38h01eb140_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/timezonefinder-6.5.2-py38hfb59056_0.conda hash: - md5: 25887ddc7ff7b31c4376a2a253891c41 - sha256: 672e03dd24fac39a0144655ba7dea1ec12b2ba19d31ef85ae8f7c2f8b92a0f9b + md5: 7113f5d5f05050f3e7e97e1c1b25c5a0 + sha256: 6d1e5fe6cd0b25fae12c3778591397f69c53092f400bd5e5c7365257b02fda18 category: main optional: false - name: timezonefinder - version: 6.4.1 + version: 6.5.2 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' cffi: '>=1.15.1,<2' h3-py: '>=3.7.6,<4' - numpy: <1.25 + numpy: '>=1.21,<3' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* setuptools: '>=65.5' - url: https://conda.anaconda.org/conda-forge/osx-64/timezonefinder-6.4.1-py38hae2e43d_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/timezonefinder-6.5.2-py38hc718529_0.conda hash: - md5: f0a16d00082c17d9fa5fb7011dab701b - sha256: 6113465638cd9056cb0ac26a6d684736812f7cc15fdd386bd04cd404f4f04248 + md5: 64d2d104541c29a53981c7f253851932 + sha256: 1f8b4f63e1c52039ddbef9cdbf850db9fa943a263147a933b538df41080982bd category: main optional: false - name: timezonefinder - version: 6.4.1 + version: 6.5.2 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' cffi: '>=1.15.1,<2' h3-py: '>=3.7.6,<4' - numpy: <1.25 + numpy: '>=1.21,<3' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* setuptools: '>=65.5' - url: https://conda.anaconda.org/conda-forge/osx-arm64/timezonefinder-6.4.1-py38h336bac9_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/timezonefinder-6.5.2-py38h3237794_0.conda hash: - md5: d0b7fe44afa330bdf07ce025ff6e2682 - sha256: 16caba2b8010aab08cf38d30636ba01e74d87c1c3f732b00c51a75da39278a3e + md5: e9b10411964d2045008c54ce558ff322 + sha256: c97c17ea6945f4d5049c5b77881c5246bd3803832d11908afa0256b02e2d335a category: main optional: false - name: timezonefinder - version: 6.4.1 + version: 6.5.2 manager: conda platform: win-64 dependencies: cffi: '>=1.15.1,<2' h3-py: '>=3.7.6,<4' - numpy: <1.25 + numpy: '>=1.21,<3' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* setuptools: '>=65.5' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/timezonefinder-6.4.1-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/timezonefinder-6.5.2-py38h4cb3324_0.conda hash: - md5: fd7a131ac7c94a0852b52e7e9c95b4b2 - sha256: d3b66984418a625b0859961b2360a13e06f5892de6ac1155ae7abb99eb8423f9 + md5: c94d4f4d0cfb2c17df843900d925c769 + sha256: 1273c1c0fb0b85926dda7143a3e56fdfaa17cfcca03780170118de9df68ee17c category: main optional: false - name: tinycss2 @@ -21822,7 +22216,7 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda hash: md5: d453b98d9c83e71da0741bb0ff4d76bc @@ -21834,7 +22228,7 @@ package: manager: conda platform: osx-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda hash: md5: bf830ba5afc507c6232d4ef0fb1a882d @@ -21846,7 +22240,7 @@ package: manager: conda platform: osx-arm64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda hash: md5: b50a57ba89c32b62428b71a875291c9b @@ -21915,132 +22309,298 @@ package: sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f category: main optional: false -- name: tomli - version: 2.0.1 +- name: tomli + version: 2.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 5844808ffab9ebdb694585b50ba02a96 + sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + category: main + optional: false +- name: tomli + version: 2.0.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + hash: + md5: 5844808ffab9ebdb694585b50ba02a96 + sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + category: main + optional: false +- name: tornado + version: 6.4.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.1-py38hfb59056_0.conda + hash: + md5: ca6a0889b55d598c8fe154005cee15ef + sha256: a084e894e4477b6bd39f387cccd5273227f01764f3f99d889c117e592fa19ef0 + category: main + optional: false +- name: tornado + version: 6.4.1 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4.1-py38hc718529_0.conda + hash: + md5: d19b73304245856c53fa70b3a49a2d28 + sha256: 865bbe19ab1c73c5cdd62c893d1cf3ad3cabad6fdd926944f2d287ac9953f868 + category: main + optional: false +- name: tornado + version: 6.4.1 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4.1-py38h3237794_0.conda + hash: + md5: 1d35b5a73c7fecb9c81fda248a1de21b + sha256: 77d2bae1eccc29352ec0b8ef2015110760afadbf6c3b7f192e1dd9a72e30b47b + category: main + optional: false +- name: tornado + version: 6.4.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4.1-py38h4cb3324_0.conda + hash: + md5: 63fe25dabccbb3eaf389142be538a702 + sha256: cfb1bddfb450dc6ecc21a09ea12e865e1a8634e70681f1c2402cee1dc2a82e8f + category: main + optional: false +- name: traitlets + version: 5.14.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + hash: + md5: 3df84416a021220d8b5700c613af2dc5 + sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + category: main + optional: false +- name: traitlets + version: 5.14.3 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + hash: + md5: 3df84416a021220d8b5700c613af2dc5 + sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + category: main + optional: false +- name: traitlets + version: 5.14.3 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + hash: + md5: 3df84416a021220d8b5700c613af2dc5 + sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + category: main + optional: false +- name: traitlets + version: 5.14.3 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + hash: + md5: 3df84416a021220d8b5700c613af2dc5 + sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + category: main + optional: false +- name: typer + version: 0.12.3 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.7' + typer-slim-standard: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-0.12.3-pyhd8ed1ab_0.conda + hash: + md5: 10efd02b22c39c0a46312ef7cb16d237 + sha256: b8b182303858c512fa04f38a3123c892958f708d2ae90afd35246da7c4829485 + category: main + optional: false +- name: typer + version: 0.12.3 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.7' + typer-slim-standard: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-0.12.3-pyhd8ed1ab_0.conda + hash: + md5: 10efd02b22c39c0a46312ef7cb16d237 + sha256: b8b182303858c512fa04f38a3123c892958f708d2ae90afd35246da7c4829485 + category: main + optional: false +- name: typer + version: 0.12.3 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + typer-slim-standard: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-0.12.3-pyhd8ed1ab_0.conda hash: - md5: 5844808ffab9ebdb694585b50ba02a96 - sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + md5: 10efd02b22c39c0a46312ef7cb16d237 + sha256: b8b182303858c512fa04f38a3123c892958f708d2ae90afd35246da7c4829485 category: main optional: false -- name: tomli - version: 2.0.1 +- name: typer + version: 0.12.3 manager: conda platform: win-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 + typer-slim-standard: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-0.12.3-pyhd8ed1ab_0.conda hash: - md5: 5844808ffab9ebdb694585b50ba02a96 - sha256: 4cd48aba7cd026d17e86886af48d0d2ebc67ed36f87f6534f4b67138f5a5a58f + md5: 10efd02b22c39c0a46312ef7cb16d237 + sha256: b8b182303858c512fa04f38a3123c892958f708d2ae90afd35246da7c4829485 category: main optional: false -- name: tornado - version: '6.4' +- name: typer-slim + version: 0.12.3 manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py38h01eb140_0.conda + click: '>=8.0.0' + python: '>=3.7' + typing_extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: - md5: 0574e87cd56f017e680532f7d5723832 - sha256: d1a19bdba1e5355fbfa20ab9f92f4090d7c6ccc6d76a1154e043a1257166c5e6 + md5: cf2c3a89f89644c53cadbfeb124914e9 + sha256: 01dcb54375c8eae54d13374ed3d5823635401c552340b87e67fdbbb507760596 category: main optional: false -- name: tornado - version: '6.4' +- name: typer-slim + version: 0.12.3 manager: conda platform: osx-64 dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py38hae2e43d_0.conda + python: '>=3.7' + click: '>=8.0.0' + typing_extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: - md5: cebe6ef877354d724e18bb2a3f20ea39 - sha256: 0b57584383ec6f703ac63dbcf3fa44d31e8c16be691f586e7473120b2e06e716 + md5: cf2c3a89f89644c53cadbfeb124914e9 + sha256: 01dcb54375c8eae54d13374ed3d5823635401c552340b87e67fdbbb507760596 category: main optional: false -- name: tornado - version: '6.4' +- name: typer-slim + version: 0.12.3 manager: conda platform: osx-arm64 dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py38h336bac9_0.conda + python: '>=3.7' + click: '>=8.0.0' + typing_extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: - md5: 1d53c65c381251d24cf5a517e59e041e - sha256: 0e26643bb49ddebc3727c2e166faf94d238efecf7762a3e187c48539f36e031f + md5: cf2c3a89f89644c53cadbfeb124914e9 + sha256: 01dcb54375c8eae54d13374ed3d5823635401c552340b87e67fdbbb507760596 category: main optional: false -- name: tornado - version: '6.4' +- name: typer-slim + version: 0.12.3 manager: conda platform: win-64 dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py38h91455d4_0.conda + python: '>=3.7' + click: '>=8.0.0' + typing_extensions: '>=3.7.4.3' + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: - md5: 7f5076125439d638586601d63f1b02cc - sha256: 6cdfe1fb92cc5ce19eea199dfb70be5144453a71b5404a2ea7d0dd45367afe79 + md5: cf2c3a89f89644c53cadbfeb124914e9 + sha256: 01dcb54375c8eae54d13374ed3d5823635401c552340b87e67fdbbb507760596 category: main optional: false -- name: traitlets - version: 5.14.3 +- name: typer-slim-standard + version: 0.12.3 manager: conda platform: linux-64 dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + rich: '' + shellingham: '' + typer-slim: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.12.3-hd8ed1ab_0.conda hash: - md5: 3df84416a021220d8b5700c613af2dc5 - sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + md5: 8e56b98837d17e6ace4dc455d905709a + sha256: 06e2f8ca7e3f7168a39d3d2cc62ee1e220928e1e5a4370f4ade2566342c4a459 category: main optional: false -- name: traitlets - version: 5.14.3 +- name: typer-slim-standard + version: 0.12.3 manager: conda platform: osx-64 dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + rich: '' + shellingham: '' + typer-slim: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.12.3-hd8ed1ab_0.conda hash: - md5: 3df84416a021220d8b5700c613af2dc5 - sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + md5: 8e56b98837d17e6ace4dc455d905709a + sha256: 06e2f8ca7e3f7168a39d3d2cc62ee1e220928e1e5a4370f4ade2566342c4a459 category: main optional: false -- name: traitlets - version: 5.14.3 +- name: typer-slim-standard + version: 0.12.3 manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + rich: '' + shellingham: '' + typer-slim: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.12.3-hd8ed1ab_0.conda hash: - md5: 3df84416a021220d8b5700c613af2dc5 - sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + md5: 8e56b98837d17e6ace4dc455d905709a + sha256: 06e2f8ca7e3f7168a39d3d2cc62ee1e220928e1e5a4370f4ade2566342c4a459 category: main optional: false -- name: traitlets - version: 5.14.3 +- name: typer-slim-standard + version: 0.12.3 manager: conda platform: win-64 dependencies: - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda + rich: '' + shellingham: '' + typer-slim: 0.12.3 + url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-standard-0.12.3-hd8ed1ab_0.conda hash: - md5: 3df84416a021220d8b5700c613af2dc5 - sha256: 8a64fa0f19022828513667c2c7176cfd125001f3f4b9bc00d33732e627dd2592 + md5: 8e56b98837d17e6ace4dc455d905709a + sha256: 06e2f8ca7e3f7168a39d3d2cc62ee1e220928e1e5a4370f4ade2566342c4a459 category: main optional: false - name: types-python-dateutil @@ -22092,99 +22652,99 @@ package: category: main optional: false - name: typing-extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: linux-64 dependencies: - typing_extensions: 4.11.0 - url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda + typing_extensions: 4.12.2 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda hash: - md5: 471e3988f8ca5e9eb3ce6be7eac3bcee - sha256: aecbd9c601ba5a6c128da8975276fd817b968a9edc969b7ae97aee76e80a14a6 + md5: 52d648bd608f5737b123f510bb5514b5 + sha256: d3b9a8ed6da7c9f9553c5fd8a4fca9c3e0ab712fa5f497859f82337d67533b73 category: main optional: false - name: typing-extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: osx-64 dependencies: - typing_extensions: 4.11.0 - url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda + typing_extensions: 4.12.2 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda hash: - md5: 471e3988f8ca5e9eb3ce6be7eac3bcee - sha256: aecbd9c601ba5a6c128da8975276fd817b968a9edc969b7ae97aee76e80a14a6 + md5: 52d648bd608f5737b123f510bb5514b5 + sha256: d3b9a8ed6da7c9f9553c5fd8a4fca9c3e0ab712fa5f497859f82337d67533b73 category: main optional: false - name: typing-extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: osx-arm64 dependencies: - typing_extensions: 4.11.0 - url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda + typing_extensions: 4.12.2 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda hash: - md5: 471e3988f8ca5e9eb3ce6be7eac3bcee - sha256: aecbd9c601ba5a6c128da8975276fd817b968a9edc969b7ae97aee76e80a14a6 + md5: 52d648bd608f5737b123f510bb5514b5 + sha256: d3b9a8ed6da7c9f9553c5fd8a4fca9c3e0ab712fa5f497859f82337d67533b73 category: main optional: false - name: typing-extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: win-64 dependencies: - typing_extensions: 4.11.0 - url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda + typing_extensions: 4.12.2 + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda hash: - md5: 471e3988f8ca5e9eb3ce6be7eac3bcee - sha256: aecbd9c601ba5a6c128da8975276fd817b968a9edc969b7ae97aee76e80a14a6 + md5: 52d648bd608f5737b123f510bb5514b5 + sha256: d3b9a8ed6da7c9f9553c5fd8a4fca9c3e0ab712fa5f497859f82337d67533b73 category: main optional: false - name: typing_extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda hash: - md5: 6ef2fc37559256cf682d8b3375e89b80 - sha256: a7e8714d14f854058e971a6ed44f18cc37cc685f98ddefb2e6b7899a0cc4d1a2 + md5: ebe6952715e1d5eb567eeebf25250fa7 + sha256: 0fce54f8ec3e59f5ef3bb7641863be4e1bf1279623e5af3d3fa726e8f7628ddb category: main optional: false - name: typing_extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda hash: - md5: 6ef2fc37559256cf682d8b3375e89b80 - sha256: a7e8714d14f854058e971a6ed44f18cc37cc685f98ddefb2e6b7899a0cc4d1a2 + md5: ebe6952715e1d5eb567eeebf25250fa7 + sha256: 0fce54f8ec3e59f5ef3bb7641863be4e1bf1279623e5af3d3fa726e8f7628ddb category: main optional: false - name: typing_extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda hash: - md5: 6ef2fc37559256cf682d8b3375e89b80 - sha256: a7e8714d14f854058e971a6ed44f18cc37cc685f98ddefb2e6b7899a0cc4d1a2 + md5: ebe6952715e1d5eb567eeebf25250fa7 + sha256: 0fce54f8ec3e59f5ef3bb7641863be4e1bf1279623e5af3d3fa726e8f7628ddb category: main optional: false - name: typing_extensions - version: 4.11.0 + version: 4.12.2 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda hash: - md5: 6ef2fc37559256cf682d8b3375e89b80 - sha256: a7e8714d14f854058e971a6ed44f18cc37cc685f98ddefb2e6b7899a0cc4d1a2 + md5: ebe6952715e1d5eb567eeebf25250fa7 + sha256: 0fce54f8ec3e59f5ef3bb7641863be4e1bf1279623e5af3d3fa726e8f7628ddb category: main optional: false - name: typing_utils @@ -22329,6 +22889,67 @@ package: sha256: a62f3fb56849dc37270f9078e1c8ba32328bc3ba4d32cf1f7dace48b431d5abe category: main optional: false +- name: ujson + version: 5.10.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libstdcxx-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/ujson-5.10.0-py38h854fd01_0.conda + hash: + md5: ae47f30506d4e23b6c93ed51ad12999e + sha256: eff2881d88f917cb74a05846013fe08653339c757d5bfc466cbb1079b1dade07 + category: main + optional: false +- name: ujson + version: 5.10.0 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + libcxx: '>=16' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/ujson-5.10.0-py38h8949568_0.conda + hash: + md5: df23dfb6607b809217ae8c76a1ac464e + sha256: 8bcd0b1c8558c39b2c76b8d27aab77849e3fc8ba3bb3f0811443db64665149ad + category: main + optional: false +- name: ujson + version: 5.10.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + libcxx: '>=16' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/ujson-5.10.0-py38h11842c7_0.conda + hash: + md5: 05ad10c41bd72492bacf1f46247281f4 + sha256: 77a39c748699b79b562cb005b0a948f2ace23ad8fd27939f562aa6be90200272 + category: main + optional: false +- name: ujson + version: 5.10.0 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/ujson-5.10.0-py38h2698bfa_0.conda + hash: + md5: a641eeaa10c7df169a04bf1a17e96350 + sha256: a0cdc93125fa4c13b520a08d9ebfd981237c348de80e099d4c9a765894703ad3 + category: main + optional: false - name: unicodedata2 version: 15.1.0 manager: conda @@ -22487,59 +23108,59 @@ package: category: main optional: false - name: urllib3 - version: 2.2.1 + version: 2.2.2 manager: conda platform: linux-64 dependencies: brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda hash: - md5: 08807a87fa7af10754d46f63b368e016 - sha256: d4009dcc9327684d6409706ce17656afbeae690d8522d3c9bc4df57649a352cd + md5: 92cdb6fe54b78739ad70637e4f0deb07 + sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 category: main optional: false - name: urllib3 - version: 2.2.1 + version: 2.2.2 manager: conda platform: osx-64 dependencies: python: '>=3.7' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda hash: - md5: 08807a87fa7af10754d46f63b368e016 - sha256: d4009dcc9327684d6409706ce17656afbeae690d8522d3c9bc4df57649a352cd + md5: 92cdb6fe54b78739ad70637e4f0deb07 + sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 category: main optional: false - name: urllib3 - version: 2.2.1 + version: 2.2.2 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda hash: - md5: 08807a87fa7af10754d46f63b368e016 - sha256: d4009dcc9327684d6409706ce17656afbeae690d8522d3c9bc4df57649a352cd + md5: 92cdb6fe54b78739ad70637e4f0deb07 + sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 category: main optional: false - name: urllib3 - version: 2.2.1 + version: 2.2.2 manager: conda platform: win-64 dependencies: python: '>=3.7' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda hash: - md5: 08807a87fa7af10754d46f63b368e016 - sha256: d4009dcc9327684d6409706ce17656afbeae690d8522d3c9bc4df57649a352cd + md5: 92cdb6fe54b78739ad70637e4f0deb07 + sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 category: main optional: false - name: utfcpp @@ -22634,40 +23255,104 @@ package: sha256: da75b1b3b0674bf14d32cb00d6d070bf273772c73c787694d438104a486e7627 category: main optional: false +- name: uvicorn + version: 0.30.1 + manager: conda + platform: linux-64 + dependencies: + click: '>=7.0' + h11: '>=0.8' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-0.30.1-py38h578d9bd_0.conda + hash: + md5: dc649127be96bd22e1b0ea884e427875 + sha256: 028ccb0830238f9b997c9658640dd1c77813a6972a1608ac95c9b02bc5d56dd3 + category: main + optional: false +- name: uvicorn + version: 0.30.1 + manager: conda + platform: osx-64 + dependencies: + click: '>=7.0' + h11: '>=0.8' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-0.30.1-py38h50d1736_0.conda + hash: + md5: 2e1dfbcdd695053d338830b62ab12d15 + sha256: f45ce6c3a4582ab094ea0bc9f404c502dbb75faa2c2c429d2fcb8c87c9251aa0 + category: main + optional: false +- name: uvicorn + version: 0.30.1 + manager: conda + platform: osx-arm64 + dependencies: + click: '>=7.0' + h11: '>=0.8' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-0.30.1-py38h10201cd_0.conda + hash: + md5: 1323d54950e3e29fb41dd76e2dc06aeb + sha256: 90940b00808a3ab2c242673f682d0a9c1c3e48c1451119c518a301eec9125760 + category: main + optional: false +- name: uvicorn + version: 0.30.1 + manager: conda + platform: win-64 + dependencies: + click: '>=7.0' + h11: '>=0.8' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + typing_extensions: '>=4.0' + url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-0.30.1-py38haa244fe_0.conda + hash: + md5: 223898c18ce5a4f87c46a3c797f58a9c + sha256: 5d51c3f48481aed643d592b2b15410344fbbe2e56ffe1d775330d2c61efe4869 + category: main + optional: false - name: vc version: '14.3' manager: conda platform: win-64 dependencies: - vc14_runtime: '>=14.38.33130' - url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda + vc14_runtime: '>=14.40.33810' + url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda hash: - md5: 20e1e652a4c740fa719002a8449994a2 - sha256: 447a8d8292a7b2107dcc18afb67f046824711a652725fc0f522c368e7a7b8318 + md5: 8558f367e1d7700554f7cdb823c46faf + sha256: 23ac5feb15a9adf3ab2b8c4dcd63650f8b7ae860c5ceb073e49cf71d203eddef category: main optional: false - name: vc14_runtime - version: 14.38.33130 + version: 14.40.33810 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' - url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda + url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda hash: - md5: 8be79fdd2725ddf7bbf8a27a4c1f79ba - sha256: bf94c9af4b2e9cba88207001197e695934eadc96a5c5e4cd7597e950aae3d8ff + md5: e39cc4c34c53654ec939558993d9dc5b + sha256: af3cfa347e3d7c1277e9b964b0849a9a9f095bff61836cb3c3a89862fbc32e17 category: main optional: false - name: vs2015_runtime - version: 14.38.33130 + version: 14.40.33810 manager: conda platform: win-64 dependencies: - vc14_runtime: '>=14.38.33130' - url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + vc14_runtime: '>=14.40.33810' + url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda hash: - md5: 10d42885e3ed84e575b454db30f1aa93 - sha256: a2fec221f361d6263c117f4ea6d772b21c90a2f8edc6f3eb0eadec6bfe8843db + md5: c21f1b4a3a30bbc3ef35a50957578e0e + sha256: 0c2803f7a788c51f28235a7228dc2ab3f107b4b16ab0845a3e595c8c51e50a7a category: main optional: false - name: vtk @@ -22694,7 +23379,7 @@ package: libtheora: '>=1.1.1,<1.2.0a0' libtiff: '>=4.5.0,<4.6.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' loguru: '' lz4-c: '>=1.9.3,<1.10.0a0' nlohmann_json: '' @@ -22741,7 +23426,7 @@ package: libtheora: '>=1.1.1,<1.2.0a0' libtiff: '>=4.5.0,<4.6.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' loguru: '' lz4-c: '>=1.9.3,<1.10.0a0' nlohmann_json: '' @@ -22787,7 +23472,7 @@ package: libtheora: '>=1.1.1,<1.2.0a0' libtiff: '>=4.5.0,<4.6.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' loguru: '' lz4-c: '>=1.9.3,<1.10.0a0' nlohmann_json: '' @@ -22832,7 +23517,7 @@ package: libtheora: '>=1.1.1,<1.2.0a0' libtiff: '>=4.5.0,<4.6.0a0' libxml2: '>=2.10.3,<3.0.0a0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' loguru: '' lz4-c: '>=1.9.3,<1.10.0a0' nlohmann_json: '' @@ -22906,51 +23591,51 @@ package: category: main optional: false - name: webcolors - version: '1.13' + version: 24.6.0 manager: conda platform: linux-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda hash: - md5: 166212fe82dad8735550030488a01d03 - sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + md5: 419f2f6cf90fc7a6feee657752cd0f7b + sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f category: main optional: false - name: webcolors - version: '1.13' + version: 24.6.0 manager: conda platform: osx-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda hash: - md5: 166212fe82dad8735550030488a01d03 - sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + md5: 419f2f6cf90fc7a6feee657752cd0f7b + sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f category: main optional: false - name: webcolors - version: '1.13' + version: 24.6.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda hash: - md5: 166212fe82dad8735550030488a01d03 - sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + md5: 419f2f6cf90fc7a6feee657752cd0f7b + sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f category: main optional: false - name: webcolors - version: '1.13' + version: 24.6.0 manager: conda platform: win-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda hash: - md5: 166212fe82dad8735550030488a01d03 - sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 + md5: 419f2f6cf90fc7a6feee657752cd0f7b + sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f category: main optional: false - name: webencodings @@ -23049,58 +23734,6 @@ package: sha256: 44a5e3b97feef24cd719f7851cca9af9799dc9c17d3e0298d5856baab2d682f5 category: main optional: false -- name: werkzeug - version: 2.3.8 - manager: conda - platform: linux-64 - dependencies: - markupsafe: '>=2.1.1' - python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.3.8-pyhd8ed1ab_0.conda - hash: - md5: 4d0a38559ef093d9987ad2934e535473 - sha256: ce0c68c3dc44e106dd15b24534c085a2c9bf6603227983d01c2bad41edcad864 - category: main - optional: false -- name: werkzeug - version: 2.3.8 - manager: conda - platform: osx-64 - dependencies: - python: '>=3.8' - markupsafe: '>=2.1.1' - url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.3.8-pyhd8ed1ab_0.conda - hash: - md5: 4d0a38559ef093d9987ad2934e535473 - sha256: ce0c68c3dc44e106dd15b24534c085a2c9bf6603227983d01c2bad41edcad864 - category: main - optional: false -- name: werkzeug - version: 2.3.8 - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.8' - markupsafe: '>=2.1.1' - url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.3.8-pyhd8ed1ab_0.conda - hash: - md5: 4d0a38559ef093d9987ad2934e535473 - sha256: ce0c68c3dc44e106dd15b24534c085a2c9bf6603227983d01c2bad41edcad864 - category: main - optional: false -- name: werkzeug - version: 2.3.8 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8' - markupsafe: '>=2.1.1' - url: https://conda.anaconda.org/conda-forge/noarch/werkzeug-2.3.8-pyhd8ed1ab_0.conda - hash: - md5: 4d0a38559ef093d9987ad2934e535473 - sha256: ce0c68c3dc44e106dd15b24534c085a2c9bf6603227983d01c2bad41edcad864 - category: main - optional: false - name: wheel version: 0.43.0 manager: conda @@ -23186,59 +23819,59 @@ package: category: main optional: false - name: wslink - version: 2.0.2 + version: 2.1.0 manager: conda platform: linux-64 dependencies: aiohttp: <4 msgpack-python: '>=1,<2' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda hash: - md5: 0c046a28359b6c6f82b3a8adbf7d2f90 - sha256: 388dc4cfbcf0b6aed0e1d89b4a0443edcc10f5998f4a014e8bcc4954d669e881 + md5: 088c224d81a1828e283186e14a4db25f + sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c category: main optional: false - name: wslink - version: 2.0.2 + version: 2.1.0 manager: conda platform: osx-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda hash: - md5: 0c046a28359b6c6f82b3a8adbf7d2f90 - sha256: 388dc4cfbcf0b6aed0e1d89b4a0443edcc10f5998f4a014e8bcc4954d669e881 + md5: 088c224d81a1828e283186e14a4db25f + sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c category: main optional: false - name: wslink - version: 2.0.2 + version: 2.1.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda hash: - md5: 0c046a28359b6c6f82b3a8adbf7d2f90 - sha256: 388dc4cfbcf0b6aed0e1d89b4a0443edcc10f5998f4a014e8bcc4954d669e881 + md5: 088c224d81a1828e283186e14a4db25f + sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c category: main optional: false - name: wslink - version: 2.0.2 + version: 2.1.0 manager: conda platform: win-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda hash: - md5: 0c046a28359b6c6f82b3a8adbf7d2f90 - sha256: 388dc4cfbcf0b6aed0e1d89b4a0443edcc10f5998f4a014e8bcc4954d669e881 + md5: 088c224d81a1828e283186e14a4db25f + sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c category: main optional: false - name: wsproto @@ -23878,51 +24511,51 @@ package: category: main optional: false - name: xyzservices - version: 2024.4.0 + version: 2024.6.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda hash: - md5: 93dffc47dadbe36a1a644f3f50d4979d - sha256: 4e095631b52a78bbd9b53f28eb79b0c8f448d9509cf0451e99c2f3f85576f114 + md5: de631703d59e40af41c56c4b4e2928ab + sha256: da2e54cb68776e62a708cb6d5f026229d8405ff4cfd8a2446f7d386f07ebc5c1 category: main optional: false - name: xyzservices - version: 2024.4.0 + version: 2024.6.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda hash: - md5: 93dffc47dadbe36a1a644f3f50d4979d - sha256: 4e095631b52a78bbd9b53f28eb79b0c8f448d9509cf0451e99c2f3f85576f114 + md5: de631703d59e40af41c56c4b4e2928ab + sha256: da2e54cb68776e62a708cb6d5f026229d8405ff4cfd8a2446f7d386f07ebc5c1 category: main optional: false - name: xyzservices - version: 2024.4.0 + version: 2024.6.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda hash: - md5: 93dffc47dadbe36a1a644f3f50d4979d - sha256: 4e095631b52a78bbd9b53f28eb79b0c8f448d9509cf0451e99c2f3f85576f114 + md5: de631703d59e40af41c56c4b4e2928ab + sha256: da2e54cb68776e62a708cb6d5f026229d8405ff4cfd8a2446f7d386f07ebc5c1 category: main optional: false - name: xyzservices - version: 2024.4.0 + version: 2024.6.0 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda hash: - md5: 93dffc47dadbe36a1a644f3f50d4979d - sha256: 4e095631b52a78bbd9b53f28eb79b0c8f448d9509cf0451e99c2f3f85576f114 + md5: de631703d59e40af41c56c4b4e2928ab + sha256: da2e54cb68776e62a708cb6d5f026229d8405ff4cfd8a2446f7d386f07ebc5c1 category: main optional: false - name: xz @@ -24084,55 +24717,55 @@ package: category: main optional: false - name: yarn - version: 4.2.2 + version: 4.3.0 manager: conda platform: linux-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.2.2-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda hash: - md5: e4d4a58a5511a7d59cdf3048197d55db - sha256: e2c01f5b1779a262b7b40976d876bf040a7eb801a6313fdcbf20e77b458c8688 + md5: fb40f36d553305b76fceb28584a2fa4f + sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 category: main optional: false - name: yarn - version: 4.2.2 + version: 4.3.0 manager: conda platform: osx-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.2.2-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda hash: - md5: e4d4a58a5511a7d59cdf3048197d55db - sha256: e2c01f5b1779a262b7b40976d876bf040a7eb801a6313fdcbf20e77b458c8688 + md5: fb40f36d553305b76fceb28584a2fa4f + sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 category: main optional: false - name: yarn - version: 4.2.2 + version: 4.3.0 manager: conda platform: osx-arm64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.2.2-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda hash: - md5: e4d4a58a5511a7d59cdf3048197d55db - sha256: e2c01f5b1779a262b7b40976d876bf040a7eb801a6313fdcbf20e77b458c8688 + md5: fb40f36d553305b76fceb28584a2fa4f + sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 category: main optional: false - name: yarn - version: 4.2.2 + version: 4.3.0 manager: conda platform: win-64 dependencies: __win: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.2.2-h5737063_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h5737063_0.conda hash: - md5: bbb6d7640fe1faac42b0d87d77c47a96 - sha256: 335c50e39c69d7c7eb6f440cfc1ed4753c2f8fbf2413a856065096458ce2b4f0 + md5: a5242d2fb59ba7c3d8ff370c0e6a4e5e + sha256: e2766ea328126396585eef19fad99670243858724df67f575ca22294f257c999 category: main optional: false - name: zeromq @@ -24192,51 +24825,51 @@ package: category: main optional: false - name: zipp - version: 3.17.0 + version: 3.19.2 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda hash: - md5: 2e4d6bc0b14e10f895fc6791a7d9b26a - sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + md5: 49808e59df5535116f6878b2a820d6f4 + sha256: e3e9c8501f581bfdc4700b83ea283395e237ec6b9b5cbfbedb556e1da6f4fdc9 category: main optional: false - name: zipp - version: 3.17.0 + version: 3.19.2 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda hash: - md5: 2e4d6bc0b14e10f895fc6791a7d9b26a - sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + md5: 49808e59df5535116f6878b2a820d6f4 + sha256: e3e9c8501f581bfdc4700b83ea283395e237ec6b9b5cbfbedb556e1da6f4fdc9 category: main optional: false - name: zipp - version: 3.17.0 + version: 3.19.2 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda hash: - md5: 2e4d6bc0b14e10f895fc6791a7d9b26a - sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + md5: 49808e59df5535116f6878b2a820d6f4 + sha256: e3e9c8501f581bfdc4700b83ea283395e237ec6b9b5cbfbedb556e1da6f4fdc9 category: main optional: false - name: zipp - version: 3.17.0 + version: 3.19.2 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda hash: - md5: 2e4d6bc0b14e10f895fc6791a7d9b26a - sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 + md5: 49808e59df5535116f6878b2a820d6f4 + sha256: e3e9c8501f581bfdc4700b83ea283395e237ec6b9b5cbfbedb556e1da6f4fdc9 category: main optional: false - name: zlib @@ -24246,10 +24879,10 @@ package: dependencies: libgcc-ng: '>=12' libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda + url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda hash: - md5: 68c34ec6149623be41a1933ab996a209 - sha256: 9887a04d7e7cb14bd2b52fa01858f05a6d7f002c890f618d9fcd864adbfecb1b + md5: 559d338a4234c2ad6e676f460a093e67 + sha256: 534824ea44939f3e59ca8ebb95e3ece6f50f9d2a0e69999fbc692311252ed6ac category: main optional: false - name: zlib @@ -24257,11 +24890,12 @@ package: manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h8a1eda9_5.conda + url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h87427d6_6.conda hash: - md5: 75a8a98b1c4671c5d2897975731da42d - sha256: d1f4c82fd7bd240a78ce8905e931e68dca5f523c7da237b6b63c87d5625c5b35 + md5: 700b922d6d22e7deb5fb2964d0c8cf6a + sha256: 3091d48a579c08ba20885bc8856def925e9dee9d1a7d8713e3ce002eb29fcd19 category: main optional: false - name: zlib @@ -24269,138 +24903,27 @@ package: manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-h53f4e23_5.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-hfb2fe0b_6.conda hash: - md5: a08383f223b10b71492d27566fafbf6c - sha256: de0ee1e24aa6867058d3b852a15c8d7f49f262f5828772700c647186d4a96bbe + md5: 88cf27df3eff5813734b538461f4c8cf + sha256: c09c9cb6de86d87b9267a6331c74cc8fb05bae5ee7749070a5e8883c3eff5424 category: main optional: false - name: zlib - version: 1.2.13 - manager: conda - platform: win-64 - dependencies: - libzlib: 1.2.13 - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-hcfcfb64_5.conda - hash: - md5: a318e8622e11663f645cc7fa3260f462 - sha256: 0f91b719c7558046bcd37fdc7ae4b9eb2b7a8e335beb8b59ae7ccb285a46aa46 - category: main - optional: false -- name: zope.event - version: '5.0' - manager: conda - platform: linux-64 - dependencies: - python: '>=3.7' - setuptools: '' - url: https://conda.anaconda.org/conda-forge/noarch/zope.event-5.0-pyhd8ed1ab_0.conda - hash: - md5: b4a7b86cf51f2831015e9eebd284dc0a - sha256: 6c8da71175dcbed170020414b38315a71771902e91c1ec0b59e0e74e510e08d9 - category: main - optional: false -- name: zope.event - version: '5.0' - manager: conda - platform: osx-64 - dependencies: - setuptools: '' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/zope.event-5.0-pyhd8ed1ab_0.conda - hash: - md5: b4a7b86cf51f2831015e9eebd284dc0a - sha256: 6c8da71175dcbed170020414b38315a71771902e91c1ec0b59e0e74e510e08d9 - category: main - optional: false -- name: zope.event - version: '5.0' - manager: conda - platform: osx-arm64 - dependencies: - setuptools: '' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/zope.event-5.0-pyhd8ed1ab_0.conda - hash: - md5: b4a7b86cf51f2831015e9eebd284dc0a - sha256: 6c8da71175dcbed170020414b38315a71771902e91c1ec0b59e0e74e510e08d9 - category: main - optional: false -- name: zope.event - version: '5.0' - manager: conda - platform: win-64 - dependencies: - setuptools: '' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/zope.event-5.0-pyhd8ed1ab_0.conda - hash: - md5: b4a7b86cf51f2831015e9eebd284dc0a - sha256: 6c8da71175dcbed170020414b38315a71771902e91c1ec0b59e0e74e510e08d9 - category: main - optional: false -- name: zope.interface - version: '6.3' - manager: conda - platform: linux-64 - dependencies: - libgcc-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - url: https://conda.anaconda.org/conda-forge/linux-64/zope.interface-6.3-py38h01eb140_0.conda - hash: - md5: c78c2dd759ebb737d5d2d005c36f7bdf - sha256: 61989801b0c8e993fda00c90af90a64d3eda89ea7557efec9911a77530c90694 - category: main - optional: false -- name: zope.interface - version: '6.3' - manager: conda - platform: osx-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - url: https://conda.anaconda.org/conda-forge/osx-64/zope.interface-6.3-py38hae2e43d_0.conda - hash: - md5: fccf1575e1562473d090d5a99df8e17f - sha256: fa0b21c3c8f51933276530446667893bcf4be29630e707891ce52ab12b0a9f3f - category: main - optional: false -- name: zope.interface - version: '6.3' - manager: conda - platform: osx-arm64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' - url: https://conda.anaconda.org/conda-forge/osx-arm64/zope.interface-6.3-py38h336bac9_0.conda - hash: - md5: dffc154d0472b1e586f542c3d9579eea - sha256: 411dd1fa1b2082fd8316ecf0fd5668de36ddbae8d041617c8d00d627332a8a94 - category: main - optional: false -- name: zope.interface - version: '6.3' + version: 1.3.1 manager: conda platform: win-64 dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - setuptools: '' + libzlib: 1.3.1 ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/zope.interface-6.3-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_1.conda hash: - md5: 6fd909ccf243d617e3d8db44370d3bab - sha256: 88b33b8282ed2f2997150f60e63a524ff24259d2a23e5ce325ed9073424fccad + md5: f8e0a35bf6df768ad87ed7bbbc36ab04 + sha256: 76409556e6c7cb91991cd94d7fc853c9272c2872bd7e3573ff35eb33d6fca5be category: main optional: false - name: zstd @@ -24410,7 +24933,7 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda hash: md5: 4d056880988120e29d75bfff282e0f45 @@ -24423,7 +24946,7 @@ package: platform: osx-64 dependencies: __osx: '>=10.9' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.6-h915ae27_0.conda hash: md5: 4cb2cd56f039b129bb0e491c1164167e @@ -24436,7 +24959,7 @@ package: platform: osx-arm64 dependencies: __osx: '>=11.0' - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' url: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.6-hb46c0d2_0.conda hash: md5: d96942c06c3e84bfcc5efb038724a7fd @@ -24448,7 +24971,7 @@ package: manager: conda platform: win-64 dependencies: - libzlib: '>=1.2.13,<1.3.0a0' + libzlib: '>=1.2.13,<2.0.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' diff --git a/environment.yml b/environment.yml index fff7b965f3..99702b0b48 100644 --- a/environment.yml +++ b/environment.yml @@ -6,13 +6,11 @@ dependencies: - deap - ephem - fiona -- flask -- flask-cors -- flask-restx>=1.3.0 # Support for Flask >= 2.0 -- flask-socketio +- fastapi +- uvicorn +- jinja2 +- python-socketio - geopandas=0.13 # Due to python3.8 support -- gevent # Required for flask-socketio, requires wheel building -- gevent-websocket # Required for flask-socketio - libpysal - networkx=2.8 - numba=0.57 From 37f4f34a9a5a0e1acdd95cab67402bc00551bba0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:10:18 +0200 Subject: [PATCH 002/103] Rename dashboards route --- cea/interfaces/dashboard/api/__init__.py | 4 ++-- cea/interfaces/dashboard/api/{dashboard.py => dashboards.py} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename cea/interfaces/dashboard/api/{dashboard.py => dashboards.py} (100%) diff --git a/cea/interfaces/dashboard/api/__init__.py b/cea/interfaces/dashboard/api/__init__.py index 3a1c2915ec..2ba3614b5e 100644 --- a/cea/interfaces/dashboard/api/__init__.py +++ b/cea/interfaces/dashboard/api/__init__.py @@ -2,7 +2,7 @@ import cea.interfaces.dashboard.api.inputs as inputs import cea.interfaces.dashboard.api.contents as contents -import cea.interfaces.dashboard.api.dashboard as dashboard +import cea.interfaces.dashboard.api.dashboards as dashboards import cea.interfaces.dashboard.api.databases as databases import cea.interfaces.dashboard.api.glossary as glossary import cea.interfaces.dashboard.api.project as project @@ -12,7 +12,7 @@ router.include_router(inputs.router, prefix="/inputs") router.include_router(contents.router, prefix="/contents") -router.include_router(dashboard.router, prefix="/dashboard") +router.include_router(dashboards.router, prefix="/dashboards") router.include_router(databases.router, prefix="/databases") router.include_router(glossary.router, prefix="/glossary") router.include_router(project.router, prefix="/project") diff --git a/cea/interfaces/dashboard/api/dashboard.py b/cea/interfaces/dashboard/api/dashboards.py similarity index 100% rename from cea/interfaces/dashboard/api/dashboard.py rename to cea/interfaces/dashboard/api/dashboards.py From 01344f0dcd0c882bf4c3eef9c9258fa1e1c15668 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:34:13 +0200 Subject: [PATCH 003/103] Define config and plot cache as global objects Allows reusing of plot cache object --- cea/interfaces/dashboard/api/dashboards.py | 70 +++++++++++----------- cea/interfaces/dashboard/dashboard.py | 12 +++- cea/interfaces/dashboard/plots/routes.py | 17 +++--- 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index 7550f64269..b21d26d54e 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -5,9 +5,8 @@ import cea.config import cea.plots -from cea.plots.cache import MemoryPlotCache from .utils import deconstruct_parameters -from ..dashboard import CEAConfig +from ..dashboard import CEAConfig, CEAPlotCache router = APIRouter() @@ -68,11 +67,11 @@ def get_parameters_from_plot_class(config, plot_class, scenario_name=None): @router.get('/') -async def get_dashboards(config: CEAConfig): +async def get_dashboards(config: CEAConfig, plot_cache: CEAPlotCache): """ Get list of Dashboards """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) out = [] for d in dashboards: @@ -82,7 +81,7 @@ async def get_dashboards(config: CEAConfig): @router.post('/') -async def create_dashboard(config: CEAConfig, payload: Dict[str, Any], ): +async def create_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, payload: Dict[str, Any], ): """ Create Dashboard """ @@ -91,29 +90,39 @@ async def create_dashboard(config: CEAConfig, payload: Dict[str, Any], ): if 'grid' in form['layout']: types = [[2] + [1] * 4, [1] * 6, [1] * 3 + [3], [2, 1] * 2] grid_width = types[int(form['layout'].split('-')[-1]) - 1] - dashboard_index = cea.plots.new_dashboard(config, MemoryPlotCache(config.project), form['name'], 'grid', + dashboard_index = cea.plots.new_dashboard(config, plot_cache, form['name'], 'grid', grid_width=grid_width) else: - dashboard_index = cea.plots.new_dashboard(config, MemoryPlotCache(config.project), form['name'], form['layout']) + dashboard_index = cea.plots.new_dashboard(config, plot_cache, form['name'], form['layout']) return {'new_dashboard_index': dashboard_index} +@router.get('/plot-categories') +async def get_plot_categories(config: CEAConfig): + return get_categories(config.plugins) + + +@router.get('/plot-categories/{category_name}/plots/{plot_id>}/parameters') +async def get_plot_category_parameters(config: CEAConfig, category_name: str, plot_id: str, scenario: str = None): + plot_class = cea.plots.categories.load_plot_by_id(category_name, plot_id, config.plugins) + return get_parameters_from_plot_class(config, plot_class, scenario) + + @router.post('/duplicate') -async def duplicate_dashboard(config: CEAConfig, payload: Dict[str, Any]): +async def duplicate_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, payload: Dict[str, Any]): form = payload - dashboard_index = cea.plots.duplicate_dashboard(config, MemoryPlotCache(config.project), form['name'], - form['dashboard_index']) + dashboard_index = cea.plots.duplicate_dashboard(config, plot_cache, form['name'], form['dashboard_index']) return {'new_dashboard_index': dashboard_index} @router.get('/{dashboard_index}') -async def get_dashboard(config: CEAConfig, dashboard_index: int): +async def get_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int): """ Get Dashboard """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) return dashboard_to_dict(dashboards[dashboard_index]) @@ -129,12 +138,12 @@ async def delete_dashboard(config: CEAConfig, dashboard_index: int): @router.patch('/{dashboard_index}') -async def update_dashboard(config: CEAConfig, dashboard_index: int, payload: Dict[str, Any]): +async def update_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, payload: Dict[str, Any]): """ Update Dashboard properties """ form = payload - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard_index] dashboard.set_scenario(form['scenario']) @@ -143,29 +152,19 @@ async def update_dashboard(config: CEAConfig, dashboard_index: int, payload: Dic return {'new_dashboard_index': dashboard_index} -@router.get('/plot-categories') -async def get_plot_categories(): - return get_categories(None) - - -@router.get('/plot-categories/{category_name}/plots/{plot_id>}/parameters') -async def get_plot_category_parameters(config: CEAConfig, category_name: str, plot_id: str, scenario: str = None): - plot_class = cea.plots.categories.load_plot_by_id(category_name, plot_id, config.plugins) - return get_parameters_from_plot_class(config, plot_class, scenario) - - @router.get('/{dashboard_index}/plots/{plot_index}>') -async def get_plot(config: CEAConfig, dashboard_index: int, plot_index: int): +async def get_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int): """ Get Dashboard Plot """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] @router.put('/{dashboard_index}/plots/{plot_index}>') -async def create_plot_at_index(config: CEAConfig, dashboard_index: int, plot_index: int, payload: Dict[str, Any]): +async def create_plot_at_index(config: CEAConfig, plot_cache: CEAPlotCache, + dashboard_index: int, plot_index: int, payload: Dict[str, Any]): """ Create/Replace a new Plot at specified index """ @@ -173,7 +172,7 @@ async def create_plot_at_index(config: CEAConfig, dashboard_index: int, plot_ind # avoid overwriting original config.scenario for plot temp_config = cea.config.Configuration() - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard_index] if 'category' in form and 'plot_id' in form: @@ -199,11 +198,11 @@ async def create_plot_at_index(config: CEAConfig, dashboard_index: int, plot_ind @router.delete('/{dashboard_index}/plots/{plot_index}>') -async def delete_plot(config: CEAConfig, dashboard_index: int, plot_index: int): +async def delete_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int): """ Delete Plot from Dashboard """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard_index] dashboard.remove_plot(plot_index) @@ -213,11 +212,12 @@ async def delete_plot(config: CEAConfig, dashboard_index: int, plot_index: int): @router.get('/{dashboard_index}/plots/{plot_index}/parameters') -async def get_plot_parameters(config: CEAConfig, dashboard_index: int, plot_index: int, scenario: str = None): +async def get_plot_parameters(config: CEAConfig, plot_cache: CEAPlotCache, + dashboard_index: int, plot_index: int, scenario: str = None): """ Get Plot Form Parameters of Plot in Dashboard """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard_index] plot = dashboard.plots[plot_index] @@ -226,11 +226,11 @@ async def get_plot_parameters(config: CEAConfig, dashboard_index: int, plot_inde @router.get('/{dashboard_index}/plots/{plot_index}/input-files') -async def get_plot_input_files(config: CEAConfig, dashboard_index: int, plot_index: int): +async def get_plot_input_files(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int): """ Get input files of Plot """ - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard_index] plot = dashboard.plots[plot_index] diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index d8808d1fd4..afbbaba18b 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -6,14 +6,22 @@ from typing_extensions import Annotated import cea.config +from cea.plots.cache import MemoryPlotCache + +_config = cea.config.Configuration() +_mem_cache = MemoryPlotCache(_config.project) def get_cea_config(): - config = cea.config.Configuration() - return config + return _config + + +def get_plot_cache(): + return _mem_cache CEAConfig = Annotated[dict, Depends(get_cea_config)] +CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] def create_app(): diff --git a/cea/interfaces/dashboard/plots/routes.py b/cea/interfaces/dashboard/plots/routes.py index f10f69895c..4669f15e71 100644 --- a/cea/interfaces/dashboard/plots/routes.py +++ b/cea/interfaces/dashboard/plots/routes.py @@ -9,8 +9,7 @@ import cea.plots.categories import cea.schemas from cea import MissingInputDataException -from cea.interfaces.dashboard.dashboard import CEAConfig -from cea.plots.cache import MemoryPlotCache +from cea.interfaces.dashboard.dashboard import CEAConfig, CEAPlotCache router = APIRouter() @@ -29,9 +28,9 @@ def script_suggestions(locator_names): return [cea.scripts.by_name(n, plugins=plugins) for n in sorted(set(script_names))] -def load_plot(config, dashboard, plot_index): +def load_plot(config, plot_cache, dashboard, plot_index): """Load a plot from the dashboard_yml""" - dashboards = cea.plots.read_dashboards(config, MemoryPlotCache(config.project)) + dashboards = cea.plots.read_dashboards(config, plot_cache) dashboard = dashboards[dashboard] plot = dashboard.plots[plot_index] return plot @@ -60,9 +59,10 @@ def render_plot(request, plot_div, plot_title): @router.get('/div/{dashboard_index}/{plot_index}', response_class=HTMLResponse) -async def route_div(config: CEAConfig, request: Request, dashboard_index: int, plot_index: int): +async def route_div(config: CEAConfig, plot_cache: CEAPlotCache, + request: Request, dashboard_index: int, plot_index: int): """Return the plot as a div to be used in an AJAX call""" - plot = load_plot(config, dashboard_index, plot_index) + plot = load_plot(config, plot_cache, dashboard_index, plot_index) try: plot_div = plot.plot_div() except MissingInputDataException: @@ -82,8 +82,9 @@ async def route_div(config: CEAConfig, request: Request, dashboard_index: int, p @router.get('/plot/{dashboard_index}/{plot_index}', response_class=HTMLResponse) -async def route_plot(config: CEAConfig, request: Request, dashboard_index: int, plot_index: int): - plot = load_plot(config, dashboard_index, plot_index) +async def route_plot(config: CEAConfig, plot_cache: CEAPlotCache, + request: Request, dashboard_index: int, plot_index: int): + plot = load_plot(config, plot_cache, dashboard_index, plot_index) plot_title = plot.title if 'scenario-name' in plot.parameters: plot_title += ' - {}'.format(plot.parameters['scenario-name']) From 211b919b1ad9a415cfeef5d808ae07c7efce1e71 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:05:55 +0200 Subject: [PATCH 004/103] Use aiocache to share objects --- cea/interfaces/dashboard/api/contents.py | 2 +- cea/interfaces/dashboard/api/dashboards.py | 2 +- cea/interfaces/dashboard/api/glossary.py | 2 +- cea/interfaces/dashboard/api/inputs.py | 2 +- cea/interfaces/dashboard/api/project.py | 2 +- cea/interfaces/dashboard/api/tools.py | 2 +- cea/interfaces/dashboard/dashboard.py | 30 +- cea/interfaces/dashboard/dependencies.py | 45 + cea/interfaces/dashboard/plots/routes.py | 2 +- conda-lock.yml | 1208 +++++++++++++------- environment.yml | 3 +- 11 files changed, 863 insertions(+), 437 deletions(-) create mode 100644 cea/interfaces/dashboard/dependencies.py diff --git a/cea/interfaces/dashboard/api/contents.py b/cea/interfaces/dashboard/api/contents.py index b073696b57..b8f32690bb 100644 --- a/cea/interfaces/dashboard/api/contents.py +++ b/cea/interfaces/dashboard/api/contents.py @@ -5,7 +5,7 @@ from fastapi import APIRouter, HTTPException, status -from cea.interfaces.dashboard.dashboard import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig router = APIRouter() diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index b21d26d54e..8ce7ac9f49 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -6,7 +6,7 @@ import cea.config import cea.plots from .utils import deconstruct_parameters -from ..dashboard import CEAConfig, CEAPlotCache +from cea.interfaces.dashboard.dependencies import CEAConfig, CEAPlotCache router = APIRouter() diff --git a/cea/interfaces/dashboard/api/glossary.py b/cea/interfaces/dashboard/api/glossary.py index e6e65e895a..45d8e910f0 100644 --- a/cea/interfaces/dashboard/api/glossary.py +++ b/cea/interfaces/dashboard/api/glossary.py @@ -1,7 +1,7 @@ from fastapi import APIRouter from cea.glossary import read_glossary_df -from cea.interfaces.dashboard.dashboard import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig router = APIRouter() diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index c4edb4d7ab..b6d830196d 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -16,7 +16,7 @@ import cea.utilities.dbf from cea.datamanagement.databases_verification import InputFileValidator from cea.interfaces.dashboard.api.databases import read_all_databases, DATABASES_SCHEMA_KEYS -from cea.interfaces.dashboard.dashboard import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig from cea.plots.supply_system.a_supply_system_map import get_building_connectivity, newer_network_layout_exists from cea.plots.variable_naming import get_color_array from cea.technologies.network_layout.main import layout_network, NetworkLayout diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 4c62144218..1fa7f85ee3 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -13,7 +13,7 @@ import cea.api import cea.inputlocator -from cea.interfaces.dashboard.dashboard import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig from cea.plots.colors import color_to_rgb from cea.utilities.standardize_coordinates import get_geographic_coordinate_system diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index ef2608fa5c..19f78bf248 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -5,7 +5,7 @@ import cea.config import cea.scripts from .utils import deconstruct_parameters -from ..dashboard import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig router = APIRouter() diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index afbbaba18b..4df71483dd 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -1,38 +1,21 @@ import sys import uvicorn -from fastapi import FastAPI, Depends +from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from typing_extensions import Annotated -import cea.config -from cea.plots.cache import MemoryPlotCache +app = FastAPI() -_config = cea.config.Configuration() -_mem_cache = MemoryPlotCache(_config.project) +def configure_app(config): + global app -def get_cea_config(): - return _config - - -def get_plot_cache(): - return _mem_cache - - -CEAConfig = Annotated[dict, Depends(get_cea_config)] -CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] - - -def create_app(): origins = [ "http://localhost", "http://localhost:5173", "http://localhost:5050", ] - app = FastAPI() - # Setup CORS app.add_middleware( CORSMiddleware, @@ -59,12 +42,13 @@ def create_app(): def main(config): - app = create_app() + _app = configure_app(config) try: - uvicorn.run(app, host="127.0.0.1", port=5050) + uvicorn.run(_app, host="127.0.0.1", port=5050) except KeyboardInterrupt: sys.exit(0) if __name__ == "__main__": + import cea.config main(cea.config.Configuration()) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py new file mode 100644 index 0000000000..ad32c4db0b --- /dev/null +++ b/cea/interfaces/dashboard/dependencies.py @@ -0,0 +1,45 @@ + +from aiocache import caches, Cache +from aiocache.serializers import PickleSerializer +from fastapi import Depends +from typing_extensions import Annotated + +import cea.config +from cea.plots.cache import MemoryPlotCache + +CACHE_NAME = 'default' +caches.set_config({ + CACHE_NAME: { + 'cache': Cache.MEMORY, + 'serializer': { + 'class': PickleSerializer + } + } +}) + + +async def get_cea_config(): + _cache = caches.get(CACHE_NAME) + cea_config = await _cache.get("cea_config") + + if cea_config is None: + cea_config = cea.config.Configuration() + await _cache.set("cea_config", cea_config) + + return cea_config + + +async def get_plot_cache(): + _cache = caches.get(CACHE_NAME) + plot_cache = await _cache.get("plot_cache") + + if plot_cache is None: + cea_config = await get_cea_config() + plot_cache = MemoryPlotCache(cea_config.project) + await _cache.set("plot_cache", plot_cache) + + return plot_cache + + +CEAConfig = Annotated[dict, Depends(get_cea_config)] +CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] diff --git a/cea/interfaces/dashboard/plots/routes.py b/cea/interfaces/dashboard/plots/routes.py index 4669f15e71..f93c4ac0cf 100644 --- a/cea/interfaces/dashboard/plots/routes.py +++ b/cea/interfaces/dashboard/plots/routes.py @@ -9,7 +9,7 @@ import cea.plots.categories import cea.schemas from cea import MissingInputDataException -from cea.interfaces.dashboard.dashboard import CEAConfig, CEAPlotCache +from cea.interfaces.dashboard.dependencies import CEAConfig, CEAPlotCache router = APIRouter() diff --git a/conda-lock.yml b/conda-lock.yml index b008e9fdff..c4a07677e8 100644 --- a/conda-lock.yml +++ b/conda-lock.yml @@ -13,10 +13,10 @@ version: 1 metadata: content_hash: - linux-64: 19813f267c32b49385277fe02d0e011414ff9d7b357164dcd511594143ef0269 - osx-arm64: 791c61e3805445e0087ea1e716ff5a121943ec32d0fe87bb5a2d303c06bcab60 - osx-64: 7554236fa75e2a06989fbf8f819a6c200289c798925163e217068abe63857f33 - win-64: 38b1240ba23a7a2b5b33597a607c8a08e29897aa9f43b53acdab3c3210ac8e15 + linux-64: 225acce22efe66b43f4c42ca466447591e91494d9353a312e35db816a508862f + osx-arm64: f6a646c38a00c2698f668032021eb6bdd5c11ac5076420acc8e14fddb3522745 + osx-64: 50b8c3ffd17c8860d8d4371aff4b36249b3b973991f78261df9bb352152ab4ec + win-64: 98b1f44a435c4961177a19cebb6df861ad6d5b31601a7b420af9ec7cb85eac8d channels: - url: conda-forge used_env_vars: [] @@ -100,6 +100,54 @@ package: sha256: fbf0288cae7c6e5005280436ff73c95a36c5a4c978ba50175cc8e3eb22abc5f9 category: main optional: false +- name: aiocache + version: 0.12.2 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/aiocache-0.12.2-pyhd8ed1ab_0.conda + hash: + md5: 60f5e5202f57b50dba8b893d65851534 + sha256: 9ea26096791782101c1fd4783b9e0a8ee3778bafc83452db5ca3038cd6b3344b + category: main + optional: false +- name: aiocache + version: 0.12.2 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/aiocache-0.12.2-pyhd8ed1ab_0.conda + hash: + md5: 60f5e5202f57b50dba8b893d65851534 + sha256: 9ea26096791782101c1fd4783b9e0a8ee3778bafc83452db5ca3038cd6b3344b + category: main + optional: false +- name: aiocache + version: 0.12.2 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/aiocache-0.12.2-pyhd8ed1ab_0.conda + hash: + md5: 60f5e5202f57b50dba8b893d65851534 + sha256: 9ea26096791782101c1fd4783b9e0a8ee3778bafc83452db5ca3038cd6b3344b + category: main + optional: false +- name: aiocache + version: 0.12.2 + manager: conda + platform: win-64 + dependencies: + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/aiocache-0.12.2-pyhd8ed1ab_0.conda + hash: + md5: 60f5e5202f57b50dba8b893d65851534 + sha256: 9ea26096791782101c1fd4783b9e0a8ee3778bafc83452db5ca3038cd6b3344b + category: main + optional: false - name: aiohttp version: 3.9.5 manager: conda @@ -211,8 +259,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' frozenlist: '>=1.1.0' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 hash: md5: d1e1eb7e21a9e2c74279d87dafb68156 @@ -333,11 +381,11 @@ package: manager: conda platform: osx-arm64 dependencies: - typing_extensions: '' exceptiongroup: '' + idna: '>=2.8' python: '>=3.7' sniffio: '>=1.1' - idna: '>=2.8' + typing_extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/anyio-3.7.1-pyhd8ed1ab_0.conda hash: md5: 7b517e7a6f0790337906c055aa97ca49 @@ -468,9 +516,9 @@ package: manager: conda platform: osx-arm64 dependencies: - typing-extensions: '' argon2-cffi-bindings: '' python: '>=3.7' + typing-extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda hash: md5: 3afef1f55a1366b4d3b6a0d92e2235e4 @@ -1663,9 +1711,9 @@ package: manager: conda platform: osx-arm64 dependencies: - setuptools: '' - pytz: '' python: '>=3.7' + pytz: '' + setuptools: '' url: https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda hash: md5: 9669586875baeced8fc30c0826c3270e @@ -1871,11 +1919,11 @@ package: manager: conda platform: osx-arm64 dependencies: - setuptools: '' packaging: '' - webencodings: '' python: '>=3.6' + setuptools: '' six: '>=1.9.0' + webencodings: '' url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda hash: md5: 0ed9d7c0e9afa7c025807a9a8136ea3e @@ -2064,8 +2112,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' jinja2: '>=3' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/branca-0.7.2-pyhd8ed1ab_0.conda hash: md5: 5f1c719f1cac0aee5e6bd6ca7d54a7fa @@ -2892,8 +2940,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '' click: '>=3.0' + python: '' url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 hash: md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f @@ -2944,8 +2992,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: <4.0 click: '>=4.0' + python: <4.0 url: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_1.tar.bz2 hash: md5: a29b7c141d6b2de4bb67788a5f107734 @@ -3620,8 +3668,8 @@ package: manager: conda platform: osx-arm64 dependencies: - sniffio: '' python: '>=3.8.0,<4.0.0' + sniffio: '' url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda hash: md5: 936e6aadb75534384d11d982fab74b61 @@ -3802,107 +3850,107 @@ package: category: main optional: false - name: email-validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: linux-64 dependencies: dnspython: '>=2.0.0' idna: '>=2.0.0' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_0.conda hash: - md5: 2561eeb8ac8f67259ed898d77c7c97a1 - sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + md5: 3067adf57ee658ddf5bfad47b0041ce4 + sha256: ea9e936ed7c49ea6d66fa3554afe31ba311f2a3d5e384d8c38925fda9e37bdb9 category: main optional: false - name: email-validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: osx-64 dependencies: python: '>=3.7' idna: '>=2.0.0' dnspython: '>=2.0.0' - url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_0.conda hash: - md5: 2561eeb8ac8f67259ed898d77c7c97a1 - sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + md5: 3067adf57ee658ddf5bfad47b0041ce4 + sha256: ea9e936ed7c49ea6d66fa3554afe31ba311f2a3d5e384d8c38925fda9e37bdb9 category: main optional: false - name: email-validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' - idna: '>=2.0.0' dnspython: '>=2.0.0' - url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + idna: '>=2.0.0' + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_0.conda hash: - md5: 2561eeb8ac8f67259ed898d77c7c97a1 - sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + md5: 3067adf57ee658ddf5bfad47b0041ce4 + sha256: ea9e936ed7c49ea6d66fa3554afe31ba311f2a3d5e384d8c38925fda9e37bdb9 category: main optional: false - name: email-validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: win-64 dependencies: python: '>=3.7' idna: '>=2.0.0' dnspython: '>=2.0.0' - url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.1.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_0.conda hash: - md5: 2561eeb8ac8f67259ed898d77c7c97a1 - sha256: 6669a409da893b4dec7eb5baec90a67361d653f05816033ebf277ada6a679a7f + md5: 3067adf57ee658ddf5bfad47b0041ce4 + sha256: ea9e936ed7c49ea6d66fa3554afe31ba311f2a3d5e384d8c38925fda9e37bdb9 category: main optional: false - name: email_validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: linux-64 dependencies: - email-validator: '>=2.1.2,<2.1.3.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + email-validator: '>=2.2.0,<2.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_0.conda hash: - md5: 0b6f091a3677f51ed4c24e346da25237 - sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + md5: 0214a004f7cf5ac28fc10a390dfc47ee + sha256: 2cbbbe9e0f3872214227c27b8b775dd2296a435c90ef50a7cc69934c329b6c65 category: main optional: false - name: email_validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: osx-64 dependencies: - email-validator: '>=2.1.2,<2.1.3.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + email-validator: '>=2.2.0,<2.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_0.conda hash: - md5: 0b6f091a3677f51ed4c24e346da25237 - sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + md5: 0214a004f7cf5ac28fc10a390dfc47ee + sha256: 2cbbbe9e0f3872214227c27b8b775dd2296a435c90ef50a7cc69934c329b6c65 category: main optional: false - name: email_validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: osx-arm64 dependencies: - email-validator: '>=2.1.2,<2.1.3.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + email-validator: '>=2.2.0,<2.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_0.conda hash: - md5: 0b6f091a3677f51ed4c24e346da25237 - sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + md5: 0214a004f7cf5ac28fc10a390dfc47ee + sha256: 2cbbbe9e0f3872214227c27b8b775dd2296a435c90ef50a7cc69934c329b6c65 category: main optional: false - name: email_validator - version: 2.1.2 + version: 2.2.0 manager: conda platform: win-64 dependencies: - email-validator: '>=2.1.2,<2.1.3.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.1.2-hd8ed1ab_0.conda + email-validator: '>=2.2.0,<2.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/email_validator-2.2.0-hd8ed1ab_0.conda hash: - md5: 0b6f091a3677f51ed4c24e346da25237 - sha256: 5cc9c89693be29c3cecc4bb3ba1d1665b02dc9b7d8eca486f2096ad81ad3fdc1 + md5: 0214a004f7cf5ac28fc10a390dfc47ee + sha256: 2cbbbe9e0f3872214227c27b8b775dd2296a435c90ef50a7cc69934c329b6c65 category: main optional: false - name: entrypoints @@ -4253,18 +4301,18 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - httpx: '>=0.23.0' - python-multipart: '>=0.0.7' - typing-extensions: '>=4.8.0' - pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' - starlette: '>=0.37.2,<0.38.0' - jinja2: '>=2.11.2' - uvicorn: '>=0.12.0' email_validator: '>=2.0.0' fastapi-cli: '>=0.0.2' + httpx: '>=0.23.0' + jinja2: '>=2.11.2' orjson: '>=3.2.1' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + python: '>=3.8' + python-multipart: '>=0.0.7' + starlette: '>=0.37.2,<0.38.0' + typing-extensions: '>=4.8.0' ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + uvicorn: '>=0.12.0' url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda hash: md5: 7d347962e391cffc68f922c344f7cb3c @@ -4331,8 +4379,8 @@ package: dependencies: fastapi: '' python: '>=3.8' - uvicorn: '>=0.15.0' typer: '>=0.12.3' + uvicorn: '>=0.15.0' url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda hash: md5: 2581ef67574e5b5400c0c151cc1c8b15 @@ -4672,12 +4720,12 @@ package: manager: conda platform: osx-arm64 dependencies: + branca: '>=0.6.0' + jinja2: '>=2.9' numpy: '' + python: '>=3.8' requests: '' xyzservices: '' - python: '>=3.8' - jinja2: '>=2.9' - branca: '>=0.6.0' url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: md5: 9b96a3e6e0473b5722fa4fbefcefcded @@ -5022,10 +5070,10 @@ package: manager: conda platform: osx-arm64 dependencies: + font-ttf-dejavu-sans-mono: '' font-ttf-inconsolata: '' font-ttf-source-code-pro: '' font-ttf-ubuntu: '' - font-ttf-dejavu-sans-mono: '' url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 hash: md5: f766549260d6815b0c52253f1fb1bb29 @@ -5538,14 +5586,14 @@ package: manager: conda platform: osx-arm64 dependencies: + fiona: '>=1.8.19' + folium: '' + geopandas-base: 0.13.2 + mapclassify: '>=2.4.0' matplotlib-base: '' + python: '>=3.8' rtree: '' - folium: '' xyzservices: '' - python: '>=3.8' - mapclassify: '>=2.4.0' - fiona: '>=1.8.19' - geopandas-base: 0.13.2 url: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.13.2-pyhd8ed1ab_1.conda hash: md5: 47226a55e4ae3bc9feb3a17925874817 @@ -5609,10 +5657,10 @@ package: platform: osx-arm64 dependencies: packaging: '' - python: '>=3.8' pandas: '>=1.1.0' - shapely: '>=1.7.1' pyproj: '>=3.0.1' + python: '>=3.8' + shapely: '>=1.7.1' url: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.13.2-pyha770c72_1.conda hash: md5: c6036236caae7d8ac684c41c64073b9e @@ -6369,10 +6417,10 @@ package: dependencies: libgcc-ng: '>=12' libstdcxx-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda hash: - md5: e358c7c5f6824c272b5034b3816438a7 - sha256: cfc4202c23d6895d9c84042d08d5cda47d597772df870d4d2a10fc86dded5576 + md5: c94a5994ef49749880a8139cf9afcbe1 + sha256: 309cf4f04fec0c31b6771a5809a1909b4b3154a2208f52351e1ada006f4c750c category: main optional: false - name: gmp @@ -6380,11 +6428,12 @@ package: manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libcxx: '>=16' - url: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-h73e2aa4_1.conda + url: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-hf036a51_2.conda hash: - md5: 92f8d748d95d97f92fc26cfac9bb5b6e - sha256: 1a5b117908deb5a12288aba84dd0cb913f779c31c75f5a57d1a00e659e8fa3d3 + md5: 427101d13f19c4974552a4e5b072eef1 + sha256: 75aa5e7a875afdcf4903b7dc98577672a3dc17b528ac217b915f9528f93c85fc category: main optional: false - name: gmp @@ -6392,11 +6441,12 @@ package: manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' libcxx: '>=16' - url: https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-hebf3989_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda hash: - md5: 64f45819921ba710398706e1a6404eb5 - sha256: 0ed5aff70675dc0ed5c2f39bb02b908b864e8eee4ceb56e1c798ba8d7509551f + md5: eed7278dfbab727b56f2c0b64330814b + sha256: 76e222e072d61c840f64a44e0580c2503562b009090f55aa45053bf1ccb385dd category: main optional: false - name: gnutls @@ -6717,8 +6767,8 @@ package: manager: conda platform: osx-arm64 dependencies: - typing_extensions: '' python: '>=3' + typing_extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b21ed0883505ba1910994f1df031a428 @@ -6771,9 +6821,9 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.6.1' hpack: '>=4.0,<5' hyperframe: '>=6.0,<7' + python: '>=3.6.1' url: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b748fbf7060927a6e82df7cb5ee8f097 @@ -6786,8 +6836,8 @@ package: platform: win-64 dependencies: python: '>=3.6.1' - hpack: '>=4.0,<5' hyperframe: '>=6.0,<7' + hpack: '>=4.0,<5' url: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b748fbf7060927a6e82df7cb5ee8f097 @@ -7165,12 +7215,12 @@ package: manager: conda platform: osx-arm64 dependencies: + anyio: '>=3.0,<5.0' certifi: '' + h11: '>=0.13,<0.15' + h2: '>=3,<5' python: '>=3.8' sniffio: 1.* - h2: '>=3,<5' - anyio: '>=3.0,<5.0' - h11: '>=0.13,<0.15' url: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda hash: md5: a6b9a0158301e697e4d0a36a3d60e133 @@ -7194,6 +7244,62 @@ package: sha256: 4025644200eefa0598e4600a66fd4804a57d9fd7054a5c8c45e508fd875e0b84 category: main optional: false +- name: httptools + version: 0.6.1 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/httptools-0.6.1-py38h01eb140_0.conda + hash: + md5: 7d67a5ef9c5170d63afc87abc3b8146d + sha256: 5956e1a87856bffaf6b5e1cd2ea53352792778ab5a7fbc3aef33fded56b1a115 + category: main + optional: false +- name: httptools + version: 0.6.1 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/httptools-0.6.1-py38hae2e43d_0.conda + hash: + md5: 403f7760ceab2d70f3d760ab6e7bbf10 + sha256: 3d45b6d7dd0dc2cb5e0735be23f1c890205b678d5b13b6dd447275ee8bb3ad94 + category: main + optional: false +- name: httptools + version: 0.6.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/httptools-0.6.1-py38h336bac9_0.conda + hash: + md5: 74633d4c25b79f108d2ffbd1fd110fb2 + sha256: 0a5582a25efe54027175a9bbf5391269aba135f6666836292f23fe0c6eb5986e + category: main + optional: false +- name: httptools + version: 0.6.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/httptools-0.6.1-py38h91455d4_0.conda + hash: + md5: 9f1ecae73c2b378bcda0cea84e0bf57b + sha256: 256fb74e47be5f8891388b6fc9bbc809a2c5111a7394abb3ec7e90500d3a8a65 + category: main + optional: false - name: httpx version: 0.27.0 manager: conda @@ -7233,12 +7339,12 @@ package: manager: conda platform: osx-arm64 dependencies: + anyio: '' certifi: '' + httpcore: 1.* idna: '' - anyio: '' - sniffio: '' python: '>=3.8' - httpcore: 1.* + sniffio: '' url: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda hash: md5: 9f359af5a886fd6ca6b2b6ea02e58332 @@ -7464,55 +7570,55 @@ package: category: main optional: false - name: importlib-metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: linux-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda hash: - md5: 0896606848b2dc5cebdf111b6543aa04 - sha256: cc2e7d1f7f01cede30feafc1118b7aefa244d0a12224513734e24165ae12ba49 + md5: b9f5330c0853ccabc39a9878c6f1a2ab + sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 category: main optional: false - name: importlib-metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: osx-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda hash: - md5: 0896606848b2dc5cebdf111b6543aa04 - sha256: cc2e7d1f7f01cede30feafc1118b7aefa244d0a12224513734e24165ae12ba49 + md5: b9f5330c0853ccabc39a9878c6f1a2ab + sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 category: main optional: false - name: importlib-metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda hash: - md5: 0896606848b2dc5cebdf111b6543aa04 - sha256: cc2e7d1f7f01cede30feafc1118b7aefa244d0a12224513734e24165ae12ba49 + md5: b9f5330c0853ccabc39a9878c6f1a2ab + sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 category: main optional: false - name: importlib-metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: win-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda hash: - md5: 0896606848b2dc5cebdf111b6543aa04 - sha256: cc2e7d1f7f01cede30feafc1118b7aefa244d0a12224513734e24165ae12ba49 + md5: b9f5330c0853ccabc39a9878c6f1a2ab + sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 category: main optional: false - name: importlib-resources @@ -7546,8 +7652,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' importlib_resources: '>=6.4.0,<6.4.1.0a0' + python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.4.0-pyhd8ed1ab_0.conda hash: md5: dcbadab7a68738a028e195ab68ab2d2e @@ -7568,51 +7674,51 @@ package: category: main optional: false - name: importlib_metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: linux-64 dependencies: - importlib-metadata: '>=7.1.0,<7.1.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda + importlib-metadata: '>=7.2.1,<7.2.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda hash: - md5: 6ef2b72d291b39e479d7694efa2b2b98 - sha256: 01dc057a45dedcc742a71599f67c7383ae2bf873be6018ebcbd06ac8d994dedb + md5: d6c936d009aa63e5f82d216c95cdcaee + sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 category: main optional: false - name: importlib_metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: osx-64 dependencies: - importlib-metadata: '>=7.1.0,<7.1.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda + importlib-metadata: '>=7.2.1,<7.2.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda hash: - md5: 6ef2b72d291b39e479d7694efa2b2b98 - sha256: 01dc057a45dedcc742a71599f67c7383ae2bf873be6018ebcbd06ac8d994dedb + md5: d6c936d009aa63e5f82d216c95cdcaee + sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 category: main optional: false - name: importlib_metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: osx-arm64 dependencies: - importlib-metadata: '>=7.1.0,<7.1.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda + importlib-metadata: '>=7.2.1,<7.2.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda hash: - md5: 6ef2b72d291b39e479d7694efa2b2b98 - sha256: 01dc057a45dedcc742a71599f67c7383ae2bf873be6018ebcbd06ac8d994dedb + md5: d6c936d009aa63e5f82d216c95cdcaee + sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 category: main optional: false - name: importlib_metadata - version: 7.1.0 + version: 7.2.1 manager: conda platform: win-64 dependencies: - importlib-metadata: '>=7.1.0,<7.1.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda + importlib-metadata: '>=7.2.1,<7.2.2.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda hash: - md5: 6ef2b72d291b39e479d7694efa2b2b98 - sha256: 01dc057a45dedcc742a71599f67c7383ae2bf873be6018ebcbd06ac8d994dedb + md5: d6c936d009aa63e5f82d216c95cdcaee + sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 category: main optional: false - name: importlib_resources @@ -7734,21 +7840,21 @@ package: manager: conda platform: osx-arm64 dependencies: - packaging: '' - psutil: '' - nest-asyncio: '' __osx: '' appnope: '' - python: '>=3.8' - tornado: '>=6.1' + comm: '>=0.1.1' + debugpy: '>=1.6.5' + ipython: '>=7.23.1' jupyter_client: '>=6.1.12' jupyter_core: '>=4.12,!=5.0.*' - ipython: '>=7.23.1' matplotlib-inline: '>=0.1' - debugpy: '>=1.6.5' - comm: '>=0.1.1' - traitlets: '>=5.4.0' + nest-asyncio: '' + packaging: '' + psutil: '' + python: '>=3.8' pyzmq: '>=24' + tornado: '>=6.1' + traitlets: '>=5.4.0' url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda hash: md5: 1e991f9ed4a81d3482d46edbeb54721a @@ -7834,20 +7940,20 @@ package: manager: conda platform: osx-arm64 dependencies: - typing_extensions: '' - decorator: '' __osx: '' - matplotlib-inline: '' - stack_data: '' - pickleshare: '' appnope: '' backcall: '' - python: '>=3.8' - pygments: '>=2.4.0' - traitlets: '>=5' + decorator: '' jedi: '>=0.16' + matplotlib-inline: '' pexpect: '>4.3' + pickleshare: '' prompt_toolkit: '>=3.0.30,<3.1.0,!=3.0.37' + pygments: '>=2.4.0' + python: '>=3.8' + stack_data: '' + traitlets: '>=5' + typing_extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.12.2-pyhd1c38e8_0.conda hash: md5: acc618532cbc899f5721cc96407b16cc @@ -7909,8 +8015,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' arrow: '>=0.15.0' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 4cb68948e0b8429534380243d063a27a @@ -7977,8 +8083,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.6' parso: '>=0.8.3,<0.9.0' + python: '>=3.6' url: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda hash: md5: 81a3be0b2023e1ea8555781f0ad904a2 @@ -8029,8 +8135,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' markupsafe: '>=2.0' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.4-pyhd8ed1ab_0.conda hash: md5: 7b86ecb7d3557821c649b3c31e3eb9f2 @@ -8081,8 +8187,8 @@ package: manager: conda platform: osx-arm64 dependencies: - setuptools: '' python: '>=3.8' + setuptools: '' url: https://conda.anaconda.org/conda-forge/noarch/joblib-1.4.2-pyhd8ed1ab_0.conda hash: md5: 25df261d4523d9f9783bcdb7208d872f @@ -8375,11 +8481,11 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' attrs: '>=22.2.0' importlib_resources: '>=1.4.0' - pkgutil-resolve-name: '>=1.3.10' jsonschema-specifications: '>=2023.03.6' + pkgutil-resolve-name: '>=1.3.10' + python: '>=3.8' referencing: '>=0.28.4' rpds-py: '>=0.7.1' url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda @@ -8439,8 +8545,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' importlib_resources: '>=1.4.0' + python: '>=3.8' referencing: '>=0.31.0' url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda hash: @@ -8509,16 +8615,16 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '' - idna: '' - rfc3339-validator: '' - uri-template: '' fqdn: '' + idna: '' isoduration: '' jsonpointer: '>1.13' - webcolors: '>=1.11' - rfc3986-validator: '>0.1.0' jsonschema: '>=4.22.0,<4.22.1.0a0' + python: '' + rfc3339-validator: '' + rfc3986-validator: '>0.1.0' + uri-template: '' + webcolors: '>=1.11' url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda hash: md5: 32ab666927ee17b9468c2c72bbd7ba1b @@ -8579,9 +8685,9 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' importlib-metadata: '>=4.8.3' jupyter_server: '>=1.1.2' + python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda hash: md5: 885867f6adab3d7ecdf8ab6ca0785f51 @@ -8643,13 +8749,13 @@ package: manager: conda platform: osx-arm64 dependencies: + importlib_metadata: '>=4.8.3' + jupyter_core: '>=4.12,!=5.0.*' python: '>=3.8' python-dateutil: '>=2.8.2' - jupyter_core: '>=4.12,!=5.0.*' - importlib_metadata: '>=4.8.3' - traitlets: '>=5.3' pyzmq: '>=23.0' tornado: '>=6.2' + traitlets: '>=5.3' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: md5: 3cdbb2fa84490e5fd44c9f9806c0d292 @@ -8778,14 +8884,14 @@ package: manager: conda platform: osx-arm64 dependencies: - referencing: '' - rfc3339-validator: '' + jsonschema-with-format-nongpl: '>=4.18.0' python: '>=3.8' + python-json-logger: '>=2.0.4' pyyaml: '>=5.3' + referencing: '' + rfc3339-validator: '' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' - python-json-logger: '>=2.0.4' - jsonschema-with-format-nongpl: '>=4.18.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: md5: ed45423c41b3da15ea1df39b1f80c2ca @@ -8876,25 +8982,25 @@ package: manager: conda platform: osx-arm64 dependencies: - packaging: '' - jinja2: '' - prometheus_client: '' - websocket-client: '' + anyio: '>=3.1.0,<4' argon2-cffi: '' - overrides: '' - send2trash: '' - jupyter_server_terminals: '' - python: '>=3.8' - terminado: '>=0.8.3' + jinja2: '' + jupyter_client: '>=7.4.4' jupyter_core: '>=4.12,!=5.0.*' - tornado: '>=6.2.0' - pyzmq: '>=24' + jupyter_events: '>=0.4.0' + jupyter_server_terminals: '' nbconvert-core: '>=6.4.4' - anyio: '>=3.1.0,<4' - jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' + overrides: '' + packaging: '' + prometheus_client: '' + python: '>=3.8' + pyzmq: '>=24' + send2trash: '' + terminado: '>=0.8.3' + tornado: '>=6.2.0' traitlets: '>=5.6.0' - jupyter_events: '>=0.4.0' + websocket-client: '' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.7.0-pyhd8ed1ab_0.conda hash: md5: 7488cd1f4d35a2af96faa765b7e5b2f0 @@ -9044,23 +9150,23 @@ package: manager: conda platform: osx-arm64 dependencies: - packaging: '' - traitlets: '' - jupyter_core: '' - python: '>=3.8' - tornado: '>=6.2.0' - tomli: '>=1.2.2' - jinja2: '>=3.0.3' + async-lru: '>=1.0.0' + httpx: '>=0.25.0' importlib_metadata: '>=4.8.3' - jupyter_server: '>=2.4.0,<3' importlib_resources: '>=1.4' + ipykernel: '>=6.5.0' + jinja2: '>=3.0.3' jupyter-lsp: '>=2.0.0' - async-lru: '>=1.0.0' + jupyter_core: '' + jupyter_server: '>=2.4.0,<3' + jupyterlab_server: '>=2.27.1,<3' notebook-shim: '>=0.2' + packaging: '' + python: '>=3.8' setuptools: '>=40.1.0' - httpx: '>=0.25.0' - jupyterlab_server: '>=2.27.1,<3' - ipykernel: '>=6.5.0' + tomli: '>=1.2.2' + tornado: '>=6.2.0' + traitlets: '' url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda hash: md5: 405a9d330af26391c8001d56b3ef4239 @@ -9126,8 +9232,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' pygments: '>=2.4.1,<3' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda hash: md5: afcd1b53bcac8844540358e33f33d28f @@ -9192,15 +9298,15 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - packaging: '>=21.3' - jinja2: '>=3.0.3' - importlib-metadata: '>=4.8.3' - requests: '>=2.31' - jupyter_server: '>=1.21,<3' babel: '>=2.10' + importlib-metadata: '>=4.8.3' + jinja2: '>=3.0.3' json5: '>=0.9.0' jsonschema: '>=4.18' + jupyter_server: '>=1.21,<3' + packaging: '>=21.3' + python: '>=3.8' + requests: '>=2.31' url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda hash: md5: d1cb7b113daaadd89e5aa6a32b28bf0d @@ -9216,8 +9322,8 @@ package: packaging: '>=21.3' jinja2: '>=3.0.3' importlib-metadata: '>=4.8.3' - requests: '>=2.31' jupyter_server: '>=1.21,<3' + requests: '>=2.31' babel: '>=2.10' json5: '>=0.9.0' jsonschema: '>=4.18' @@ -10770,10 +10876,10 @@ package: dependencies: _libgcc_mutex: '0.1' _openmp_mutex: '>=4.5' - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_11.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_13.conda hash: - md5: 0b3b218a596bb4c3854cc9ee799f94e5 - sha256: bbdd49b5a191105cf4bf82a59d611afa1e8568efa556dd988e4e5d0efc3058b1 + md5: 9358cdd61ef0d600d2a0dde2d53b006c + sha256: ffa0f472c8b37f864de855af2d3c057f1813162319f10ebd97332d73fc27ba60 category: main optional: false - name: libgcrypt @@ -11128,10 +11234,10 @@ package: platform: linux-64 dependencies: libgfortran5: 13.2.0 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_11.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_13.conda hash: - md5: 4c3e460d6acf8e43e4ce8bf405187eb7 - sha256: f91aa928161201f189057c90db1508def36bef6329ebb29a71d8064b180250dd + md5: 516e66b26eea14e7e322fe99e88e0f02 + sha256: 3ef5d92510e9cdd70ec2a9f1f83b8c1d327ff0f9bfc17831a8f8f06f10c2085c category: main optional: false - name: libgfortran5 @@ -11140,10 +11246,10 @@ package: platform: linux-64 dependencies: libgcc-ng: '>=13.2.0' - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_11.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_13.conda hash: - md5: c485da4fdb454539f852a90ae06e9bb7 - sha256: de8535b5fb39a78f4b7473b88c400c922ae063f29500c097743b480fd0a4f326 + md5: 1e380198685bc1e993bbbc4b579f5916 + sha256: 19cffb68b19ff5f426d1cb3db670dccb73c09f54b8d3f8e304665e2cee68f14f category: main optional: false - name: libgfortran5 @@ -11262,10 +11368,10 @@ package: platform: linux-64 dependencies: _libgcc_mutex: '0.1' - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_11.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_13.conda hash: - md5: 8c462ced2af33648195dc9459f331f31 - sha256: f4112111fa350bcd8d6d354cdde3426751a579add88fa523f6483c714821e681 + md5: d370d1855cca14dff6a819c90c77497c + sha256: c5949bec7eee93cdd5c367e6e5c5e92ee1c5139a827567af23853dd52721d8ed category: main optional: false - name: libgoogle-cloud @@ -11971,50 +12077,53 @@ package: category: main optional: false - name: libogg - version: 1.3.4 + version: 1.3.5 manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=9.3.0' - url: https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.4-h7f98852_1.tar.bz2 + libgcc-ng: '>=12' + url: https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-h4ab18f5_0.conda hash: - md5: 6e8cc2173440d77708196c5b93771680 - sha256: b88afeb30620b11bed54dac4295aa57252321446ba4e6babd7dce4b9ffde9b25 + md5: 601bfb4b3c6f0b844443bb81a56651e0 + sha256: 5eda3fe92b99b25dd4737226a9485078ab405672d9f621be75edcb68f1e9026d category: main optional: false - name: libogg - version: 1.3.4 + version: 1.3.5 manager: conda platform: osx-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/libogg-1.3.4-h35c211d_1.tar.bz2 + dependencies: + __osx: '>=10.13' + url: https://conda.anaconda.org/conda-forge/osx-64/libogg-1.3.5-hfdf4475_0.conda hash: - md5: a7ab4b53ef18c598ffaa597230bc3ba1 - sha256: e3cec0c66d352d822b7a90db8edbc62f237fca079b6044e5b27f6ca529f7d9d9 + md5: 7497372c91a31d3e8d64ce3f1a9632e8 + sha256: bebf5797e2a278fd2094f2b0c29ccdfc51d400f4736701108a7e544a49705c64 category: main optional: false - name: libogg - version: 1.3.4 + version: 1.3.5 manager: conda platform: osx-arm64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/libogg-1.3.4-h27ca646_1.tar.bz2 + dependencies: + __osx: '>=11.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libogg-1.3.5-h99b78c6_0.conda hash: - md5: fb211883ad5716e398b974a9cde9d78e - sha256: 916bbd5b7da6c922d6a16dd7d396b8a4e862edaca045671692e35add58aace64 + md5: 57b668b9b78dea2c08e44bb2385d57c0 + sha256: 685f73b7241978007dfe0cecb9cae46c6a26d87d192b6f85a09eb65023c0b99e category: main optional: false - name: libogg - version: 1.3.4 + version: 1.3.5 manager: conda platform: win-64 dependencies: - vc: '>=14.1,<15.0a0' - vs2015_runtime: '>=14.16.27012' - url: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.4-h8ffe710_1.tar.bz2 + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.5-h2466b09_0.conda hash: - md5: 04286d905a0dcb7f7d4a12bdfe02516d - sha256: ef20f04ad2121a07e074b34bfc211587df18180e680963f5c02c54d1951b9ee6 + md5: 44a4d173e62c5ed6d715f18ae7c46b7a + sha256: fcffdf32c620569738b85c98ddd25e1c84c8add80cd732743d90d469b7b532bb category: main optional: false - name: libopenblas @@ -12338,17 +12447,17 @@ package: manager: conda platform: osx-arm64 dependencies: - requests: '' - packaging: '' - jinja2: '' - geopandas: '' beautifulsoup4: '' + geopandas: '' + jinja2: '' + numpy: '>=1.3' + packaging: '' + pandas: '>=1.4' platformdirs: '' python: '>=3.8' - pandas: '>=1.4' + requests: '' scipy: '>=1.8' shapely: '>=2.0' - numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/libpysal-4.8.0-pyhd8ed1ab_1.conda hash: md5: ea5d04d8018c1f2ba75a1fd3c30e830b @@ -12820,10 +12929,10 @@ package: platform: linux-64 dependencies: libgcc-ng: 13.2.0 - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_11.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_13.conda hash: - md5: eaa8ea74083fb4a78ae19e431e556003 - sha256: e03f0f2712f45a85234016bcc5afa76023e31e00a2e74d8819a1b3bdf091fdb0 + md5: 1053882642ed5bbc799e1e866ff86826 + sha256: 143171c6084e526122cc2976fbbfadf7b9f50e5d13036adf20feb7ed9d036dd2 category: main optional: false - name: libsystemd0 @@ -13647,27 +13756,27 @@ package: category: main optional: false - name: llvm-openmp - version: 18.1.7 + version: 18.1.8 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' - url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.7-h15ab845_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.8-h15ab845_0.conda hash: - md5: 57440310d92e93efd808c75fec50f94d - sha256: 66ab0feed5ed7ace0d9327bc7ae47500afb81ef51e6ef10a478af9d65dd60ac6 + md5: 2c3c6c8aaf8728f87326964a82fdc7d8 + sha256: 0fd74128806bd839c7a9aa343faf265b94aece84f75f67f14b6246936138e61e category: main optional: false - name: llvm-openmp - version: 18.1.7 + version: 18.1.8 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.7-hde57baf_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.8-hde57baf_0.conda hash: - md5: 2f651f8977594cc74852fa280785187a - sha256: 30121bc3ebf134d69bcb24ab1270bfa2beeb0ae59579b8acb67a38e3531c05d1 + md5: 82393fdbe38448d878a8848b6fcbcefb + sha256: 42bc913b3c91934a1ce7ff635e87ee48e2e252632f0cbf607c5a3e4409d9f9dd category: main optional: false - name: llvmlite @@ -13948,12 +14057,12 @@ package: manager: conda platform: osx-arm64 dependencies: - scikit-learn: '' networkx: '' - python: '>=3.6' + numpy: '>=1.3' pandas: '>=1.0' + python: '>=3.6' + scikit-learn: '' scipy: '>=1.0' - numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.5.0-pyhd8ed1ab_1.conda hash: md5: db1aeaff6e248db425e049feffded7a9 @@ -14008,8 +14117,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' mdurl: '>=0.1,<1' + python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda hash: md5: 93a8e71256479c62074356ef6ebf501b @@ -14287,8 +14396,8 @@ package: manager: conda platform: osx-arm64 dependencies: - traitlets: '' python: '>=3.6' + traitlets: '' url: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_0.conda hash: md5: 779345c95648be40d22aaa89de7d4254 @@ -14915,10 +15024,10 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' jupyter_client: '>=6.1.12' jupyter_core: '>=4.12,!=5.0.*' nbformat: '>=5.1' + python: '>=3.8' traitlets: '>=5.4' url: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda hash: @@ -15003,23 +15112,23 @@ package: manager: conda platform: osx-arm64 dependencies: - packaging: '' beautifulsoup4: '' - defusedxml: '' bleach: '' - tinycss2: '' - jupyterlab_pygments: '' - python: '>=3.8' - jinja2: '>=3.0' + defusedxml: '' entrypoints: '>=0.2.2' - markupsafe: '>=2.0' + jinja2: '>=3.0' jupyter_core: '>=4.7' - traitlets: '>=5.0' - pandocfilters: '>=1.4.1' + jupyterlab_pygments: '' + markupsafe: '>=2.0' + mistune: '>=2.0.3,<4' + nbclient: '>=0.5.0' nbformat: '>=5.1' + packaging: '' + pandocfilters: '>=1.4.1' pygments: '>=2.4.1' - nbclient: '>=0.5.0' - mistune: '>=2.0.3,<4' + python: '>=3.8' + tinycss2: '' + traitlets: '>=5.0' url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: md5: e2d2abb421c13456a9a9f80272fdf543 @@ -15091,11 +15200,11 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - jupyter_core: '>=4.12,!=5.0.*' - traitlets: '>=5.1' jsonschema: '>=2.6' + jupyter_core: '>=4.12,!=5.0.*' + python: '>=3.8' python-fastjsonschema: '>=2.15' + traitlets: '>=5.1' url: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda hash: md5: 0b57b5368ab7fc7cdc9e3511fa867214 @@ -15431,12 +15540,12 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - tornado: '>=6.2.0' jupyter_server: '>=2.4.0,<3' - notebook-shim: '>=0.2,<0.3' - jupyterlab_server: '>=2.27.1,<3' jupyterlab: '>=4.2.0,<4.3' + jupyterlab_server: '>=2.27.1,<3' + notebook-shim: '>=0.2,<0.3' + python: '>=3.8' + tornado: '>=6.2.0' url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: md5: 08fa71a038c2cac2e636a5a456df15d5 @@ -15491,8 +15600,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' jupyter_server: '>=1.8,<3' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda hash: md5: 3d85618e2c97ab896b5b5e298d32b5b3 @@ -15773,8 +15882,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.5' numpy: '>=1.15' + python: '>=3.5' url: https://conda.anaconda.org/conda-forge/noarch/numpy-financial-1.0.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 3483f2da98bccd9363d09e1c9fee6f72 @@ -16336,18 +16445,18 @@ package: manager: conda platform: osx-arm64 dependencies: - numpy: '' - requests: '' - pandas: '' - scipy: '' + folium: '' + gdal: '' + geopandas: '' matplotlib-base: '' - scikit-learn: '' networkx: '' - geopandas: '' - rasterio: '' - gdal: '' - folium: '' + numpy: '' + pandas: '' python: '>=3.8' + rasterio: '' + requests: '' + scikit-learn: '' + scipy: '' shapely: '>=2.0' url: https://conda.anaconda.org/conda-forge/noarch/osmnx-1.8.1-pyhd8ed1ab_0.conda hash: @@ -16410,8 +16519,8 @@ package: manager: conda platform: osx-arm64 dependencies: - typing_utils: '' python: '>=3.6' + typing_utils: '' url: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda hash: md5: 24fba5a9d161ad8103d4e84c0e1a3ed4 @@ -16727,11 +16836,11 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' dill: '>=0.3.8' - pox: '>=0.3.4' multiprocess: '>=0.70.16' + pox: '>=0.3.4' ppft: '>=1.7.6.8' + python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/pathos-0.3.2-pyhd8ed1ab_1.conda hash: md5: 22ed208c1b54e7c2ec6616665fba6b0f @@ -16787,9 +16896,9 @@ package: manager: conda platform: osx-arm64 dependencies: - six: '' - python: '>=3.6' numpy: '>=1.4.0' + python: '>=3.6' + six: '' url: https://conda.anaconda.org/conda-forge/noarch/patsy-0.5.6-pyhd8ed1ab_0.conda hash: md5: a5b55d1cb110cdcedc748b5c3e16e687 @@ -16932,8 +17041,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' ptyprocess: '>=0.5' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda hash: md5: 629f3203c99b32e0988910c93e77f3b6 @@ -17113,9 +17222,9 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.7' setuptools: '' wheel: '' - python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda hash: md5: f586ac1e56c8638b64f9c8122a7b8a67 @@ -17398,10 +17507,10 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' packaging: '>=20.0' - requests: '>=2.19.0' platformdirs: '>=2.5.0' + python: '>=3.7' + requests: '>=2.19.0' url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: md5: 8dab97d8a9616e07d779782995710aed @@ -17908,8 +18017,8 @@ package: manager: conda platform: osx-arm64 dependencies: - wcwidth: '' python: '>=3.7' + wcwidth: '' url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: md5: 1247c861065d227781231950e14fe817 @@ -17978,47 +18087,49 @@ package: category: main optional: false - name: psutil - version: 5.9.8 + version: 6.0.0 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.8-py38h01eb140_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/psutil-6.0.0-py38hfb59056_0.conda hash: - md5: 571da172be3f0f94f49c069e5b775f05 - sha256: 948984a69b32625c32c8c0abe724fa4219d8a03baf1c3269a0db4fc1c14aebe3 + md5: 14d8661ec0011b79081f8429c716f46f + sha256: d6d5f1ac1dc3bbddb50c093f89a425edae695754ad1ab1bc78bf720be11315ea category: main optional: false - name: psutil - version: 5.9.8 + version: 6.0.0 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/psutil-5.9.8-py38hae2e43d_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/psutil-6.0.0-py38hc718529_0.conda hash: - md5: 472f759cff3581370fac5d574c559d0a - sha256: d946b6d24f33047f50ade6187fd84bde4c989b235c941225d02e62fb279c86ba + md5: fc486245b64b4e03c5968915c277aabf + sha256: b6006e8d25ae4c8d43ca07f5ff15b2ca51bfceb92168b8f73e376d30078bb944 category: main optional: false - name: psutil - version: 5.9.8 + version: 6.0.0 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-5.9.8-py38h336bac9_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-6.0.0-py38h3237794_0.conda hash: - md5: 40175a55b8436b2bd216e94bfa168fdd - sha256: 245ddf59d580348d6f95a00e803d4eed7b53543e162f7d1172d30a74c439d021 + md5: f14d02d525fd9f62172c717979e2d849 + sha256: 76e30573405195dbcedff472f7706e09765b2d49112209e7f81dfb8436e73235 category: main optional: false - name: psutil - version: 5.9.8 + version: 6.0.0 manager: conda platform: win-64 dependencies: @@ -18027,10 +18138,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/psutil-5.9.8-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/psutil-6.0.0-py38h4cb3324_0.conda hash: - md5: 0f9a1745d5a5857ec90414ce0d2d4c43 - sha256: 36a973f5bd8f08623bdf9b190e7f6ee27e0caa6c3330ae04024e2efe90fe3abd + md5: 00cc8acaf6d7eec51d009a0662a0cc03 + sha256: b624f4be2d0e7b956835ea8822cb9502c861819e5402fe5d02f27d8b4289e392 category: main optional: false - name: pthread-stubs @@ -18282,7 +18393,7 @@ package: category: main optional: false - name: pvlib - version: 0.10.5 + version: 0.11.0 manager: conda platform: linux-64 dependencies: @@ -18298,14 +18409,14 @@ package: requests: '' scipy: '>=1.6.0' statsmodels: '' - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.10.5-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.11.0-pyha770c72_0.conda hash: - md5: 0fb62e25e1d608ff1878bfd06a2de8e0 - sha256: 78a6b89b4bc6c6eafa675fd647b2e36796262979b693caa972f4bcff52ce6d84 + md5: c9f4459108b58bd349251f93ebd561cb + sha256: 71e35104c1e0f4b25df2b3b1d625f0af1e7efd0955030f62ff926b40fe63715f category: main optional: false - name: pvlib - version: 0.10.5 + version: 0.11.0 manager: conda platform: osx-64 dependencies: @@ -18321,37 +18432,37 @@ package: scipy: '>=1.6.0' pandas: '>=1.3.0' numba: '>=0.17.0' - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.10.5-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.11.0-pyha770c72_0.conda hash: - md5: 0fb62e25e1d608ff1878bfd06a2de8e0 - sha256: 78a6b89b4bc6c6eafa675fd647b2e36796262979b693caa972f4bcff52ce6d84 + md5: c9f4459108b58bd349251f93ebd561cb + sha256: 71e35104c1e0f4b25df2b3b1d625f0af1e7efd0955030f62ff926b40fe63715f category: main optional: false - name: pvlib - version: 0.10.5 + version: 0.11.0 manager: conda platform: osx-arm64 dependencies: - requests: '' + ephem: '' h5py: '' - pytz: '' importlib-metadata: '' + numba: '>=0.17.0' + numpy: '>=1.17.3' + pandas: '>=1.3.0' pip: '' - statsmodels: '' - ephem: '' python: '>=3.8' - numpy: '>=1.17.3' + pytz: '' + requests: '' scipy: '>=1.6.0' - pandas: '>=1.3.0' - numba: '>=0.17.0' - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.10.5-pyha770c72_0.conda + statsmodels: '' + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.11.0-pyha770c72_0.conda hash: - md5: 0fb62e25e1d608ff1878bfd06a2de8e0 - sha256: 78a6b89b4bc6c6eafa675fd647b2e36796262979b693caa972f4bcff52ce6d84 + md5: c9f4459108b58bd349251f93ebd561cb + sha256: 71e35104c1e0f4b25df2b3b1d625f0af1e7efd0955030f62ff926b40fe63715f category: main optional: false - name: pvlib - version: 0.10.5 + version: 0.11.0 manager: conda platform: win-64 dependencies: @@ -18367,58 +18478,58 @@ package: scipy: '>=1.6.0' pandas: '>=1.3.0' numba: '>=0.17.0' - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.10.5-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.11.0-pyha770c72_0.conda hash: - md5: 0fb62e25e1d608ff1878bfd06a2de8e0 - sha256: 78a6b89b4bc6c6eafa675fd647b2e36796262979b693caa972f4bcff52ce6d84 + md5: c9f4459108b58bd349251f93ebd561cb + sha256: 71e35104c1e0f4b25df2b3b1d625f0af1e7efd0955030f62ff926b40fe63715f category: main optional: false - name: pvlib-python - version: 0.10.5 + version: 0.11.0 manager: conda platform: linux-64 dependencies: - pvlib: 0.10.5 - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.10.5-hd8ed1ab_0.conda + pvlib: 0.11.0 + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.11.0-hd8ed1ab_0.conda hash: - md5: 652835bc1069344644ff157ce1aadf1b - sha256: 99a37abd5120c07ad319b46ef0699f7dc5dca2cd3f352301c2ffed1b1454887b + md5: 7f548535e783e8bd63233f5ec97364ee + sha256: 3a0321cd252eb91c712cc2aa72140b983cc8a9633e6f7041afa0834a757d0aa6 category: main optional: false - name: pvlib-python - version: 0.10.5 + version: 0.11.0 manager: conda platform: osx-64 dependencies: - pvlib: 0.10.5 - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.10.5-hd8ed1ab_0.conda + pvlib: 0.11.0 + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.11.0-hd8ed1ab_0.conda hash: - md5: 652835bc1069344644ff157ce1aadf1b - sha256: 99a37abd5120c07ad319b46ef0699f7dc5dca2cd3f352301c2ffed1b1454887b + md5: 7f548535e783e8bd63233f5ec97364ee + sha256: 3a0321cd252eb91c712cc2aa72140b983cc8a9633e6f7041afa0834a757d0aa6 category: main optional: false - name: pvlib-python - version: 0.10.5 + version: 0.11.0 manager: conda platform: osx-arm64 dependencies: - pvlib: 0.10.5 - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.10.5-hd8ed1ab_0.conda + pvlib: 0.11.0 + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.11.0-hd8ed1ab_0.conda hash: - md5: 652835bc1069344644ff157ce1aadf1b - sha256: 99a37abd5120c07ad319b46ef0699f7dc5dca2cd3f352301c2ffed1b1454887b + md5: 7f548535e783e8bd63233f5ec97364ee + sha256: 3a0321cd252eb91c712cc2aa72140b983cc8a9633e6f7041afa0834a757d0aa6 category: main optional: false - name: pvlib-python - version: 0.10.5 + version: 0.11.0 manager: conda platform: win-64 dependencies: - pvlib: 0.10.5 - url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.10.5-hd8ed1ab_0.conda + pvlib: 0.11.0 + url: https://conda.anaconda.org/conda-forge/noarch/pvlib-python-0.11.0-hd8ed1ab_0.conda hash: - md5: 652835bc1069344644ff157ce1aadf1b - sha256: 99a37abd5120c07ad319b46ef0699f7dc5dca2cd3f352301c2ffed1b1454887b + md5: 7f548535e783e8bd63233f5ec97364ee + sha256: 3a0321cd252eb91c712cc2aa72140b983cc8a9633e6f7041afa0834a757d0aa6 category: main optional: false - name: pyarrow @@ -18571,10 +18682,10 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' - typing-extensions: '>=4.6.1' annotated-types: '>=0.4.0' pydantic-core: 2.18.4 + python: '>=3.7' + typing-extensions: '>=4.6.1' url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda hash: md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 @@ -19113,6 +19224,54 @@ package: sha256: f3ceef02ac164a8d3a080d0d32f8e2ebe10dd29e3a685d240e38b3599e146320 category: main optional: false +- name: python-dotenv + version: 1.0.1 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: c2997ea9360ac4e015658804a7a84f94 + sha256: 2d4c80364f03315d606a50eddd493dbacc078e21412c2462c0f781eec49b572c + category: main + optional: false +- name: python-dotenv + version: 1.0.1 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: c2997ea9360ac4e015658804a7a84f94 + sha256: 2d4c80364f03315d606a50eddd493dbacc078e21412c2462c0f781eec49b572c + category: main + optional: false +- name: python-dotenv + version: 1.0.1 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: c2997ea9360ac4e015658804a7a84f94 + sha256: 2d4c80364f03315d606a50eddd493dbacc078e21412c2462c0f781eec49b572c + category: main + optional: false +- name: python-dotenv + version: 1.0.1 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda + hash: + md5: c2997ea9360ac4e015658804a7a84f94 + sha256: 2d4c80364f03315d606a50eddd493dbacc078e21412c2462c0f781eec49b572c + category: main + optional: false - name: python-engineio version: 4.9.1 manager: conda @@ -19342,8 +19501,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' bidict: '>=0.21.0' + python: '>=3.8' python-engineio: '>=4.8.0' url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: @@ -20164,8 +20323,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' attrs: '>=22.2.0' + python: '>=3.8' rpds-py: '>=0.7.0' url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda hash: @@ -20224,10 +20383,10 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' - idna: '>=2.5,<4' certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' + idna: '>=2.5,<4' + python: '>=3.8' urllib3: '>=1.21.1,<3' url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: @@ -20282,8 +20441,8 @@ package: manager: conda platform: osx-arm64 dependencies: - six: '' python: '>=3.5' + six: '' url: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 hash: md5: fed45fc5ea0813240707998abe49f520 @@ -20386,10 +20545,10 @@ package: manager: conda platform: osx-arm64 dependencies: + markdown-it-py: '>=2.2.0' + pygments: '>=2.13.0,<3.0.0' python: '>=3.7.0' typing_extensions: '>=4.0.0,<5.0.0' - pygments: '>=2.13.0,<3.0.0' - markdown-it-py: '>=2.2.0' url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda hash: md5: ba445bf767ae6f0d959ff2b40c20912b @@ -20581,11 +20740,11 @@ package: dependencies: matplotlib-base: '' multiprocess: '' - python: '>=3.8' - scipy: '>=1.7.3' numpy: '>=1.20.3' pandas: '>=1.1.2' pathos: '>=0.2.5' + python: '>=3.8' + scipy: '>=1.7.3' url: https://conda.anaconda.org/conda-forge/noarch/salib-1.5.0-pyhd8ed1ab_0.conda hash: md5: 86437b51c934e7314e4e69f5c0b75332 @@ -21021,8 +21180,8 @@ package: manager: conda platform: osx-arm64 dependencies: - wsproto: '' python: '>=3.7' + wsproto: '' url: https://conda.anaconda.org/conda-forge/noarch/simple-websocket-1.0.0-pyhd8ed1ab_1.conda hash: md5: 4e9136be6c66312f63b3a8ef60443389 @@ -21259,9 +21418,9 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '' numpy: '' pyparsing: '>=2.1.6' + python: '' url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 hash: md5: cb83a3d6ecf73f50117635192414426a @@ -21486,9 +21645,9 @@ package: manager: conda platform: osx-arm64 dependencies: + anyio: <5,>=3.4.0 python: '>=3.8' typing_extensions: '>=3.10.0' - anyio: <5,>=3.4.0 url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda hash: md5: 7e5550dfa3ed2c2019988cbb9f8302ea @@ -21673,8 +21832,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.6' pyparsing: '>=2.0.1' + python: '>=3.6' url: https://conda.anaconda.org/conda-forge/noarch/svgwrite-1.4.3-pyhd8ed1ab_0.tar.bz2 hash: md5: 9d1eb6e4bf36cf72e0662ed9246f4e1b @@ -22524,8 +22683,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' click: '>=8.0.0' + python: '>=3.7' typing_extensions: '>=3.7.4.3' url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: @@ -23140,9 +23299,9 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda hash: md5: 92cdb6fe54b78739ad70637e4f0deb07 @@ -23319,6 +23478,125 @@ package: sha256: 5d51c3f48481aed643d592b2b15410344fbbe2e56ffe1d775330d2c61efe4869 category: main optional: false +- name: uvicorn-standard + version: 0.30.1 + manager: conda + platform: linux-64 + dependencies: + httptools: '>=0.5.0' + python-dotenv: '>=0.13' + python_abi: 3.8.* + pyyaml: '>=5.1' + uvicorn: 0.30.1 + uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' + watchfiles: '>=0.13' + websockets: '>=10.4' + url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-standard-0.30.1-h578d9bd_0.conda + hash: + md5: 878844f126b5cbe2708dfd70eb5242b1 + sha256: f56977cabd8966db28ab84cd38434b57ebd34d591dd06dd78a9ec402de28c02a + category: main + optional: false +- name: uvicorn-standard + version: 0.30.1 + manager: conda + platform: osx-64 + dependencies: + httptools: '>=0.5.0' + python-dotenv: '>=0.13' + python_abi: 3.8.* + pyyaml: '>=5.1' + uvicorn: 0.30.1 + uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' + watchfiles: '>=0.13' + websockets: '>=10.4' + url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-standard-0.30.1-h50d1736_0.conda + hash: + md5: 62f8229b71c9f2ffceb32c23fd7547b5 + sha256: a06b8a1aa5962e39bf7753178ce330b8da41b04dc9943097498f032d37022e29 + category: main + optional: false +- name: uvicorn-standard + version: 0.30.1 + manager: conda + platform: osx-arm64 + dependencies: + httptools: '>=0.5.0' + python-dotenv: '>=0.13' + python_abi: 3.8.* + pyyaml: '>=5.1' + uvicorn: 0.30.1 + uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' + watchfiles: '>=0.13' + websockets: '>=10.4' + url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-standard-0.30.1-h150bfb4_0.conda + hash: + md5: 04998e379e5bb56396f2e28562431721 + sha256: 3e4ef8b2ba839dfa7f26a84893bdc0e16f27b2ac6dc9135cdbc18fab39b2c184 + category: main + optional: false +- name: uvicorn-standard + version: 0.30.1 + manager: conda + platform: win-64 + dependencies: + colorama: '>=0.4' + httptools: '>=0.5.0' + python-dotenv: '>=0.13' + python_abi: 3.8.* + pyyaml: '>=5.1' + uvicorn: 0.30.1 + watchfiles: '>=0.13' + websockets: '>=10.4' + url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-standard-0.30.1-haa244fe_0.conda + hash: + md5: ec7d831fa142c356abd6c8c9b6a2271c + sha256: 148498e9c6d06cab2231f90b7fd699c622dba9a3814915148e99d0cea91c917a + category: main + optional: false +- name: uvloop + version: 0.17.0 + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + libuv: '>=1.44.2,<2.0a0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/uvloop-0.17.0-py38h0a891b7_1.tar.bz2 + hash: + md5: 67e8c6a38a870622224dd41920c13169 + sha256: 497bb91a3a9b7d5a8d5f0304c3161aa34925f77b3cd59f5291f7afb48833a2e1 + category: main + optional: false +- name: uvloop + version: 0.17.0 + manager: conda + platform: osx-64 + dependencies: + libuv: '>=1.44.2,<2.0a0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/uvloop-0.17.0-py38hef030d1_1.tar.bz2 + hash: + md5: 0b71efe4708107de855335a7443335d7 + sha256: d21438c5b39cd252a6dad831ceb69e82c5368987dc4ebd6cb27ad1c63472e5fd + category: main + optional: false +- name: uvloop + version: 0.17.0 + manager: conda + platform: osx-arm64 + dependencies: + libuv: '>=1.44.2,<2.0a0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/uvloop-0.17.0-py38hb991d35_1.tar.bz2 + hash: + md5: d8f0164124989f4597c9ade1bfecfe39 + sha256: f50434e755e853e9cf6bcf3244c4861dd8d2365f77b4ea819ca6735c23bc53f9 + category: main + optional: false - name: vc version: '14.3' manager: conda @@ -23542,6 +23820,68 @@ package: sha256: c5d0a1918b95379e4082661a91bf21f00a33670a0e09b77f2b4c83e80f888bdb category: main optional: false +- name: watchfiles + version: 0.22.0 + manager: conda + platform: linux-64 + dependencies: + anyio: '>=3.0.0' + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-0.22.0-py38h31a4407_0.conda + hash: + md5: a0d8804ab4ab98e53675145913e7556a + sha256: e29a47a84379e0e3bfeea8e9551f0bea693b75c261615d130954e414485372a8 + category: main + optional: false +- name: watchfiles + version: 0.22.0 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + anyio: '>=3.0.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-0.22.0-py38h2c15f49_0.conda + hash: + md5: ef538bcab09347480bf5aa7f9db3ab7d + sha256: 8713a1961cc63998f813e187672f3f01091a42c0f875e0492adcec21e4f3e8a5 + category: main + optional: false +- name: watchfiles + version: 0.22.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + anyio: '>=3.0.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/watchfiles-0.22.0-py38h186058e_0.conda + hash: + md5: 1e3e6cce6e9f3733fb278a80b7db1045 + sha256: a61266606f5b483f667adebe29a4f69ab7051a977d6d1cf14bd6d9ee73ab14b2 + category: main + optional: false +- name: watchfiles + version: 0.22.0 + manager: conda + platform: win-64 + dependencies: + anyio: '>=3.0.0' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/watchfiles-0.22.0-py38h2e0ef18_0.conda + hash: + md5: a0138158474a4f73a6bd050039b70d99 + sha256: 85300ac98ba5e82efbbf145bfd3b4c7edea1dc85066f5df0ca640f7c730191c5 + category: main + optional: false - name: wcwidth version: 0.2.13 manager: conda @@ -23734,6 +24074,62 @@ package: sha256: 44a5e3b97feef24cd719f7851cca9af9799dc9c17d3e0298d5856baab2d682f5 category: main optional: false +- name: websockets + version: '12.0' + manager: conda + platform: linux-64 + dependencies: + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/linux-64/websockets-12.0-py38h01eb140_0.conda + hash: + md5: 3eacfa3018ac9da7d0514488167dc528 + sha256: 3fafe0ae82859848ae84d9114d962f3aecb73d3b0d23a1b08664812119d32b02 + category: main + optional: false +- name: websockets + version: '12.0' + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-64/websockets-12.0-py38hae2e43d_0.conda + hash: + md5: 5d3d91e21f85fe78ca7c9ffa04c58cb3 + sha256: 2685c43dcdb424049454034cb70fa800adb1b34b560c5c70be3c99bebf7d245b + category: main + optional: false +- name: websockets + version: '12.0' + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + url: https://conda.anaconda.org/conda-forge/osx-arm64/websockets-12.0-py38h336bac9_0.conda + hash: + md5: 1bef657e4e41c91053b81dcc533fd925 + sha256: 707763ad83653e2c81255096e94fd1f63929a75a3b604f977e9dce412b3bc740 + category: main + optional: false +- name: websockets + version: '12.0' + manager: conda + platform: win-64 + dependencies: + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/websockets-12.0-py38h91455d4_0.conda + hash: + md5: 0913c6bcdc2a8e5d3a83bcdcba03f566 + sha256: 187cd74d559c7aaeafd67a6883082f286b8b778300b7f109c6c4318a33a7fc3c + category: main + optional: false - name: wheel version: 0.43.0 manager: conda @@ -23819,59 +24215,59 @@ package: category: main optional: false - name: wslink - version: 2.1.0 + version: 2.1.1 manager: conda platform: linux-64 dependencies: aiohttp: <4 msgpack-python: '>=1,<2' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda hash: - md5: 088c224d81a1828e283186e14a4db25f - sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c + md5: 6b1aef9c878c58baa7bb9f0d44457174 + sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 category: main optional: false - name: wslink - version: 2.1.0 + version: 2.1.1 manager: conda platform: osx-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda hash: - md5: 088c224d81a1828e283186e14a4db25f - sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c + md5: 6b1aef9c878c58baa7bb9f0d44457174 + sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 category: main optional: false - name: wslink - version: 2.1.0 + version: 2.1.1 manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda + python: '>=3.7' + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda hash: - md5: 088c224d81a1828e283186e14a4db25f - sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c + md5: 6b1aef9c878c58baa7bb9f0d44457174 + sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 category: main optional: false - name: wslink - version: 2.1.0 + version: 2.1.1 manager: conda platform: win-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda hash: - md5: 088c224d81a1828e283186e14a4db25f - sha256: e5edbda78cb21b696ce7f9f3cb2f4c0dbaf1bd90a715cedf12f5e879754eae8c + md5: 6b1aef9c878c58baa7bb9f0d44457174 + sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 category: main optional: false - name: wsproto @@ -23905,8 +24301,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' h11: '>=0.9.0,<1.0' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/wsproto-1.2.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 00ba804b54f451d102f6a7615f08470d @@ -24717,55 +25113,55 @@ package: category: main optional: false - name: yarn - version: 4.3.0 + version: 4.3.1 manager: conda platform: linux-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda hash: - md5: fb40f36d553305b76fceb28584a2fa4f - sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 + md5: 7d0a2d56af92fab67f350d469ebda9cc + sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 category: main optional: false - name: yarn - version: 4.3.0 + version: 4.3.1 manager: conda platform: osx-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda hash: - md5: fb40f36d553305b76fceb28584a2fa4f - sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 + md5: 7d0a2d56af92fab67f350d469ebda9cc + sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 category: main optional: false - name: yarn - version: 4.3.0 + version: 4.3.1 manager: conda platform: osx-arm64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda hash: - md5: fb40f36d553305b76fceb28584a2fa4f - sha256: 330754436ae312334f33a47fbdeab39f9ad3f5b9daf610dd2184f662b3bae0e5 + md5: 7d0a2d56af92fab67f350d469ebda9cc + sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 category: main optional: false - name: yarn - version: 4.3.0 + version: 4.3.1 manager: conda platform: win-64 dependencies: __win: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.0-h5737063_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h5737063_0.conda hash: - md5: a5242d2fb59ba7c3d8ff370c0e6a4e5e - sha256: e2766ea328126396585eef19fad99670243858724df67f575ca22294f257c999 + md5: fd9fee941d3fa785d2567909057a2a04 + sha256: 8aaa1ce4fd43dce53c21fbb5edadb13dfee6fdfc034dcff8e674b143da09a81c category: main optional: false - name: zeromq diff --git a/environment.yml b/environment.yml index 99702b0b48..2445f2c85b 100644 --- a/environment.yml +++ b/environment.yml @@ -6,8 +6,9 @@ dependencies: - deap - ephem - fiona +- aiocache - fastapi -- uvicorn +- uvicorn-standard - jinja2 - python-socketio - geopandas=0.13 # Due to python3.8 support From 12fa1c06671bc97735de478ada7c230ecd16c25a Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:14:00 +0200 Subject: [PATCH 005/103] Move fastapi app into its own module --- cea/interfaces/dashboard/app.py | 28 ++++++++++++++++++ cea/interfaces/dashboard/dashboard.py | 41 +-------------------------- 2 files changed, 29 insertions(+), 40 deletions(-) create mode 100644 cea/interfaces/dashboard/app.py diff --git a/cea/interfaces/dashboard/app.py b/cea/interfaces/dashboard/app.py new file mode 100644 index 0000000000..e5b0b6e36c --- /dev/null +++ b/cea/interfaces/dashboard/app.py @@ -0,0 +1,28 @@ +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from cea.interfaces.dashboard.server.socketio import socket_app + +import cea.interfaces.dashboard.api as api +import cea.interfaces.dashboard.plots.routes as plots +import cea.interfaces.dashboard.server as server + + +app = FastAPI() + +# Setup CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Mount socketio app +app.mount("/socket.io", socket_app, "socketio") + +# Import other routers +app.include_router(api.router, prefix='/api') +app.include_router(plots.router, prefix='/plots') +app.include_router(server.router, prefix='/server') diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 4df71483dd..99c6f98e40 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -1,50 +1,11 @@ import sys import uvicorn -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -app = FastAPI() - - -def configure_app(config): - global app - - origins = [ - "http://localhost", - "http://localhost:5173", - "http://localhost:5050", - ] - - # Setup CORS - app.add_middleware( - CORSMiddleware, - allow_origins=origins, - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], - ) - - # Mount socketio app - from cea.interfaces.dashboard.server.socketio import socket_app - app.mount("/socket.io", socket_app, "socketio") - - # Import other routers - import cea.interfaces.dashboard.api as api - import cea.interfaces.dashboard.plots.routes as plots - import cea.interfaces.dashboard.server as server - - app.include_router(api.router, prefix='/api') - app.include_router(plots.router, prefix='/plots') - app.include_router(server.router, prefix='/server') - - return app def main(config): - _app = configure_app(config) try: - uvicorn.run(_app, host="127.0.0.1", port=5050) + uvicorn.run("cea.interfaces.dashboard.app:app", host="127.0.0.1", port=5050, workers=3) except KeyboardInterrupt: sys.exit(0) From 8f79253b7dc31227ed0b2e43ee195e3e86157905 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:41:54 +0200 Subject: [PATCH 006/103] Move jobs to cache --- cea/interfaces/dashboard/dependencies.py | 13 +++++++ cea/interfaces/dashboard/server/jobs.py | 43 +++++++++++------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index ad32c4db0b..2efb33a383 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -41,5 +41,18 @@ async def get_plot_cache(): return plot_cache +async def get_jobs(): + _cache = caches.get(CACHE_NAME) + jobs = await _cache.get("jobs") + + if jobs is None: + jobs = dict() + await _cache.set("jobs", jobs) + + print(jobs) + return jobs + + CEAConfig = Annotated[dict, Depends(get_cea_config)] CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] +CEAJobs = Annotated[dict, Depends(get_jobs)] diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index fce693dc66..3412bf1adb 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -9,6 +9,7 @@ from fastapi import APIRouter from pydantic import BaseModel +from cea.interfaces.dashboard.dependencies import CEAJobs from cea.interfaces.dashboard.server.socketio import sio router = APIRouter() @@ -41,17 +42,6 @@ worker_processes = {} # jobid -> subprocess.Popen -def next_id(): - """ - FIXME: replace with better solution - """ - try: - return str(len(jobs.keys()) + 1) - except ValueError: - # this is the first job... - return str(1) - - # FIXME: replace with database or similar solution class JobInfo(BaseModel): """Store all the information required to run a job""" @@ -64,22 +54,29 @@ class JobInfo(BaseModel): end_time: datetime = None -jobs = { - # jobid -> JobInfo -} - @router.get("/{job_id}") -async def get_job_info(job_id: str): +async def get_job_info(jobs: CEAJobs, job_id: str): """Return a JobInfo by id""" return jobs[job_id] @router.post("/new") -async def create_new_job(payload: Dict[str, Any]): +async def create_new_job(jobs: CEAJobs, payload: Dict[str, Any]): """Post a new job to the list of jobs to complete""" args = payload print("NewJob: args={args}".format(**locals())) + + def next_id(): + """ + FIXME: replace with better solution + """ + try: + return str(len(jobs.keys()) + 1) + except ValueError: + # this is the first job... + return str(1) + job = JobInfo(id=next_id(), script=args["script"], parameters=args["parameters"]) jobs[job.id] = job await sio.emit("cea-job-created", job.model_dump(mode='json')) @@ -87,12 +84,12 @@ async def create_new_job(payload: Dict[str, Any]): @router.get("/") -async def get_jobs(): +async def get_jobs(jobs: CEAJobs): return [job.dict() for job in jobs.values()] @router.post("/started/{job_id}") -async def set_job_started(job_id: str) -> JobInfo: +async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: job = jobs[job_id] job.state = JOB_STATE_STARTED job.start_time = datetime.now() @@ -101,7 +98,7 @@ async def set_job_started(job_id: str) -> JobInfo: @router.post("/success/{job_id}") -async def set_job_success(job_id: str) -> JobInfo: +async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: job = jobs[job_id] job.state = JOB_STATE_SUCCESS job.error = None @@ -113,7 +110,7 @@ async def set_job_success(job_id: str) -> JobInfo: @router.post("/error/{job_id}") -async def set_job_error(job_id: str, error: str) -> JobInfo: +async def set_job_error(jobs: CEAJobs, job_id: str, error: str) -> JobInfo: job = jobs[job_id] job.state = JOB_STATE_ERROR job.error = error @@ -125,7 +122,7 @@ async def set_job_error(job_id: str, error: str) -> JobInfo: @router.post('/start/{job_id}') -async def start_job(job_id: str): +async def start_job(jobs: CEAJobs, job_id: str): """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" print("tools/route_start: {job_id}".format(**locals())) worker_processes[job_id] = subprocess.Popen(["python", "-m", "cea.worker", f"{job_id}"]) @@ -133,7 +130,7 @@ async def start_job(job_id: str): @router.post("/cancel/{job_id}") -async def cancel_job(job_id: str) -> JobInfo: +async def cancel_job(jobs: CEAJobs, job_id: str) -> JobInfo: job = jobs[job_id] job.state = JOB_STATE_CANCELED job.error = "Canceled by user" From 792c7d82b40d35651db02f457ce7c369fcbe1456 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:57:22 +0200 Subject: [PATCH 007/103] Move generation of image to thread pool --- cea/interfaces/dashboard/api/project.py | 120 +++++++++++++----------- cea/interfaces/dashboard/dashboard.py | 2 +- cea/interfaces/dashboard/server/jobs.py | 1 - 3 files changed, 67 insertions(+), 56 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 1fa7f85ee3..339482fda4 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -9,6 +9,7 @@ from fastapi import APIRouter, HTTPException, status, Request, Path, Depends from pydantic import BaseModel from shapely.geometry import shape +from fastapi.concurrency import run_in_threadpool from staticmap import StaticMap, Polygon import cea.api @@ -285,10 +286,53 @@ async def delete(config: CEAConfig, scenario: str): ) +class ZoneFileNotFound(ValueError): + """Raised when a zone file is not found.""" + + +def generate_scenario_image(config, scenario: str, image_path: str, building_limit: int = 500): + locator = cea.inputlocator.InputLocator(os.path.join(config.project, scenario)) + zone_path = locator.get_zone_geometry() + + if not os.path.isfile(zone_path): + raise ZoneFileNotFound + + zone_modified = os.path.getmtime(zone_path) + if not os.path.isfile(image_path): + image_modified = 0 + else: + image_modified = os.path.getmtime(image_path) + + if zone_modified > image_modified: + print(f'Generating preview image for scenario: {scenario}') + # Make sure .cache folder exists + os.makedirs(os.path.dirname(image_path), exist_ok=True) + + zone_df = geopandas.read_file(zone_path) + zone_df = zone_df.to_crs(get_geographic_coordinate_system()) + polygons = zone_df['geometry'] + + m = StaticMap(256, 160, url_template='http://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png') + if len(polygons) <= building_limit: + polygons = [list(polygons.geometry.exterior[row_id].coords) for row_id in range(polygons.shape[0])] + for polygon in polygons: + out = Polygon(polygon, color_to_rgb('purple'), 'black', False) + m.add_polygon(out) + else: + print(f'Number of buildings({len(polygons)}) exceed building limit({building_limit}): ' + f'Generating simplified image') + # Generate only the shape outline of the zone area + convex_hull = polygons.unary_union.convex_hull + polygon = convex_hull.exterior.coords + out = Polygon(polygon, None, color_to_rgb('purple'), False) + m.add_polygon(out) + + image = m.render() + image.save(image_path) + + @router.get('/scenario/{scenario}/image') async def get_scenario_image(config: CEAConfig, project: str, scenario: str): - building_limit = 500 - if project is None: config = config else: @@ -301,64 +345,32 @@ async def get_scenario_image(config: CEAConfig, project: str, scenario: str): config.project = project choices = list_scenario_names_for_project(config) - if scenario in choices: - locator = cea.inputlocator.InputLocator(os.path.join(config.project, scenario)) - zone_path = locator.get_zone_geometry() - if os.path.isfile(zone_path): - cache_path = os.path.join(config.project, '.cache') - image_path = os.path.join(cache_path, scenario + '.png') - - zone_modified = os.path.getmtime(zone_path) - if not os.path.isfile(image_path): - image_modified = 0 - else: - image_modified = os.path.getmtime(image_path) - - if zone_modified > image_modified: - print(f'Generating preview image for scenario: {scenario}') - # Make sure .cache folder exists - os.makedirs(cache_path, exist_ok=True) - - try: - zone_df = geopandas.read_file(zone_path) - zone_df = zone_df.to_crs(get_geographic_coordinate_system()) - polygons = zone_df['geometry'] - - m = StaticMap(256, 160, url_template='http://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png') - if len(polygons) <= building_limit: - polygons = [list(polygons.geometry.exterior[row_id].coords) for row_id in - range(polygons.shape[0])] - for polygon in polygons: - out = Polygon(polygon, color_to_rgb('purple'), 'black', False) - m.add_polygon(out) - else: - print(f'Number of buildings({len(polygons)}) exceed building limit({building_limit}): ' - f'Generating simplified image') - # Generate only the shape outline of the zone area - convex_hull = polygons.unary_union.convex_hull - polygon = convex_hull.exterior.coords - out = Polygon(polygon, None, color_to_rgb('purple'), False) - m.add_polygon(out) - - image = m.render() - image.save(image_path) - except Exception as e: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=str(e), - ) - import base64 - with open(image_path, 'rb') as imgFile: - image = base64.b64encode(imgFile.read()) + if scenario not in choices: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Scenario does not exist', + ) - return {'image': image.decode("utf-8")} + cache_path = os.path.join(config.project, '.cache') + image_path = os.path.join(cache_path, scenario + '.png') + try: + await run_in_threadpool(lambda: generate_scenario_image(config, scenario, image_path)) + except ZoneFileNotFound: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail='Zone file not found', ) - else: + except Exception as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail='Scenario does not exist', + detail=str(e), ) + + import base64 + with open(image_path, 'rb') as imgFile: + image = base64.b64encode(imgFile.read()) + + return {'image': image.decode("utf-8")} + + diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 99c6f98e40..f927e7351e 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -5,7 +5,7 @@ def main(config): try: - uvicorn.run("cea.interfaces.dashboard.app:app", host="127.0.0.1", port=5050, workers=3) + uvicorn.run("cea.interfaces.dashboard.app:app", host="127.0.0.1", port=5050) except KeyboardInterrupt: sys.exit(0) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 3412bf1adb..980597e9e4 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -54,7 +54,6 @@ class JobInfo(BaseModel): end_time: datetime = None - @router.get("/{job_id}") async def get_job_info(jobs: CEAJobs, job_id: str): """Return a JobInfo by id""" From 691ef7a47129f61da59b8c323a9c93c297078ba8 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:36:31 +0200 Subject: [PATCH 008/103] Move some long running functions to thread pool --- cea/interfaces/dashboard/api/dashboards.py | 15 ++- cea/interfaces/dashboard/api/inputs.py | 150 +++++++++++---------- 2 files changed, 87 insertions(+), 78 deletions(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index 8ce7ac9f49..91ef424419 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -2,6 +2,7 @@ from typing import Dict, Any from fastapi import APIRouter +from fastapi.concurrency import run_in_threadpool import cea.config import cea.plots @@ -71,7 +72,7 @@ async def get_dashboards(config: CEAConfig, plot_cache: CEAPlotCache): """ Get list of Dashboards """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) out = [] for d in dashboards: @@ -122,7 +123,7 @@ async def get_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_i """ Get Dashboard """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) return dashboard_to_dict(dashboards[dashboard_index]) @@ -143,7 +144,7 @@ async def update_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboar Update Dashboard properties """ form = payload - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) dashboard = dashboards[dashboard_index] dashboard.set_scenario(form['scenario']) @@ -157,7 +158,7 @@ async def get_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: """ Get Dashboard Plot """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] @@ -202,7 +203,7 @@ async def delete_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_in """ Delete Plot from Dashboard """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) dashboard = dashboards[dashboard_index] dashboard.remove_plot(plot_index) @@ -217,7 +218,7 @@ async def get_plot_parameters(config: CEAConfig, plot_cache: CEAPlotCache, """ Get Plot Form Parameters of Plot in Dashboard """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) dashboard = dashboards[dashboard_index] plot = dashboard.plots[plot_index] @@ -230,7 +231,7 @@ async def get_plot_input_files(config: CEAConfig, plot_cache: CEAPlotCache, dash """ Get input files of Plot """ - dashboards = cea.plots.read_dashboards(config, plot_cache) + dashboards = await run_in_threadpool(lambda: cea.plots.read_dashboards(config, plot_cache)) dashboard = dashboards[dashboard_index] plot = dashboard.plots[plot_index] diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index b6d830196d..40498fcac8 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -9,6 +9,7 @@ from fastapi import APIRouter, HTTPException, status from fiona.errors import DriverError from pydantic import BaseModel +from fastapi.concurrency import run_in_threadpool import cea.inputlocator import cea.schemas @@ -122,21 +123,24 @@ async def get_all_inputs(config: CEAConfig): locator = cea.inputlocator.InputLocator(config.scenario) # FIXME: Find a better way, current used to test for Input Editor - store = get_building_properties(config) - store['geojsons'] = {} - store['connected_buildings'] = {} - store['crs'] = {} - store['geojsons']['zone'], store['crs']['zone'] = df_to_json(locator.get_zone_geometry()) - store['geojsons']['surroundings'], store['crs']['surroundings'] = df_to_json( - locator.get_surroundings_geometry()) - store['geojsons']['trees'], store['crs']['trees'] = df_to_json(locator.get_tree_geometry()) - store['geojsons']['streets'], store['crs']['streets'] = df_to_json(locator.get_street_network()) - store['geojsons']['dc'], store['connected_buildings']['dc'], store['crs']['dc'] = get_network(config, 'dc') - store['geojsons']['dh'], store['connected_buildings']['dh'], store['crs']['dh'] = get_network(config, 'dh') - store['colors'] = COLORS - store['schedules'] = {} - - return store + def fn(): + store = get_building_properties(config) + store['geojsons'] = {} + store['connected_buildings'] = {} + store['crs'] = {} + store['geojsons']['zone'], store['crs']['zone'] = df_to_json(locator.get_zone_geometry()) + store['geojsons']['surroundings'], store['crs']['surroundings'] = df_to_json( + locator.get_surroundings_geometry()) + store['geojsons']['trees'], store['crs']['trees'] = df_to_json(locator.get_tree_geometry()) + store['geojsons']['streets'], store['crs']['streets'] = df_to_json(locator.get_street_network()) + store['geojsons']['dc'], store['connected_buildings']['dc'], store['crs']['dc'] = get_network(config, 'dc') + store['geojsons']['dh'], store['connected_buildings']['dh'], store['crs']['dh'] = get_network(config, 'dh') + store['colors'] = COLORS + store['schedules'] = {} + + return store + + return await run_in_threadpool(fn) class InputForm(BaseModel): @@ -155,72 +159,76 @@ async def save_all_inputs(config: CEAConfig, form: InputForm): crs = form.crs schedules = form.schedules - out = {'tables': {}, 'geojsons': {}} + def fn(): + out = {'tables': {}, 'geojsons': {}} - # TODO: Maybe save the files to temp location in case something fails - for db in INPUTS: - db_info = INPUTS[db] - location = getattr(locator, db_info['location'])() - file_type = db_info['file_type'] + # TODO: Maybe save the files to temp location in case something fails + for db in INPUTS: + db_info = INPUTS[db] + location = getattr(locator, db_info['location'])() + file_type = db_info['file_type'] - if tables.get(db) is None: # ignore if table does not exist - continue + if tables.get(db) is None: # ignore if table does not exist + continue - if len(tables[db]): - if file_type == 'shp': - table_df = geopandas.GeoDataFrame.from_features(geojsons[db]['features'], - crs=get_geographic_coordinate_system()) - out['geojsons'][db] = json.loads(table_df.to_json()) - table_df = table_df.to_crs(crs[db]) - table_df.to_file(location, driver='ESRI Shapefile', encoding='ISO-8859-1') + if len(tables[db]): + if file_type == 'shp': + table_df = geopandas.GeoDataFrame.from_features(geojsons[db]['features'], + crs=get_geographic_coordinate_system()) + out['geojsons'][db] = json.loads(table_df.to_json()) + table_df = table_df.to_crs(crs[db]) + table_df.to_file(location, driver='ESRI Shapefile', encoding='ISO-8859-1') + + table_df = pd.DataFrame(table_df.drop(columns='geometry')) + out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) + elif file_type == 'dbf': + table_df = pd.read_json(json.dumps(tables[db]), orient='index') - table_df = pd.DataFrame(table_df.drop(columns='geometry')) - out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) - elif file_type == 'dbf': - table_df = pd.read_json(json.dumps(tables[db]), orient='index') + # Make sure index name is 'Name; + table_df.index.name = 'Name' + table_df = table_df.reset_index() - # Make sure index name is 'Name; - table_df.index.name = 'Name' - table_df = table_df.reset_index() + cea.utilities.dbf.dataframe_to_dbf(table_df, location) + out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) - cea.utilities.dbf.dataframe_to_dbf(table_df, location) - out['tables'][db] = json.loads(table_df.set_index('Name').to_json(orient='index')) + else: # delete file if empty unless it is surroundings (allow for empty surroundings file) + if db == "surroundings": + table_df = geopandas.GeoDataFrame(columns=["Name", "height_ag", "floors_ag"], geometry=[], + crs=get_geographic_coordinate_system()) + table_df.to_file(location) - else: # delete file if empty unless it is surroundings (allow for empty surroundings file) - if db == "surroundings": - table_df = geopandas.GeoDataFrame(columns=["Name", "height_ag", "floors_ag"], geometry=[], - crs=get_geographic_coordinate_system()) - table_df.to_file(location) + out['tables'][db] = [] - out['tables'][db] = [] + elif os.path.isfile(location): + if file_type == 'shp': + import glob + for filepath in glob.glob(os.path.join(locator.get_building_geometry_folder(), '%s.*' % db)): + os.remove(filepath) + elif file_type == 'dbf': + os.remove(location) - elif os.path.isfile(location): if file_type == 'shp': - import glob - for filepath in glob.glob(os.path.join(locator.get_building_geometry_folder(), '%s.*' % db)): - os.remove(filepath) - elif file_type == 'dbf': - os.remove(location) + out['geojsons'][db] = {} + + if schedules: + for building in schedules: + schedule_dict = schedules[building] + schedule_path = locator.get_building_weekly_schedules(building) + schedule_data = schedule_dict['SCHEDULES'] + schedule_complementary_data = {'MONTHLY_MULTIPLIER': schedule_dict['MONTHLY_MULTIPLIER'], + 'METADATA': schedule_dict['METADATA']} + data = pd.DataFrame() + for day in ['WEEKDAY', 'SATURDAY', 'SUNDAY']: + df = pd.DataFrame({'HOUR': range(1, 25), 'DAY': [day] * 24}) + for schedule_type, schedule in schedule_data.items(): + df[schedule_type] = schedule[day] + data = pd.concat([df, data], ignore_index=True) + save_cea_schedule(data.to_dict('list'), schedule_complementary_data, schedule_path) + print('Schedule file written to {}'.format(schedule_path)) - if file_type == 'shp': - out['geojsons'][db] = {} - - if schedules: - for building in schedules: - schedule_dict = schedules[building] - schedule_path = locator.get_building_weekly_schedules(building) - schedule_data = schedule_dict['SCHEDULES'] - schedule_complementary_data = {'MONTHLY_MULTIPLIER': schedule_dict['MONTHLY_MULTIPLIER'], - 'METADATA': schedule_dict['METADATA']} - data = pd.DataFrame() - for day in ['WEEKDAY', 'SATURDAY', 'SUNDAY']: - df = pd.DataFrame({'HOUR': range(1, 25), 'DAY': [day] * 24}) - for schedule_type, schedule in schedule_data.items(): - df[schedule_type] = schedule[day] - data = pd.concat([df, data], ignore_index=True) - save_cea_schedule(data.to_dict('list'), schedule_complementary_data, schedule_path) - print('Schedule file written to {}'.format(schedule_path)) - return out + return out + + return await run_in_threadpool(fn) def get_building_properties(config): @@ -376,7 +384,7 @@ async def get_building_schedule(config: CEAConfig, building: str): async def get_input_database_data(config: CEAConfig): locator = cea.inputlocator.InputLocator(config.scenario) try: - return read_all_databases(locator.get_databases_folder()) + return await run_in_threadpool(lambda: read_all_databases(locator.get_databases_folder())) except IOError as e: print(e) raise HTTPException( From 1cc4cfdbefbba00c80dcaa5492f6419eb5a76e01 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:25:13 +0200 Subject: [PATCH 009/103] Fix scenario not changing --- cea/interfaces/dashboard/api/project.py | 11 +++++------ cea/interfaces/dashboard/dependencies.py | 24 ++++++++++++------------ cea/plots/cache.py | 6 +----- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 339482fda4..e9e333c79c 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -12,9 +12,10 @@ from fastapi.concurrency import run_in_threadpool from staticmap import StaticMap, Polygon +import cea.config import cea.api import cea.inputlocator -from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig, CEAConfigSaveFunc from cea.plots.colors import color_to_rgb from cea.utilities.standardize_coordinates import get_geographic_coordinate_system @@ -96,7 +97,7 @@ async def create_new_project(new_project: NewProject): @router.put('/') -async def update_project(config: CEAConfig, scenario_path: ScenarioPath): +async def update_project(config: CEAConfig, save_func: CEAConfigSaveFunc, scenario_path: ScenarioPath): """ Update Project info in config """ @@ -108,6 +109,7 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): if os.path.exists(project): config.project = project config.scenario_name = scenario_name + await save_func(config) config.save() return {'message': 'Updated project info in config', 'project': project, 'scenario_name': scenario_name} else: @@ -333,15 +335,12 @@ def generate_scenario_image(config, scenario: str, image_path: str, building_lim @router.get('/scenario/{scenario}/image') async def get_scenario_image(config: CEAConfig, project: str, scenario: str): - if project is None: - config = config - else: + if project is not None: if not os.path.exists(project): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f'Project path: "{project}" does not exist', ) - config = config config.project = project choices = list_scenario_names_for_project(config) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index 2efb33a383..cfb4eb218d 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -1,11 +1,10 @@ - from aiocache import caches, Cache from aiocache.serializers import PickleSerializer from fastapi import Depends from typing_extensions import Annotated import cea.config -from cea.plots.cache import MemoryPlotCache +from cea.plots.cache import PlotCache CACHE_NAME = 'default' caches.set_config({ @@ -29,16 +28,18 @@ async def get_cea_config(): return cea_config -async def get_plot_cache(): - _cache = caches.get(CACHE_NAME) - plot_cache = await _cache.get("plot_cache") +async def save_cea_config(): + async def fn(config): + _cache = caches.get(CACHE_NAME) + await _cache.set("cea_config", config) + return fn - if plot_cache is None: - cea_config = await get_cea_config() - plot_cache = MemoryPlotCache(cea_config.project) - await _cache.set("plot_cache", plot_cache) - return plot_cache +async def get_plot_cache(): + cea_config = await get_cea_config() + _plot_cache = PlotCache(cea_config.project) + + return _plot_cache async def get_jobs(): @@ -48,11 +49,10 @@ async def get_jobs(): if jobs is None: jobs = dict() await _cache.set("jobs", jobs) - - print(jobs) return jobs CEAConfig = Annotated[dict, Depends(get_cea_config)] +CEAConfigSaveFunc = Annotated[dict, Depends(save_cea_config)] CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] CEAJobs = Annotated[dict, Depends(get_jobs)] diff --git a/cea/plots/cache.py b/cea/plots/cache.py index f8b99e95d3..998523b303 100644 --- a/cea/plots/cache.py +++ b/cea/plots/cache.py @@ -3,11 +3,6 @@ and dependencies (a list of files that are used to produce that data) as well as the parameters used in that data. The cache object is passed to the `calc_graph` method and the plot is responsible for retrieving data from the cache. """ - - - - - import functools import hashlib import json @@ -16,6 +11,7 @@ import pandas as pd + class PlotCache(object): """A cache for plot data. Use the ``lookup`` method to retrieve data from the cache.""" From f39aac9e61d1115b3b8fc5b215eaaa61c400b9ee Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:37:32 +0200 Subject: [PATCH 010/103] Fix jobs not saving --- cea/interfaces/dashboard/dependencies.py | 39 +++++++++++++++++++++++- cea/interfaces/dashboard/server/jobs.py | 20 ++++++------ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index cfb4eb218d..ae2e24dd0a 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -1,3 +1,5 @@ +import asyncio + from aiocache import caches, Cache from aiocache.serializers import PickleSerializer from fastapi import Depends @@ -17,6 +19,40 @@ }) +class JobStoreCache: + def __init__(self, cache, key): + self._loop = asyncio.get_event_loop() + self._cache = cache + self._key = key + + async def get(self, job_id): + jobs = await self._cache.get(self._key) + + if jobs is None: + jobs = {} + + return jobs[job_id] + + async def set(self, job_id, value): + jobs = await self._cache.get(self._key) + + if jobs is None: + jobs = {} + + jobs[job_id] = value + await self._cache.set(self._key, jobs) + + return value + + async def values(self): + jobs = await self._cache.get(self._key) + return jobs.values() + + async def keys(self): + jobs = await self._cache.get(self._key) + return jobs.keys() + + async def get_cea_config(): _cache = caches.get(CACHE_NAME) cea_config = await _cache.get("cea_config") @@ -49,7 +85,8 @@ async def get_jobs(): if jobs is None: jobs = dict() await _cache.set("jobs", jobs) - return jobs + + return JobStoreCache(_cache, "jobs") CEAConfig = Annotated[dict, Depends(get_cea_config)] diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 980597e9e4..1c7c1e735c 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -57,7 +57,7 @@ class JobInfo(BaseModel): @router.get("/{job_id}") async def get_job_info(jobs: CEAJobs, job_id: str): """Return a JobInfo by id""" - return jobs[job_id] + return await jobs.get(job_id) @router.post("/new") @@ -66,30 +66,30 @@ async def create_new_job(jobs: CEAJobs, payload: Dict[str, Any]): args = payload print("NewJob: args={args}".format(**locals())) - def next_id(): + async def next_id(): """ FIXME: replace with better solution """ try: - return str(len(jobs.keys()) + 1) + return str(len(await jobs.keys()) + 1) except ValueError: # this is the first job... return str(1) - job = JobInfo(id=next_id(), script=args["script"], parameters=args["parameters"]) - jobs[job.id] = job + job = JobInfo(id=await next_id(), script=args["script"], parameters=args["parameters"]) + await jobs.set(job.id, job) await sio.emit("cea-job-created", job.model_dump(mode='json')) return job @router.get("/") async def get_jobs(jobs: CEAJobs): - return [job.dict() for job in jobs.values()] + return [job.dict() for job in await jobs.values()] @router.post("/started/{job_id}") async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: - job = jobs[job_id] + job = await jobs.get(job_id) job.state = JOB_STATE_STARTED job.start_time = datetime.now() await sio.emit("cea-worker-started", job.model_dump(mode='json')) @@ -98,7 +98,7 @@ async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: @router.post("/success/{job_id}") async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: - job = jobs[job_id] + job = await jobs.get(job_id) job.state = JOB_STATE_SUCCESS job.error = None job.end_time = datetime.now() @@ -110,7 +110,7 @@ async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: @router.post("/error/{job_id}") async def set_job_error(jobs: CEAJobs, job_id: str, error: str) -> JobInfo: - job = jobs[job_id] + job = await jobs.get(job_id) job.state = JOB_STATE_ERROR job.error = error job.end_time = datetime.now() @@ -130,7 +130,7 @@ async def start_job(jobs: CEAJobs, job_id: str): @router.post("/cancel/{job_id}") async def cancel_job(jobs: CEAJobs, job_id: str) -> JobInfo: - job = jobs[job_id] + job = await jobs.get(job_id) job.state = JOB_STATE_CANCELED job.error = "Canceled by user" job.end_time = datetime.now() From 8402698c7adfce53707e803043f9af2eaca9522c Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:43:20 +0200 Subject: [PATCH 011/103] Fix config not saving --- cea/interfaces/dashboard/api/project.py | 3 ++- cea/interfaces/dashboard/api/tools.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index e9e333c79c..8fd2b7f7c2 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -252,7 +252,7 @@ async def get(scenario: str): @router.put('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) -async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): +async def put(config: CEAConfig, save_func: CEAConfigSaveFunc, scenario: str, payload: Dict[str, Any]): """Update scenario""" scenario_path = os.path.join(config.project, scenario) new_scenario_name = payload.get('name') @@ -262,6 +262,7 @@ async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): os.rename(scenario_path, new_path) if config.scenario_name == scenario: config.scenario_name = new_scenario_name + await save_func(config) config.save() return {'name': new_scenario_name} except OSError: diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index 19f78bf248..4f641fe26c 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -5,7 +5,7 @@ import cea.config import cea.scripts from .utils import deconstruct_parameters -from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.dependencies import CEAConfig, CEAConfigSaveFunc router = APIRouter() @@ -58,7 +58,7 @@ async def get_tool_properties(config: CEAConfig, tool_name: str): @router.post('/{tool_name}/default') -async def restore_default_config(config: CEAConfig, tool_name: str): +async def restore_default_config(config: CEAConfig, save_func: CEAConfigSaveFunc, tool_name: str): """Restore the default configuration values for the CEA""" default_config = cea.config.Configuration(config_file=cea.config.DEFAULT_CONFIG) @@ -66,6 +66,7 @@ async def restore_default_config(config: CEAConfig, tool_name: str): if parameter.name != 'scenario': parameter.set( default_config.sections[parameter.section.name].parameters[parameter.name].get()) + await save_func(config) config.save() return 'Success' From 6aed216d5cce62551b38774b3f4c4a05fe11b7c0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 01:22:26 +0200 Subject: [PATCH 012/103] Use `CSafeLoader` for yaml --- cea/plots/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cea/plots/__init__.py b/cea/plots/__init__.py index 8ce918b653..6cf1043506 100644 --- a/cea/plots/__init__.py +++ b/cea/plots/__init__.py @@ -36,7 +36,8 @@ def read_dashboards(config, cache): """ try: with open(dashboard_yml_path(config), 'r') as f: - dashboards = [Dashboard(config, dashboard_dict, cache) for dashboard_dict in yaml.safe_load(f)] + dashboards = [Dashboard(config, dashboard_dict, cache) + for dashboard_dict in yaml.load(f, Loader=yaml.CSafeLoader)] if not dashboards: dashboards = [default_dashboard(config, cache)] return dashboards From 172eeba86b8af01f1c3af740a62fd9c11c321873 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 01:33:00 +0200 Subject: [PATCH 013/103] Fix delete dashboard --- cea/interfaces/dashboard/api/dashboards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index 91ef424419..515a979534 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -128,7 +128,7 @@ async def get_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_i return dashboard_to_dict(dashboards[dashboard_index]) -@router.get('/{dashboard_index}') +@router.delete('/{dashboard_index}') async def delete_dashboard(config: CEAConfig, dashboard_index: int): """ Delete Dashboard From d65b4a3590c7f7e8c587047659acf073222c706e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 02:29:58 +0200 Subject: [PATCH 014/103] Fix error body not being parsed properly --- cea/interfaces/dashboard/server/jobs.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 1c7c1e735c..5ccb0c6528 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -6,7 +6,7 @@ from typing import Dict, Any import psutil -from fastapi import APIRouter +from fastapi import APIRouter, Request from pydantic import BaseModel from cea.interfaces.dashboard.dependencies import CEAJobs @@ -109,7 +109,10 @@ async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: @router.post("/error/{job_id}") -async def set_job_error(jobs: CEAJobs, job_id: str, error: str) -> JobInfo: +async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo: + body = await request.body() + error = body.decode("utf-8") + job = await jobs.get(job_id) job.state = JOB_STATE_ERROR job.error = error From 77b3b73c1032d5a4c689d8facf3ea4294bbd5c64 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:44:31 +0200 Subject: [PATCH 015/103] Add "list" route for backward compatibility --- cea/interfaces/dashboard/server/jobs.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 5ccb0c6528..730492a8d3 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -54,6 +54,12 @@ class JobInfo(BaseModel): end_time: datetime = None +@router.get("/") +@router.get("/list") +async def get_jobs(jobs: CEAJobs): + return [job.dict() for job in await jobs.values()] + + @router.get("/{job_id}") async def get_job_info(jobs: CEAJobs, job_id: str): """Return a JobInfo by id""" @@ -82,11 +88,6 @@ async def next_id(): return job -@router.get("/") -async def get_jobs(jobs: CEAJobs): - return [job.dict() for job in await jobs.values()] - - @router.post("/started/{job_id}") async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: job = await jobs.get(job_id) From 26999118f36656e13f760b007d0f9e7e4aac87d6 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:29:50 +0200 Subject: [PATCH 016/103] Override config save function instead --- cea/interfaces/dashboard/api/project.py | 12 +++---- cea/interfaces/dashboard/api/tools.py | 7 ++-- cea/interfaces/dashboard/dependencies.py | 45 +++++++++++++----------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 8fd2b7f7c2..4a964d0a08 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -15,7 +15,7 @@ import cea.config import cea.api import cea.inputlocator -from cea.interfaces.dashboard.dependencies import CEAConfig, CEAConfigSaveFunc +from cea.interfaces.dashboard.dependencies import CEAConfig from cea.plots.colors import color_to_rgb from cea.utilities.standardize_coordinates import get_geographic_coordinate_system @@ -97,7 +97,7 @@ async def create_new_project(new_project: NewProject): @router.put('/') -async def update_project(config: CEAConfig, save_func: CEAConfigSaveFunc, scenario_path: ScenarioPath): +async def update_project(config: CEAConfig, scenario_path: ScenarioPath): """ Update Project info in config """ @@ -109,8 +109,7 @@ async def update_project(config: CEAConfig, save_func: CEAConfigSaveFunc, scenar if os.path.exists(project): config.project = project config.scenario_name = scenario_name - await save_func(config) - config.save() + await config.save() return {'message': 'Updated project info in config', 'project': project, 'scenario_name': scenario_name} else: raise HTTPException( @@ -252,7 +251,7 @@ async def get(scenario: str): @router.put('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) -async def put(config: CEAConfig, save_func: CEAConfigSaveFunc, scenario: str, payload: Dict[str, Any]): +async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): """Update scenario""" scenario_path = os.path.join(config.project, scenario) new_scenario_name = payload.get('name') @@ -262,8 +261,7 @@ async def put(config: CEAConfig, save_func: CEAConfigSaveFunc, scenario: str, pa os.rename(scenario_path, new_path) if config.scenario_name == scenario: config.scenario_name = new_scenario_name - await save_func(config) - config.save() + await config.save() return {'name': new_scenario_name} except OSError: raise HTTPException( diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index 4f641fe26c..c8ef5d9d4b 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -5,7 +5,7 @@ import cea.config import cea.scripts from .utils import deconstruct_parameters -from cea.interfaces.dashboard.dependencies import CEAConfig, CEAConfigSaveFunc +from cea.interfaces.dashboard.dependencies import CEAConfig router = APIRouter() @@ -58,7 +58,7 @@ async def get_tool_properties(config: CEAConfig, tool_name: str): @router.post('/{tool_name}/default') -async def restore_default_config(config: CEAConfig, save_func: CEAConfigSaveFunc, tool_name: str): +async def restore_default_config(config: CEAConfig, tool_name: str): """Restore the default configuration values for the CEA""" default_config = cea.config.Configuration(config_file=cea.config.DEFAULT_CONFIG) @@ -66,8 +66,7 @@ async def restore_default_config(config: CEAConfig, save_func: CEAConfigSaveFunc if parameter.name != 'scenario': parameter.set( default_config.sections[parameter.section.name].parameters[parameter.name].get()) - await save_func(config) - config.save() + await config.save() return 'Success' diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index ae2e24dd0a..d9725aafe5 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -1,11 +1,10 @@ -import asyncio - -from aiocache import caches, Cache +from aiocache import caches, Cache, BaseCache from aiocache.serializers import PickleSerializer from fastapi import Depends from typing_extensions import Annotated import cea.config +from cea.config import CEA_CONFIG from cea.plots.cache import PlotCache CACHE_NAME = 'default' @@ -19,14 +18,28 @@ }) +class CEAConfigCache(cea.config.Configuration): + _cache = caches.get(CACHE_NAME) + _cache_key = "cea_config" + + def __init__(self, config_file: str = CEA_CONFIG): + super().__init__(config_file) + + async def save(self, config_file: str = CEA_CONFIG) -> None: + """ + Write to cache as well when saving to file + """ + await self._cache.set(self._cache_key, self) + super().save(config_file) + + class JobStoreCache: - def __init__(self, cache, key): - self._loop = asyncio.get_event_loop() + def __init__(self, cache: BaseCache, cache_key: str): self._cache = cache - self._key = key + self._cache_key = cache_key async def get(self, job_id): - jobs = await self._cache.get(self._key) + jobs = await self._cache.get(self._cache_key) if jobs is None: jobs = {} @@ -34,22 +47,22 @@ async def get(self, job_id): return jobs[job_id] async def set(self, job_id, value): - jobs = await self._cache.get(self._key) + jobs = await self._cache.get(self._cache_key) if jobs is None: jobs = {} jobs[job_id] = value - await self._cache.set(self._key, jobs) + await self._cache.set(self._cache_key, jobs) return value async def values(self): - jobs = await self._cache.get(self._key) + jobs = await self._cache.get(self._cache_key) return jobs.values() async def keys(self): - jobs = await self._cache.get(self._key) + jobs = await self._cache.get(self._cache_key) return jobs.keys() @@ -58,19 +71,12 @@ async def get_cea_config(): cea_config = await _cache.get("cea_config") if cea_config is None: - cea_config = cea.config.Configuration() + cea_config = CEAConfigCache() await _cache.set("cea_config", cea_config) return cea_config -async def save_cea_config(): - async def fn(config): - _cache = caches.get(CACHE_NAME) - await _cache.set("cea_config", config) - return fn - - async def get_plot_cache(): cea_config = await get_cea_config() _plot_cache = PlotCache(cea_config.project) @@ -90,6 +96,5 @@ async def get_jobs(): CEAConfig = Annotated[dict, Depends(get_cea_config)] -CEAConfigSaveFunc = Annotated[dict, Depends(save_cea_config)] CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] CEAJobs = Annotated[dict, Depends(get_jobs)] From d907ed9628f1c82630e2342104b161e43f1e44e2 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:05:07 +0200 Subject: [PATCH 017/103] Remove OrderedDict --- cea/interfaces/dashboard/api/databases.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/cea/interfaces/dashboard/api/databases.py b/cea/interfaces/dashboard/api/databases.py index 8ee2a168b4..c2b3c589d5 100644 --- a/cea/interfaces/dashboard/api/databases.py +++ b/cea/interfaces/dashboard/api/databases.py @@ -1,5 +1,4 @@ import os -from collections import OrderedDict import pandas as pd from fastapi import APIRouter, HTTPException, status @@ -22,34 +21,33 @@ } -# FIXME: Using OrderedDict here due to Python2 unordered dict insertion, change when using Python3 def database_to_dict(db_path): - out = OrderedDict() + out = dict() xls = pd.ExcelFile(db_path) for sheet in xls.sheet_names: df = xls.parse(sheet, keep_default_na=False) - out[sheet] = df.to_dict(orient='records', into=OrderedDict) + out[sheet] = df.to_dict(orient='records') return out def schedule_to_dict(schedule_path): - out = OrderedDict() + out = dict() schedule_df = schedule_to_dataframe(schedule_path) for df_name, df in schedule_df.items(): - out[df_name] = df.to_dict(orient='records', into=OrderedDict) + out[df_name] = df.to_dict(orient='records') return out def read_all_databases(database_path): - out = OrderedDict() + out = dict() db_info = get_database_tree(database_path) for category in db_info['categories'].keys(): - out[category] = OrderedDict() + out[category] = dict() for db_name in db_info['categories'][category]['databases']: db_files = db_info['databases'][db_name]['files'] if db_name == 'USE_TYPES': - out[category][db_name] = OrderedDict() - out[category][db_name]['SCHEDULES'] = OrderedDict() + out[category][db_name] = dict() + out[category][db_name]['SCHEDULES'] = dict() for db_file in db_files: # Use type property file if db_file['name'] == 'USE_TYPE_PROPERTIES': From b7a5a46769643de38c245e003dffe7663d8ca365 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:16:21 +0200 Subject: [PATCH 018/103] Remove commented models --- cea/interfaces/dashboard/api/project.py | 18 -------- cea/interfaces/dashboard/api/tools.py | 59 ++++++++++++++----------- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 4a964d0a08..e8968edd73 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -24,24 +24,6 @@ # PATH_REGEX = r'(^[a-zA-Z]:\\[\\\S|*\S]?.*$)|(^(/[^/ ]*)+/?$)' -# PROJECT_PATH_MODEL = api.model('Project Path', { -# 'project': fields.String(description='Path of Project'), -# }) -# -# SCENARIO_PATH_MODEL = api.inherit('Scenario Path', PROJECT_PATH_MODEL, { -# 'scenario_name': fields.String(description='Name of Scenario') -# }) -# -# PROJECT_MODEL = api.inherit('Project', SCENARIO_PATH_MODEL, { -# 'project_name': fields.String(description='Name of Project'), -# 'scenarios_list': fields.List(fields.String, description='List of Scenarios found in Project') -# }) -# -# NEW_PROJECT_MODEL = api.model('New Project', { -# 'project_name': fields.String(description='Name of Project'), -# 'project_root': fields.String(description='Root path of Project') -# }) - class ScenarioPath(BaseModel): project: str scenario_name: str diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index c8ef5d9d4b..ebb68d1ba1 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -1,6 +1,9 @@ -from typing import Dict, Any +from collections import defaultdict +from itertools import groupby +from typing import Dict, Any, List from fastapi import APIRouter +from pydantic import BaseModel import cea.config import cea.scripts @@ -10,49 +13,51 @@ router = APIRouter() -# TOOL_DESCRIPTION_MODEL = api.model('Tool', { -# 'label': fields.String(description='Name of tool'), -# 'description': fields.String(description='Description of tool') -# }) -# -# TOOL_LIST = api.model('ToolList', {'tools': fields.List}) +class ToolDescription(BaseModel): + name: str + label: str + description: str -@router.get('/') -async def get_tool_list(config: CEAConfig): - from itertools import groupby +class ToolProperties(ToolDescription): + category: str + categorical_parameters: Dict[str, List[Dict]] + parameters: List[Dict] + +@router.get('/') +async def get_tool_list(config: CEAConfig) -> Dict[str, List[ToolDescription]]: tools = cea.scripts.for_interface('dashboard', plugins=config.plugins) result = dict() for category, group in groupby(tools, lambda t: t.category): result[category] = [ - {'name': t.name, 'label': t.label, 'description': t.description} for t in group] - + ToolDescription(name=t.name, label=t.label, description=t.description) for t in group + ] return result @router.get('/{tool_name}') -async def get_tool_properties(config: CEAConfig, tool_name: str): +async def get_tool_properties(config: CEAConfig, tool_name: str) -> ToolProperties: script = cea.scripts.by_name(tool_name, plugins=config.plugins) parameters = [] - categories = {} + categories = defaultdict(list) for _, parameter in config.matching_parameters(script.parameters): + parameter_dict = deconstruct_parameters(parameter, config) + if parameter.category: - if parameter.category not in categories: - categories[parameter.category] = [] - categories[parameter.category].append( - deconstruct_parameters(parameter, config)) + categories[parameter.category].append(parameter_dict) else: - parameters.append(deconstruct_parameters(parameter, config)) - - out = { - 'category': script.category, - 'label': script.label, - 'description': script.description, - 'parameters': parameters, - 'categorical_parameters': categories, - } + parameters.append(parameter_dict) + + out = ToolProperties( + name=tool_name, + label=script.label, + description=script.description, + category=script.category, + categorical_parameters=categories, + parameters=parameters, + ) return out From fec96bd0e11e92e8fa0fe80d269e2c97580163b3 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:16:42 +0200 Subject: [PATCH 019/103] Remove wrong input files --- cea/scripts.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index 5c2d9cc003..f7a9c02098 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -102,10 +102,8 @@ Demand forecasting: 'general:debug', schedule-maker] input-files: - - [get_database_envelope_systems] - [get_building_architecture] - [get_zone_geometry] - - [get_terrain] - [get_weather_file] - name: demand From 4bcc02e9ea08132a33acdfa0872b4be665e846fa Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:19:35 +0200 Subject: [PATCH 020/103] Save job properties --- cea/interfaces/dashboard/server/jobs.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 730492a8d3..ae37ab987d 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -93,6 +93,8 @@ async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: job = await jobs.get(job_id) job.state = JOB_STATE_STARTED job.start_time = datetime.now() + await jobs.set(job.id, job) + await sio.emit("cea-worker-started", job.model_dump(mode='json')) return job @@ -103,6 +105,8 @@ async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: job.state = JOB_STATE_SUCCESS job.error = None job.end_time = datetime.now() + await jobs.set(job.id, job) + if job.id in worker_processes: del worker_processes[job.id] await sio.emit("cea-worker-success", job.model_dump(mode='json')) @@ -118,6 +122,8 @@ async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo job.state = JOB_STATE_ERROR job.error = error job.end_time = datetime.now() + await jobs.set(job.id, job) + if job.id in worker_processes: del worker_processes[job.id] await sio.emit("cea-worker-error", job.model_dump(mode='json')) @@ -138,6 +144,8 @@ async def cancel_job(jobs: CEAJobs, job_id: str) -> JobInfo: job.state = JOB_STATE_CANCELED job.error = "Canceled by user" job.end_time = datetime.now() + await jobs.set(job.id, job) + kill_job(job_id) await sio.emit("cea-worker-canceled", job.model_dump(mode='json')) return job From 1ab5a450c9200dffbc3bbc3b9b406c820fd7f9c1 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:22:43 +0200 Subject: [PATCH 021/103] Remove commented lines --- cea/interfaces/dashboard/server/jobs.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index ae37ab987d..d8d7b2af2e 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -21,24 +21,6 @@ JOB_STATE_ERROR = 3 JOB_STATE_CANCELED = 4 -# job_info_model = api.model('JobInfo', { -# 'id': fields.Integer, -# 'script': fields.String, -# 'state': fields.Integer, -# 'error': fields.String, -# 'parameters': fields.Raw, -# 'start_time': fields.DateTime, -# 'end_time': fields.DateTime, -# }) -# -# job_info_request_parser = reqparse.RequestParser() -# job_info_request_parser.add_argument("id", type=int, location="json") -# job_info_request_parser.add_argument("script", type=str, required=True, location="json") -# job_info_request_parser.add_argument("state", location="json") -# job_info_request_parser.add_argument("error", location="json") -# job_info_request_parser.add_argument("parameters", type=dict, location="json") - - worker_processes = {} # jobid -> subprocess.Popen From 7348b876606c50de169fcbd8011fc78a185b59b6 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:32:13 +0200 Subject: [PATCH 022/103] Use lifespan events instead of endpoint for shutting down --- cea/interfaces/dashboard/app.py | 11 ++++++++++- cea/interfaces/dashboard/server/__init__.py | 9 --------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cea/interfaces/dashboard/app.py b/cea/interfaces/dashboard/app.py index e5b0b6e36c..3464f34871 100644 --- a/cea/interfaces/dashboard/app.py +++ b/cea/interfaces/dashboard/app.py @@ -1,3 +1,5 @@ +from contextlib import asynccontextmanager + from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware @@ -8,7 +10,14 @@ import cea.interfaces.dashboard.server as server -app = FastAPI() +@asynccontextmanager +async def lifespan(_: FastAPI): + yield + print("Shutting down server...") + # Shutdown all worker processes on exit + server.shutdown_worker_processes() + +app = FastAPI(lifespan=lifespan) # Setup CORS app.add_middleware( diff --git a/cea/interfaces/dashboard/server/__init__.py b/cea/interfaces/dashboard/server/__init__.py index 2ef427befc..5e7d1d4a6a 100644 --- a/cea/interfaces/dashboard/server/__init__.py +++ b/cea/interfaces/dashboard/server/__init__.py @@ -18,12 +18,3 @@ def shutdown_worker_processes(): @router.get("/alive") async def get_health_check(): return {'success': True} - - -@router.post("/shutdown") -async def shutdown(): - print("Shutting down server...") - shutdown_worker_processes() - # current_app.socketio.stop() - - return {'message': 'Shutting down...'} From 9dddf4dcadd6ff90e0c3e21befd724564232142e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:25:08 +0200 Subject: [PATCH 023/103] Allow loading of config from environment variables --- cea/interfaces/dashboard/app.py | 3 ++- cea/interfaces/dashboard/dashboard.py | 17 ++++++++++++++++- cea/interfaces/dashboard/settings.py | 18 ++++++++++++++++++ environment.yml | 1 + 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 cea/interfaces/dashboard/settings.py diff --git a/cea/interfaces/dashboard/app.py b/cea/interfaces/dashboard/app.py index 3464f34871..7ad6e1eaba 100644 --- a/cea/interfaces/dashboard/app.py +++ b/cea/interfaces/dashboard/app.py @@ -8,6 +8,7 @@ import cea.interfaces.dashboard.api as api import cea.interfaces.dashboard.plots.routes as plots import cea.interfaces.dashboard.server as server +from cea.interfaces.dashboard.settings import get_settings @asynccontextmanager @@ -22,7 +23,7 @@ async def lifespan(_: FastAPI): # Setup CORS app.add_middleware( CORSMiddleware, - allow_origins=["*"], + allow_origins=get_settings().cors_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index f927e7351e..0bdb82e116 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -2,10 +2,25 @@ import uvicorn +from cea.interfaces.dashboard.settings import get_settings + def main(config): + # Try loading settings from env vars first + settings = get_settings() + + # Load from config if not found in env vars + if settings.host is None: + settings.host = config.server.host + + if settings.port is None: + settings.port = config.server.port + + print(f"Using settings: {settings}") + try: - uvicorn.run("cea.interfaces.dashboard.app:app", host="127.0.0.1", port=5050) + uvicorn.run("cea.interfaces.dashboard.app:app", + host=settings.host, port=settings.port) except KeyboardInterrupt: sys.exit(0) diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py new file mode 100644 index 0000000000..4efd121186 --- /dev/null +++ b/cea/interfaces/dashboard/settings.py @@ -0,0 +1,18 @@ +from functools import lru_cache +from typing import Optional, List + +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class Settings(BaseSettings): + # Use "cea_" as prefix for env vars + model_config = SettingsConfigDict(env_prefix='cea_') + + host: Optional[str] = None + port: Optional[int] = None + cors_origins: List[str] = ["*"] + + +@lru_cache +def get_settings(): + return Settings() diff --git a/environment.yml b/environment.yml index 2445f2c85b..7e7065d363 100644 --- a/environment.yml +++ b/environment.yml @@ -8,6 +8,7 @@ dependencies: - fiona - aiocache - fastapi +- pydantic-settings - uvicorn-standard - jinja2 - python-socketio From 5a196e9fbf4d80bb2e82b4fc271cb4255fb3d11c Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 19 Jul 2024 18:07:14 +0200 Subject: [PATCH 024/103] Use enum for job state --- cea/interfaces/dashboard/server/jobs.py | 26 ++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index d8d7b2af2e..314cf3c4ef 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -3,6 +3,7 @@ """ import subprocess from datetime import datetime +from enum import IntEnum from typing import Dict, Any import psutil @@ -14,12 +15,15 @@ router = APIRouter() -# Job states -JOB_STATE_PENDING = 0 -JOB_STATE_STARTED = 1 -JOB_STATE_SUCCESS = 2 -JOB_STATE_ERROR = 3 -JOB_STATE_CANCELED = 4 + +class JobState(IntEnum): + # Job states + PENDING = 0 + STARTED = 1 + SUCCESS = 2 + ERROR = 3 + CANCELED = 4 + worker_processes = {} # jobid -> subprocess.Popen @@ -30,7 +34,7 @@ class JobInfo(BaseModel): id: str script: str parameters: dict - state: int = JOB_STATE_PENDING + state: JobState = JobState.PENDING error: str = None start_time: datetime = None end_time: datetime = None @@ -73,7 +77,7 @@ async def next_id(): @router.post("/started/{job_id}") async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: job = await jobs.get(job_id) - job.state = JOB_STATE_STARTED + job.state = JobState.STARTED job.start_time = datetime.now() await jobs.set(job.id, job) @@ -84,7 +88,7 @@ async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: @router.post("/success/{job_id}") async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: job = await jobs.get(job_id) - job.state = JOB_STATE_SUCCESS + job.state = JobState.SUCCESS job.error = None job.end_time = datetime.now() await jobs.set(job.id, job) @@ -101,7 +105,7 @@ async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo error = body.decode("utf-8") job = await jobs.get(job_id) - job.state = JOB_STATE_ERROR + job.state = JobState.ERROR job.error = error job.end_time = datetime.now() await jobs.set(job.id, job) @@ -123,7 +127,7 @@ async def start_job(jobs: CEAJobs, job_id: str): @router.post("/cancel/{job_id}") async def cancel_job(jobs: CEAJobs, job_id: str) -> JobInfo: job = await jobs.get(job_id) - job.state = JOB_STATE_CANCELED + job.state = JobState.CANCELED job.error = "Canceled by user" job.end_time = datetime.now() await jobs.set(job.id, job) From 6a065a007f0029de93b5f0cd7529ac50f8a649cc Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:39:12 +0200 Subject: [PATCH 025/103] Add worker url to settings --- cea/interfaces/dashboard/dashboard.py | 3 +++ cea/interfaces/dashboard/dependencies.py | 6 ++++++ cea/interfaces/dashboard/server/jobs.py | 9 ++++++--- cea/interfaces/dashboard/settings.py | 1 + cea/scripts.yml | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 0bdb82e116..7b9b126736 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -16,6 +16,9 @@ def main(config): if settings.port is None: settings.port = config.server.port + if settings.worker_url is None: + settings.worker_url = config.worker.url + print(f"Using settings: {settings}") try: diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index d9725aafe5..9e3cc0d918 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -5,6 +5,7 @@ import cea.config from cea.config import CEA_CONFIG +from cea.interfaces.dashboard.settings import get_settings from cea.plots.cache import PlotCache CACHE_NAME = 'default' @@ -95,6 +96,11 @@ async def get_jobs(): return JobStoreCache(_cache, "jobs") +def get_worker_url(): + return get_settings().worker_url + + CEAConfig = Annotated[dict, Depends(get_cea_config)] CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] CEAJobs = Annotated[dict, Depends(get_jobs)] +CEAWorkerUrl = Annotated[dict, Depends(get_worker_url)] diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 314cf3c4ef..83acee96a4 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -10,7 +10,7 @@ from fastapi import APIRouter, Request from pydantic import BaseModel -from cea.interfaces.dashboard.dependencies import CEAJobs +from cea.interfaces.dashboard.dependencies import CEAJobs, CEAWorkerUrl from cea.interfaces.dashboard.server.socketio import sio router = APIRouter() @@ -117,10 +117,13 @@ async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo @router.post('/start/{job_id}') -async def start_job(jobs: CEAJobs, job_id: str): +async def start_job(worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" print("tools/route_start: {job_id}".format(**locals())) - worker_processes[job_id] = subprocess.Popen(["python", "-m", "cea.worker", f"{job_id}"]) + worker_processes[job_id] = subprocess.Popen([ + "python", "-m", "cea.worker", f"{job_id}", + "--url", f"{worker_url}" + ]) return job_id diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py index 4efd121186..6dad687d86 100644 --- a/cea/interfaces/dashboard/settings.py +++ b/cea/interfaces/dashboard/settings.py @@ -11,6 +11,7 @@ class Settings(BaseSettings): host: Optional[str] = None port: Optional[int] = None cors_origins: List[str] = ["*"] + worker_url: Optional[str] = None @lru_cache diff --git a/cea/scripts.yml b/cea/scripts.yml index f7a9c02098..4037ded2f3 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -444,7 +444,7 @@ default: description: dashboard interfaces: [cli] module: cea.interfaces.dashboard.dashboard - parameters: ['general:debug', 'server'] + parameters: ['general:debug', 'server', 'worker'] - name: excel-to-shapefile label: excel-to-shapefile From 3b91453ab21ff948aba0c0ebc6cb0c13b7dbd727 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:42:24 +0200 Subject: [PATCH 026/103] Fix pydantic unable to parse list of string --- cea/interfaces/dashboard/app.py | 8 +++++++- cea/interfaces/dashboard/settings.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/app.py b/cea/interfaces/dashboard/app.py index 7ad6e1eaba..1b2f59ec25 100644 --- a/cea/interfaces/dashboard/app.py +++ b/cea/interfaces/dashboard/app.py @@ -18,12 +18,18 @@ async def lifespan(_: FastAPI): # Shutdown all worker processes on exit server.shutdown_worker_processes() + +def get_cors_origins(): + origin = get_settings().cors_origin + return [origin] + + app = FastAPI(lifespan=lifespan) # Setup CORS app.add_middleware( CORSMiddleware, - allow_origins=get_settings().cors_origins, + allow_origins=get_cors_origins(), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py index 6dad687d86..89e8e70086 100644 --- a/cea/interfaces/dashboard/settings.py +++ b/cea/interfaces/dashboard/settings.py @@ -10,7 +10,7 @@ class Settings(BaseSettings): host: Optional[str] = None port: Optional[int] = None - cors_origins: List[str] = ["*"] + cors_origin: str = "*" worker_url: Optional[str] = None From 24ff3ad732040a701f8830a5479cf4460b98ca29 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:57:10 +0200 Subject: [PATCH 027/103] Rename dict cache class to be generic --- cea/interfaces/dashboard/dependencies.py | 36 +++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index 9e3cc0d918..5af97457f6 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -19,6 +19,8 @@ }) + + class CEAConfigCache(cea.config.Configuration): _cache = caches.get(CACHE_NAME) _cache_key = "cea_config" @@ -34,37 +36,37 @@ async def save(self, config_file: str = CEA_CONFIG) -> None: super().save(config_file) -class JobStoreCache: +class AsyncDictCache: def __init__(self, cache: BaseCache, cache_key: str): self._cache = cache self._cache_key = cache_key - async def get(self, job_id): - jobs = await self._cache.get(self._cache_key) + async def get(self, item_id): + _dict = await self._cache.get(self._cache_key) - if jobs is None: - jobs = {} + if _dict is None: + _dict = {} - return jobs[job_id] + return _dict[item_id] - async def set(self, job_id, value): - jobs = await self._cache.get(self._cache_key) + async def set(self, item_id, value): + _dict = await self._cache.get(self._cache_key) - if jobs is None: - jobs = {} + if _dict is None: + _dict = {} - jobs[job_id] = value - await self._cache.set(self._cache_key, jobs) + _dict[item_id] = value + await self._cache.set(self._cache_key, item_id) return value async def values(self): - jobs = await self._cache.get(self._cache_key) - return jobs.values() + _dict = await self._cache.get(self._cache_key) + return _dict.values() async def keys(self): - jobs = await self._cache.get(self._cache_key) - return jobs.keys() + _dict = await self._cache.get(self._cache_key) + return _dict.keys() async def get_cea_config(): @@ -93,7 +95,7 @@ async def get_jobs(): jobs = dict() await _cache.set("jobs", jobs) - return JobStoreCache(_cache, "jobs") + return AsyncDictCache(_cache, "jobs") def get_worker_url(): From b7826d7c33cb0c85ecaf3fa7fece75181b4f1c6a Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:31:03 +0200 Subject: [PATCH 028/103] Add delete funciton --- cea/interfaces/dashboard/dependencies.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index 5af97457f6..2f95492919 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -19,8 +19,6 @@ }) - - class CEAConfigCache(cea.config.Configuration): _cache = caches.get(CACHE_NAME) _cache_key = "cea_config" @@ -42,24 +40,21 @@ def __init__(self, cache: BaseCache, cache_key: str): self._cache_key = cache_key async def get(self, item_id): - _dict = await self._cache.get(self._cache_key) - - if _dict is None: - _dict = {} - + _dict = await self._cache.get(self._cache_key, dict()) return _dict[item_id] async def set(self, item_id, value): - _dict = await self._cache.get(self._cache_key) - - if _dict is None: - _dict = {} - + _dict = await self._cache.get(self._cache_key, dict()) _dict[item_id] = value - await self._cache.set(self._cache_key, item_id) + await self._cache.set(self._cache_key, _dict) return value + async def delete(self, item_id): + _dict = await self._cache.get(self._cache_key, dict()) + del _dict[item_id] + await self._cache.set(self._cache_key, _dict) + async def values(self): _dict = await self._cache.get(self._cache_key) return _dict.values() From cb86f57fa77811e8a3167dfe29b209e892a99fc5 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:33:22 +0200 Subject: [PATCH 029/103] Add worker processes to cache --- cea/interfaces/dashboard/dependencies.py | 12 +++++++++ cea/interfaces/dashboard/server/jobs.py | 31 +++++++++++------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/cea/interfaces/dashboard/dependencies.py b/cea/interfaces/dashboard/dependencies.py index 2f95492919..28ff362787 100644 --- a/cea/interfaces/dashboard/dependencies.py +++ b/cea/interfaces/dashboard/dependencies.py @@ -93,6 +93,17 @@ async def get_jobs(): return AsyncDictCache(_cache, "jobs") +async def get_worker_processes(): + _cache = caches.get(CACHE_NAME) + worker_processes = await _cache.get("worker_processes") + + if worker_processes is None: + worker_processes = dict() + await _cache.set("worker_processes", worker_processes) + + return AsyncDictCache(_cache, "worker_processes") + + def get_worker_url(): return get_settings().worker_url @@ -100,4 +111,5 @@ def get_worker_url(): CEAConfig = Annotated[dict, Depends(get_cea_config)] CEAPlotCache = Annotated[dict, Depends(get_plot_cache)] CEAJobs = Annotated[dict, Depends(get_jobs)] +CEAWorkerProcesses = Annotated[dict, Depends(get_worker_processes)] CEAWorkerUrl = Annotated[dict, Depends(get_worker_url)] diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index 83acee96a4..c7c73c0622 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -10,7 +10,7 @@ from fastapi import APIRouter, Request from pydantic import BaseModel -from cea.interfaces.dashboard.dependencies import CEAJobs, CEAWorkerUrl +from cea.interfaces.dashboard.dependencies import CEAJobs, CEAWorkerUrl, CEAWorkerProcesses, get_worker_processes from cea.interfaces.dashboard.server.socketio import sio router = APIRouter() @@ -25,9 +25,6 @@ class JobState(IntEnum): CANCELED = 4 -worker_processes = {} # jobid -> subprocess.Popen - - # FIXME: replace with database or similar solution class JobInfo(BaseModel): """Store all the information required to run a job""" @@ -86,21 +83,21 @@ async def set_job_started(jobs: CEAJobs, job_id: str) -> JobInfo: @router.post("/success/{job_id}") -async def set_job_success(jobs: CEAJobs, job_id: str) -> JobInfo: +async def set_job_success(jobs: CEAJobs, job_id: str, worker_processes: CEAWorkerProcesses) -> JobInfo: job = await jobs.get(job_id) job.state = JobState.SUCCESS job.error = None job.end_time = datetime.now() await jobs.set(job.id, job) - if job.id in worker_processes: - del worker_processes[job.id] + if job.id in await worker_processes.values(): + await worker_processes.delete(job.id) await sio.emit("cea-worker-success", job.model_dump(mode='json')) return job @router.post("/error/{job_id}") -async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo: +async def set_job_error(jobs: CEAJobs, job_id: str, worker_processes: CEAWorkerProcesses, request: Request) -> JobInfo: body = await request.body() error = body.decode("utf-8") @@ -110,14 +107,14 @@ async def set_job_error(jobs: CEAJobs, job_id: str, request: Request) -> JobInfo job.end_time = datetime.now() await jobs.set(job.id, job) - if job.id in worker_processes: - del worker_processes[job.id] + if job.id in await worker_processes.values(): + await worker_processes.delete(job.id) await sio.emit("cea-worker-error", job.model_dump(mode='json')) return job @router.post('/start/{job_id}') -async def start_job(worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): +async def start_job(worker_processes: CEAWorkerProcesses, worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" print("tools/route_start: {job_id}".format(**locals())) worker_processes[job_id] = subprocess.Popen([ @@ -128,24 +125,24 @@ async def start_job(worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): @router.post("/cancel/{job_id}") -async def cancel_job(jobs: CEAJobs, job_id: str) -> JobInfo: +async def cancel_job(jobs: CEAJobs, job_id: str, worker_processes: CEAWorkerProcesses) -> JobInfo: job = await jobs.get(job_id) job.state = JobState.CANCELED job.error = "Canceled by user" job.end_time = datetime.now() await jobs.set(job.id, job) - kill_job(job_id) + await kill_job(job_id, worker_processes) await sio.emit("cea-worker-canceled", job.model_dump(mode='json')) return job -def kill_job(jobid): +async def kill_job(jobid, worker_processes): """Kill the processes associated with a jobid""" - if jobid not in worker_processes: + if jobid not in await worker_processes.values(): return - popen = worker_processes[jobid] + popen = await worker_processes.get(jobid) # using code from here: https://stackoverflow.com/a/4229404/2260 # to terminate child processes too print("killing child processes of {jobid} ({pid})".format(jobid=jobid, pid=popen.pid)) @@ -158,4 +155,4 @@ def kill_job(jobid): print("-- killing child {pid}".format(pid=child.pid)) child.kill() process.kill() - del worker_processes[jobid] + await worker_processes.delete(jobid) From b90275536c89af0f7e19fcc1d02713bf0896cf5f Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:30:58 +0200 Subject: [PATCH 030/103] Remove unused import --- cea/interfaces/dashboard/server/jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index c7c73c0622..b0a86a8613 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -10,7 +10,7 @@ from fastapi import APIRouter, Request from pydantic import BaseModel -from cea.interfaces.dashboard.dependencies import CEAJobs, CEAWorkerUrl, CEAWorkerProcesses, get_worker_processes +from cea.interfaces.dashboard.dependencies import CEAJobs, CEAWorkerUrl, CEAWorkerProcesses from cea.interfaces.dashboard.server.socketio import sio router = APIRouter() From 5dd75fee76e24b71b9e09e0ed30d931d6c672ac3 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:46:50 +0200 Subject: [PATCH 031/103] Add `project_root` to settings --- cea/default.config | 2 +- cea/interfaces/dashboard/dashboard.py | 3 +++ cea/interfaces/dashboard/settings.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cea/default.config b/cea/default.config index 7afec9375f..c1365ab450 100644 --- a/cea/default.config +++ b/cea/default.config @@ -1434,7 +1434,7 @@ filename.type = StringParameter filename.help = Name to use for polygon shapefile outputs [server] -project-root = {general:project}/.. +project-root = project-root.type = PathParameter project-root.help = Path to the root of all projects, assuming they are all stored in one location diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 7b9b126736..c03e16bec7 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -19,6 +19,9 @@ def main(config): if settings.worker_url is None: settings.worker_url = config.worker.url + if settings.project_root is None: + settings.project_root = config.project_root + print(f"Using settings: {settings}") try: diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py index 89e8e70086..8fa77f45b1 100644 --- a/cea/interfaces/dashboard/settings.py +++ b/cea/interfaces/dashboard/settings.py @@ -12,6 +12,7 @@ class Settings(BaseSettings): port: Optional[int] = None cors_origin: str = "*" worker_url: Optional[str] = None + project_root: Optional[str] = None @lru_cache From 841ba578adeae34529a815cc729b6fc85d6e19b1 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:24:39 +0200 Subject: [PATCH 032/103] Fix parameter not found --- cea/interfaces/dashboard/dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index c03e16bec7..5c06c6bfa0 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -20,7 +20,7 @@ def main(config): settings.worker_url = config.worker.url if settings.project_root is None: - settings.project_root = config.project_root + settings.project_root = config.server.project_root print(f"Using settings: {settings}") From 5c21c9412cf5ef1beb1b64bf24193a4a22344de7 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:29:47 +0200 Subject: [PATCH 033/103] Fix `worker_processes` not found --- cea/interfaces/dashboard/app.py | 2 +- cea/interfaces/dashboard/server/__init__.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cea/interfaces/dashboard/app.py b/cea/interfaces/dashboard/app.py index 1b2f59ec25..f575deadaf 100644 --- a/cea/interfaces/dashboard/app.py +++ b/cea/interfaces/dashboard/app.py @@ -16,7 +16,7 @@ async def lifespan(_: FastAPI): yield print("Shutting down server...") # Shutdown all worker processes on exit - server.shutdown_worker_processes() + await server.shutdown_worker_processes() def get_cors_origins(): diff --git a/cea/interfaces/dashboard/server/__init__.py b/cea/interfaces/dashboard/server/__init__.py index 5e7d1d4a6a..131a885011 100644 --- a/cea/interfaces/dashboard/server/__init__.py +++ b/cea/interfaces/dashboard/server/__init__.py @@ -2,6 +2,7 @@ import cea.interfaces.dashboard.server.jobs as jobs import cea.interfaces.dashboard.server.streams as streams +from cea.interfaces.dashboard.dependencies import get_worker_processes router = APIRouter() @@ -9,10 +10,11 @@ router.include_router(streams.router, prefix='/streams') -def shutdown_worker_processes(): +async def shutdown_worker_processes(): """When shutting down the flask server, make sure any subprocesses are also terminated. See issue #2408.""" - for jobid in jobs.worker_processes.keys(): - jobs.kill_job(jobid) + worker_processes = await get_worker_processes() + for jobid in await worker_processes.keys(): + await jobs.kill_job(jobid, worker_processes) @router.get("/alive") From 9a01d2eab19f74cc8b6fd1f840f3b542b15b7b26 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:34:00 +0200 Subject: [PATCH 034/103] Add schema for database path payload --- cea/interfaces/dashboard/api/inputs.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index 40498fcac8..c4734d69ff 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -1,5 +1,6 @@ import json import os +import pathlib import shutil import traceback from typing import Dict, Any @@ -417,25 +418,23 @@ async def put_input_database_data(config: CEAConfig, payload: Dict[str, Any]): return payload +class DatabasePath(BaseModel): + path: pathlib.Path + name: str + + @router.put('/databases/copy') -async def copy_input_database(config: CEAConfig, payload: Dict[str, Any]): +async def copy_input_database(config: CEAConfig, database_path: DatabasePath): locator = cea.inputlocator.InputLocator(config.scenario) - if payload and 'path' in payload and 'name' in payload: - copy_path = os.path.join(payload['path'], payload['name']) - if os.path.exists(copy_path): - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f'Copy path {copy_path} already exists. Choose a different path/name.', - ) - locator.ensure_parent_folder_exists(copy_path) - shutil.copytree(locator.get_databases_folder(), copy_path) - return {'message': 'Database copied to {}'.format(copy_path)} - else: + if os.path.exists(copy_path): raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="'path' and 'name' required", + detail=f'Copy path {copy_path} already exists. Choose a different path/name.', ) + locator.ensure_parent_folder_exists(copy_path) + shutil.copytree(locator.get_databases_folder(), copy_path) + return {'message': 'Database copied to {}'.format(copy_path)} @router.get('/databases/check') From d8b58c7b2ccd3e5b4f3058f4add902fbe4f906ca Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:39:39 +0200 Subject: [PATCH 035/103] Verify user-provided paths with project root --- cea/interfaces/dashboard/api/contents.py | 5 ++++- cea/interfaces/dashboard/api/inputs.py | 2 ++ cea/interfaces/dashboard/api/project.py | 23 +++++++++++++---------- cea/interfaces/dashboard/utils.py | 21 +++++++++++++++++++++ 4 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 cea/interfaces/dashboard/utils.py diff --git a/cea/interfaces/dashboard/api/contents.py b/cea/interfaces/dashboard/api/contents.py index b8f32690bb..3bd26ce35e 100644 --- a/cea/interfaces/dashboard/api/contents.py +++ b/cea/interfaces/dashboard/api/contents.py @@ -6,6 +6,7 @@ from fastapi import APIRouter, HTTPException, status from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.utils import secure_path, InvalidPathError router = APIRouter() @@ -93,9 +94,11 @@ async def get_contents(config: CEAConfig, type: ContentType, root: str, else: root_path = root try: + # Check path first + secure_path(os.path.join(root_path, content_path)) content_info = get_content_info(root_path, content_path, content_type, show_hidden=show_hidden) return content_info.as_dict() - except ContentPathNotFound: + except (ContentPathNotFound, InvalidPathError): raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Path `{content_path}` does not exist", diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index c4734d69ff..83f1fb68f2 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -19,6 +19,7 @@ from cea.datamanagement.databases_verification import InputFileValidator from cea.interfaces.dashboard.api.databases import read_all_databases, DATABASES_SCHEMA_KEYS from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.utils import secure_path from cea.plots.supply_system.a_supply_system_map import get_building_connectivity, newer_network_layout_exists from cea.plots.variable_naming import get_color_array from cea.technologies.network_layout.main import layout_network, NetworkLayout @@ -427,6 +428,7 @@ class DatabasePath(BaseModel): async def copy_input_database(config: CEAConfig, database_path: DatabasePath): locator = cea.inputlocator.InputLocator(config.scenario) + copy_path = secure_path(os.path.join(database_path.path, database_path.name)) if os.path.exists(copy_path): raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index e8968edd73..593a06bc86 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -16,6 +16,7 @@ import cea.api import cea.inputlocator from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.utils import secure_path from cea.plots.colors import color_to_rgb from cea.utilities.standardize_coordinates import get_geographic_coordinate_system @@ -40,6 +41,7 @@ async def get_project_info(config: CEAConfig, project: str = None): if project is None: scenario_name = config.scenario_name else: + project = secure_path(project) if not os.path.exists(project): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -61,7 +63,7 @@ async def create_new_project(new_project: NewProject): project_root = new_project.project_root if project_name and project_root: - project = os.path.join(project_root, project_name) + project = secure_path(os.path.join(project_root, project_name)) try: os.makedirs(project, exist_ok=True) except OSError as e: @@ -83,7 +85,7 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): """ Update Project info in config """ - project = scenario_path.project + project = secure_path(scenario_path.project) scenario_name = scenario_path.scenario_name if project and scenario_name: @@ -110,7 +112,7 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): """ Create new scenario """ - project = payload.get('project') + project = secure_path(payload.get('project')) scenario_name = payload.get('scenario_name') if scenario_name is None: raise HTTPException( @@ -118,7 +120,7 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): detail='scenario_name parameter cannot be empty', ) - databases_path = payload.get('databases_path') + databases_path = secure_path(payload.get('databases_path')) input_data = payload.get('input_data') with tempfile.TemporaryDirectory() as tmp: @@ -155,7 +157,7 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): elif input_data == 'copy': source_scenario_name = payload.get('copy_scenario') - source_scenario = os.path.join(_project, source_scenario_name) + source_scenario = secure_path(os.path.join(_project, source_scenario_name)) os.makedirs(locator.get_input_folder(), exist_ok=True) shutil.copytree(cea.inputlocator.InputLocator(source_scenario).get_input_folder(), locator.get_input_folder()) @@ -188,7 +190,7 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): raise Exception(f'{tool}_helper: {e}') from e # Move temp scenario to correct path - new_scenario_path = os.path.join(_project, str(scenario_name).strip()) + new_scenario_path = secure_path(os.path.join(_project, str(scenario_name).strip())) print(f"Moving from {config.scenario} to {new_scenario_path}") shutil.move(config.scenario, new_scenario_path) @@ -235,11 +237,11 @@ async def get(scenario: str): @router.put('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): """Update scenario""" - scenario_path = os.path.join(config.project, scenario) - new_scenario_name = payload.get('name') + scenario_path = secure_path(os.path.join(config.project, scenario)) + new_scenario_name: str = payload.get('name') try: if new_scenario_name is not None: - new_path = os.path.join(config.project, new_scenario_name) + new_path = secure_path(os.path.join(config.project, new_scenario_name)) os.rename(scenario_path, new_path) if config.scenario_name == scenario: config.scenario_name = new_scenario_name @@ -256,7 +258,7 @@ async def put(config: CEAConfig, scenario: str, payload: Dict[str, Any]): @router.delete('/scenario/{scenario}', dependencies=[Depends(check_scenario_exists)]) async def delete(config: CEAConfig, scenario: str): """Delete scenario from project""" - scenario_path = os.path.join(config.project, scenario) + scenario_path = secure_path(os.path.join(config.project, scenario)) try: shutil.rmtree(scenario_path) return {'scenarios': list_scenario_names_for_project(config)} @@ -317,6 +319,7 @@ def generate_scenario_image(config, scenario: str, image_path: str, building_lim @router.get('/scenario/{scenario}/image') async def get_scenario_image(config: CEAConfig, project: str, scenario: str): if project is not None: + project = secure_path(project) if not os.path.exists(project): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, diff --git a/cea/interfaces/dashboard/utils.py b/cea/interfaces/dashboard/utils.py new file mode 100644 index 0000000000..f1b08d22a3 --- /dev/null +++ b/cea/interfaces/dashboard/utils.py @@ -0,0 +1,21 @@ +import os + +from cea.interfaces.dashboard.settings import get_settings + + +class InvalidPathError(Exception): + """Raised when a path is invalid (e.g. outside or project root folder)""" + + +def secure_path(path: str) -> str: + """ + Simple sanitation of path + """ + project_root = get_settings().project_root + real_path = os.path.realpath(path) + rel_path = os.path.relpath(real_path, project_root) + + if ".." in rel_path: + raise InvalidPathError("Path is outside of project root") + + return real_path From 693477a5188056df7fb59f8c10fd126436d734be Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:07:04 +0200 Subject: [PATCH 036/103] Use commonpath to check path and project root --- cea/interfaces/dashboard/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/utils.py b/cea/interfaces/dashboard/utils.py index f1b08d22a3..f715cf630b 100644 --- a/cea/interfaces/dashboard/utils.py +++ b/cea/interfaces/dashboard/utils.py @@ -13,9 +13,9 @@ def secure_path(path: str) -> str: """ project_root = get_settings().project_root real_path = os.path.realpath(path) - rel_path = os.path.relpath(real_path, project_root) + prefix = os.path.commonpath((project_root, real_path)) - if ".." in rel_path: + if project_root != prefix: raise InvalidPathError("Path is outside of project root") return real_path From 9afb04301cf3f13a858154c3c10d3a04ed92439c Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:58:08 +0200 Subject: [PATCH 037/103] Check path only if `project_root` is defined --- cea/interfaces/dashboard/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cea/interfaces/dashboard/utils.py b/cea/interfaces/dashboard/utils.py index f715cf630b..8896d94630 100644 --- a/cea/interfaces/dashboard/utils.py +++ b/cea/interfaces/dashboard/utils.py @@ -13,9 +13,10 @@ def secure_path(path: str) -> str: """ project_root = get_settings().project_root real_path = os.path.realpath(path) - prefix = os.path.commonpath((project_root, real_path)) - if project_root != prefix: - raise InvalidPathError("Path is outside of project root") + if project_root != "": + prefix = os.path.commonpath((project_root, real_path)) + if project_root != prefix: + raise InvalidPathError("Path is outside of project root") return real_path From ead09e689e8e0264e47df9655630cdc38634e134 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:20:49 +0200 Subject: [PATCH 038/103] Sanitise database path --- cea/interfaces/dashboard/api/databases.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/databases.py b/cea/interfaces/dashboard/api/databases.py index c2b3c589d5..3f7fc2a14b 100644 --- a/cea/interfaces/dashboard/api/databases.py +++ b/cea/interfaces/dashboard/api/databases.py @@ -87,8 +87,16 @@ async def get_database_region_data(region: str): status_code=status.HTTP_400_BAD_REQUEST, detail=f"Could not find '{region}' region. Try instead {_regions}", ) + + db_path = os.path.normpath(os.path.join(databases_folder_path, region)) + if not db_path.startswith(databases_folder_path): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Invalid database region.", + ) + try: - return read_all_databases(os.path.join(databases_folder_path, region)) + return read_all_databases(db_path) except IOError as e: print(e) raise HTTPException( From 61c94d3087e0f569aa8e98ac7534f9cfa132cd17 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:18:33 +0200 Subject: [PATCH 039/103] Sanitise schedules path --- cea/interfaces/dashboard/api/contents.py | 1 + cea/interfaces/dashboard/api/inputs.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/contents.py b/cea/interfaces/dashboard/api/contents.py index 3bd26ce35e..3f589864b1 100644 --- a/cea/interfaces/dashboard/api/contents.py +++ b/cea/interfaces/dashboard/api/contents.py @@ -93,6 +93,7 @@ async def get_contents(config: CEAConfig, type: ContentType, root: str, root_path = config.server.project_root else: root_path = root + try: # Check path first secure_path(os.path.join(root_path, content_path)) diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index 83f1fb68f2..d2bcb3b837 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -366,7 +366,7 @@ def df_to_json(file_location): async def get_building_schedule(config: CEAConfig, building: str): locator = cea.inputlocator.InputLocator(config.scenario) try: - schedule_path = locator.get_building_weekly_schedules(building) + schedule_path = secure_path(locator.get_building_weekly_schedules(building)) schedule_data, schedule_complementary_data = read_cea_schedule(schedule_path) df = pd.DataFrame(schedule_data).set_index(['DAY', 'HOUR']) out = {'SCHEDULES': { From 2bc834a7aa95ebbb55e901f93a7d573db5a2933e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 13:19:57 +0200 Subject: [PATCH 040/103] Update conda-lock.yml --- conda-lock.yml | 2555 +++++++++++++++++++++++++----------------------- 1 file changed, 1318 insertions(+), 1237 deletions(-) diff --git a/conda-lock.yml b/conda-lock.yml index c4a07677e8..7505b9af71 100644 --- a/conda-lock.yml +++ b/conda-lock.yml @@ -13,10 +13,10 @@ version: 1 metadata: content_hash: - linux-64: 225acce22efe66b43f4c42ca466447591e91494d9353a312e35db816a508862f - osx-arm64: f6a646c38a00c2698f668032021eb6bdd5c11ac5076420acc8e14fddb3522745 - osx-64: 50b8c3ffd17c8860d8d4371aff4b36249b3b973991f78261df9bb352152ab4ec - win-64: 98b1f44a435c4961177a19cebb6df861ad6d5b31601a7b420af9ec7cb85eac8d + linux-64: b2c2957fddcd9b9ddc8923cef3d935591771d6a6ddd6f2ae4c48c5bd308a7873 + osx-arm64: d73a8b349385dbaf336923cfa7fdfe17b8e72b5221ca06fffc10b91bb8c3a4fa + osx-64: 5f95fabcc9038c883ccf7f2946038b60949ac09ae465dc573316628cedd0ca99 + win-64: 16ae8e92dda832ad5d683c8c17cee1fa34964ff5dfb470e25ec9ca58ed508447 channels: - url: conda-forge used_env_vars: [] @@ -148,11 +148,61 @@ package: sha256: 9ea26096791782101c1fd4783b9e0a8ee3778bafc83452db5ca3038cd6b3344b category: main optional: false +- name: aiohappyeyeballs + version: 2.3.5 + manager: conda + platform: linux-64 + dependencies: + python: '>=3.8.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.3.5-pyhd8ed1ab_0.conda + hash: + md5: d904abda207d2dba054fd820d34bbaee + sha256: 37ac19a57d429670dcd2c716232e6f842b7f357cecd0977b1d4fd30b8446a30a + category: main + optional: false +- name: aiohappyeyeballs + version: 2.3.5 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.3.5-pyhd8ed1ab_0.conda + hash: + md5: d904abda207d2dba054fd820d34bbaee + sha256: 37ac19a57d429670dcd2c716232e6f842b7f357cecd0977b1d4fd30b8446a30a + category: main + optional: false +- name: aiohappyeyeballs + version: 2.3.5 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.3.5-pyhd8ed1ab_0.conda + hash: + md5: d904abda207d2dba054fd820d34bbaee + sha256: 37ac19a57d429670dcd2c716232e6f842b7f357cecd0977b1d4fd30b8446a30a + category: main + optional: false +- name: aiohappyeyeballs + version: 2.3.5 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8.0' + url: https://conda.anaconda.org/conda-forge/noarch/aiohappyeyeballs-2.3.5-pyhd8ed1ab_0.conda + hash: + md5: d904abda207d2dba054fd820d34bbaee + sha256: 37ac19a57d429670dcd2c716232e6f842b7f357cecd0977b1d4fd30b8446a30a + category: main + optional: false - name: aiohttp - version: 3.9.5 + version: 3.10.2 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' + aiohappyeyeballs: '>=2.3.0' aiosignal: '>=1.1.2' async-timeout: '>=4.0,<5.0' attrs: '>=17.3.0' @@ -162,17 +212,19 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.9.5-py38h01eb140_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.10.2-py38h2019614_0.conda hash: - md5: 6f1f11964405dfe3b44e826db69c0fbb - sha256: 2f35397d291934d2851d0d5bd14b95574306dfd061c33e31694eea98a672c4c5 + md5: aefa307b305ab253c865cc81fa8129b6 + sha256: c8d937888812c048601533a856492e7fb55db75efde3dfad5756e7fe4c80b4f7 category: main optional: false - name: aiohttp - version: 3.9.5 + version: 3.10.2 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' + aiohappyeyeballs: '>=2.3.0' aiosignal: '>=1.1.2' async-timeout: '>=4.0,<5.0' attrs: '>=17.3.0' @@ -181,17 +233,19 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.9.5-py38hae2e43d_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.10.2-py38hc718529_0.conda hash: - md5: ffbbe148f496a6640b9c5790f56e5de9 - sha256: 3a46434bf0547ddabe5561f78e651b50a5d75d759d18ba8afa28eeb3711b4dd1 + md5: 4b315bc686e7c8477504a293f0742b93 + sha256: b348f8768763d0686d2c782321ef6934d03130ef09cdb5db48abdda72ad707fe category: main optional: false - name: aiohttp - version: 3.9.5 + version: 3.10.2 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' + aiohappyeyeballs: '>=2.3.0' aiosignal: '>=1.1.2' async-timeout: '>=4.0,<5.0' attrs: '>=17.3.0' @@ -200,17 +254,18 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.9.5-py38h336bac9_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.10.2-py38h3237794_0.conda hash: - md5: 57803173a21659d9e95d3e24e1daa9ae - sha256: dfa06a8fee0d2ac03994b74e3a1d0d9187801750b1bd86c8df1dc2a3798f0c15 + md5: 7a61e6aabd919af7c6e8b8fbeeeccd4d + sha256: 799d22e7642deed0825c87dc2267f49e2b8705bdc697c9367290d9acddae2adc category: main optional: false - name: aiohttp - version: 3.9.5 + version: 3.10.2 manager: conda platform: win-64 dependencies: + aiohappyeyeballs: '>=2.3.0' aiosignal: '>=1.1.2' async-timeout: '>=4.0,<5.0' attrs: '>=17.3.0' @@ -222,10 +277,10 @@ package: vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.9.5-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.10.2-py38h4cb3324_0.conda hash: - md5: af47e7a369156947dd91f9f7ce214d95 - sha256: 40db66c2336563ca37fc2b751192fc5782f3e56f103a7538ba363eea4d763508 + md5: 858504ad3c45ed8b4ff01fd5df063b69 + sha256: 28563fce8c4e8c628a730bb9180b479f15f0287fb58efda335981b6fe5c8c79f category: main optional: false - name: aiosignal @@ -259,8 +314,8 @@ package: manager: conda platform: osx-arm64 dependencies: - frozenlist: '>=1.1.0' python: '>=3.7' + frozenlist: '>=1.1.0' url: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 hash: md5: d1e1eb7e21a9e2c74279d87dafb68156 @@ -381,11 +436,11 @@ package: manager: conda platform: osx-arm64 dependencies: + typing_extensions: '' exceptiongroup: '' - idna: '>=2.8' python: '>=3.7' sniffio: '>=1.1' - typing_extensions: '' + idna: '>=2.8' url: https://conda.anaconda.org/conda-forge/noarch/anyio-3.7.1-pyhd8ed1ab_0.conda hash: md5: 7b517e7a6f0790337906c055aa97ca49 @@ -516,9 +571,9 @@ package: manager: conda platform: osx-arm64 dependencies: + typing-extensions: '' argon2-cffi-bindings: '' python: '>=3.7' - typing-extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda hash: md5: 3afef1f55a1366b4d3b6a0d92e2235e4 @@ -824,51 +879,51 @@ package: category: main optional: false - name: attrs - version: 23.2.0 + version: 24.2.0 manager: conda platform: linux-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/attrs-24.2.0-pyh71513ae_0.conda hash: - md5: 5e4c0743c70186509d1412e03c2d8dfa - sha256: 77c7d03bdb243a048fff398cedc74327b7dc79169ebe3b4c8448b0331ea55fea + md5: 6732fa52eb8e66e5afeb32db8701a791 + sha256: 28dba85a7e0f7fb57d7315e13f603d1e41b83c5b88aa2a602596b52c833a2ff8 category: main optional: false - name: attrs - version: 23.2.0 + version: 24.2.0 manager: conda platform: osx-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/attrs-24.2.0-pyh71513ae_0.conda hash: - md5: 5e4c0743c70186509d1412e03c2d8dfa - sha256: 77c7d03bdb243a048fff398cedc74327b7dc79169ebe3b4c8448b0331ea55fea + md5: 6732fa52eb8e66e5afeb32db8701a791 + sha256: 28dba85a7e0f7fb57d7315e13f603d1e41b83c5b88aa2a602596b52c833a2ff8 category: main optional: false - name: attrs - version: 23.2.0 + version: 24.2.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/attrs-24.2.0-pyh71513ae_0.conda hash: - md5: 5e4c0743c70186509d1412e03c2d8dfa - sha256: 77c7d03bdb243a048fff398cedc74327b7dc79169ebe3b4c8448b0331ea55fea + md5: 6732fa52eb8e66e5afeb32db8701a791 + sha256: 28dba85a7e0f7fb57d7315e13f603d1e41b83c5b88aa2a602596b52c833a2ff8 category: main optional: false - name: attrs - version: 23.2.0 + version: 24.2.0 manager: conda platform: win-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/attrs-24.2.0-pyh71513ae_0.conda hash: - md5: 5e4c0743c70186509d1412e03c2d8dfa - sha256: 77c7d03bdb243a048fff398cedc74327b7dc79169ebe3b4c8448b0331ea55fea + md5: 6732fa52eb8e66e5afeb32db8701a791 + sha256: 28dba85a7e0f7fb57d7315e13f603d1e41b83c5b88aa2a602596b52c833a2ff8 category: main optional: false - name: aws-c-auth @@ -1711,9 +1766,9 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' - pytz: '' setuptools: '' + pytz: '' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda hash: md5: 9669586875baeced8fc30c0826c3270e @@ -1919,11 +1974,11 @@ package: manager: conda platform: osx-arm64 dependencies: + setuptools: '' packaging: '' + webencodings: '' python: '>=3.6' - setuptools: '' six: '>=1.9.0' - webencodings: '' url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda hash: md5: 0ed9d7c0e9afa7c025807a9a8136ea3e @@ -2112,8 +2167,8 @@ package: manager: conda platform: osx-arm64 dependencies: - jinja2: '>=3' python: '>=3.7' + jinja2: '>=3' url: https://conda.anaconda.org/conda-forge/noarch/branca-0.7.2-pyhd8ed1ab_0.conda hash: md5: 5f1c719f1cac0aee5e6bd6ca7d54a7fa @@ -2313,33 +2368,36 @@ package: manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda + url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda hash: - md5: 69b8b6202a07720f448be700e300ccf4 - sha256: 242c0c324507ee172c0e0dd2045814e746bb303d1eb78870d182ceb0abc726a8 + md5: 62ee74e96c5ebb0af99386de58cf9553 + sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d category: main optional: false - name: bzip2 version: 1.0.8 manager: conda platform: osx-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda + dependencies: + __osx: '>=10.13' + url: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda hash: - md5: 6097a6ca9ada32699b5fc4312dd6ef18 - sha256: 61fb2b488928a54d9472113e1280b468a309561caa54f33825a3593da390b242 + md5: 7ed4301d437b59045be7e051a0308211 + sha256: cad153608b81fb24fc8c509357daa9ae4e49dfc535b2cb49b91e23dbd68fc3c5 category: main optional: false - name: bzip2 version: 1.0.8 manager: conda platform: osx-arm64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda + dependencies: + __osx: '>=11.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda hash: - md5: 1bbc659ca658bfd49a481b5ef7a0f40f - sha256: bfa84296a638bea78a8bb29abc493ee95f2a0218775642474a840411b950fe5f + md5: fc6948412dbbbe9a4c9ddbbcfe0a79ab + sha256: adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91 category: main optional: false - name: bzip2 @@ -2350,102 +2408,105 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda + url: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda hash: - md5: 26eb8ca6ea332b675e11704cce84a3be - sha256: ae5f47a5c86fd6db822931255dcf017eb12f60c77f07dc782ccb477f7808aab2 + md5: 276e7ffe9ffe39688abc665ef0f45596 + sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b category: main optional: false - name: c-ares - version: 1.28.1 + version: 1.32.3 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.28.1-hd590300_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.32.3-h4bc722e_0.conda hash: - md5: dcde58ff9a1f30b0037a2315d1846d1f - sha256: cb25063f3342149c7924b21544109696197a9d774f1407567477d4f3026bf38a + md5: 7624e34ee6baebfc80d67bac76cc9d9d + sha256: 3c5a844bb60b0d52d89c3f1bd828c9856417fe33a6102fd8bbd5c13c3351704a category: main optional: false - name: c-ares - version: 1.28.1 + version: 1.32.3 manager: conda platform: osx-64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda + dependencies: + __osx: '>=10.13' + url: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.32.3-h51dda26_0.conda hash: - md5: d5eb7992227254c0e9a0ce71151f0079 - sha256: fccd7ad7e3dfa6b19352705b33eb738c4c55f79f398e106e6cf03bab9415595a + md5: 5487b45a597e142da7839941ab2494a9 + sha256: 2454287fa7d32b2cd089ad2bb46c8f8634b6f409d6fa8892c37ccc66134ec076 category: main optional: false - name: c-ares - version: 1.28.1 + version: 1.32.3 manager: conda platform: osx-arm64 - dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda + dependencies: + __osx: '>=11.0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.32.3-h99b78c6_0.conda hash: - md5: 04f776a6139f7eafc2f38668570eb7db - sha256: 2fc553d7a75e912efbdd6b82cd7916cc9cb2773e6cd873b77e02d631dd7be698 + md5: c27bebc62991ab075b773f86ba64aa9b + sha256: dc8e2c2508295595675fb829345a156b0bb42b164271c2fcafb7fb193449bcf8 category: main optional: false - name: c-ares - version: 1.28.1 + version: 1.32.3 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.28.1-hcfcfb64_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.32.3-h2466b09_0.conda hash: - md5: 3b2a518680f790a79a7e77bad1861c3a - sha256: 44ded34fdac46d4a37942c1cae3fc871dc6ecb13e0408442c6f8797671b332e6 + md5: eb6bcf1d4a0bb3ab98d4bbd402534b80 + sha256: 91e3568f5708916b28863d672120e67f85f86d3d9d892aabe6012153702aa045 category: main optional: false - name: ca-certificates - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: linux-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda hash: - md5: 847c3c2905cc467cea52c24f9cfa8080 - sha256: 979af0932b2a5a26112044891a2d79e402e5ae8166f50fa48b8ebae47c0a2d65 + md5: 23ab7665c5f63cfb9f1f6195256daac6 + sha256: c1548a3235376f464f9931850b64b02492f379b2f2bb98bc786055329b080446 category: main optional: false - name: ca-certificates - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: osx-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.7.4-h8857fd0_0.conda hash: - md5: 3c23a8cab15ae51ebc9efdc229fccecf - sha256: ba0614477229fcb0f0666356f2c4686caa66f0ed1446e7c9666ce234abe2bacf + md5: 7df874a4b05b2d2b82826190170eaa0f + sha256: d16f46c489cb3192305c7d25b795333c5fc17bb0986de20598ed519f8c9cc9e4 category: main optional: false - name: ca-certificates - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: osx-arm64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.7.4-hf0a4a13_0.conda hash: - md5: b534f104f102479402f88f73adf750f5 - sha256: f5fd189d48965df396d060eb48628cbd9f083f1a1ea79c5236f60d655c7b9633 + md5: 21f9a33e5fe996189e470c19c5354dbe + sha256: 33a61116dae7f369b6ce92a7f2a1ff361ae737c675a493b11feb5570b89e0e3b category: main optional: false - name: ca-certificates - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.7.4-h56e8100_0.conda hash: - md5: 12a3a2b3a00a21bbb390d4de5ad8dd0f - sha256: d872d11558ebeaeb87bcf9086e97c075a1a2dfffed2d0e97570cf197ab29e3d8 + md5: 9caa97c9504072cd060cf0a3142cc0ed + sha256: 7f37bb33c7954de1b4d19ad622859feb4f6c58f751c38b895524cad4e44af72e category: main optional: false - name: cached-property @@ -2551,11 +2612,11 @@ package: dependencies: fontconfig: '>=2.13.96,<3.0a0' fonts-conda-ecosystem: '' - freetype: '>=2.12.1,<3.0a0' + freetype: '>=2.10.4,<3.0a0' icu: '>=70.1,<71.0a0' libgcc-ng: '>=12' libglib: '>=2.72.1,<3.0a0' - libpng: '>=1.6.38,<1.7.0a0' + libpng: '>=1.6.37,<1.7.0a0' libxcb: '>=1.13,<1.14.0a0' libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' @@ -2564,11 +2625,10 @@ package: xorg-libx11: '' xorg-libxext: '' xorg-libxrender: '' - zlib: '>=1.2.12,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.16.0-ha61ee94_1014.tar.bz2 + url: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.16.0-ha61ee94_1012.tar.bz2 hash: - md5: d1a88f3ed5b52e1024b80d4bcd26a7a0 - sha256: f062cf56e6e50d3ad4b425ebb3765ca9138c6ebc52e6a42d1377de8bc8d954f6 + md5: 9604a7c93dd37bcb6d6cc8d6b64223a4 + sha256: 61bd7cf0a4c5f6f0e5cda3ae8b841ad4546985e0eb49ad30cf24cfedd3684862 category: main optional: false - name: cairo @@ -2578,17 +2638,16 @@ package: dependencies: fontconfig: '>=2.13.96,<3.0a0' fonts-conda-ecosystem: '' - freetype: '>=2.12.1,<3.0a0' + freetype: '>=2.10.4,<3.0a0' icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' - libpng: '>=1.6.38,<1.7.0a0' + libpng: '>=1.6.37,<1.7.0a0' libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' - zlib: '>=1.2.12,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.16.0-h904041c_1014.tar.bz2 + url: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.16.0-h56d7d38_1012.tar.bz2 hash: - md5: 2e7b4350178ed52bb6fd2b1ecbeeed4f - sha256: a41a819cf32b87492098332c9f2a2c4b1055489efdad4a8be75a086ffc8573c5 + md5: cf7c3889f5e8f7e613ee2721af1d275e + sha256: d81209b19d8e611d01944b9502c1912671aa6972764d9ce58c2b56023bd39486 category: main optional: false - name: cairo @@ -2598,17 +2657,16 @@ package: dependencies: fontconfig: '>=2.13.96,<3.0a0' fonts-conda-ecosystem: '' - freetype: '>=2.12.1,<3.0a0' + freetype: '>=2.10.4,<3.0a0' icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' - libpng: '>=1.6.38,<1.7.0a0' + libpng: '>=1.6.37,<1.7.0a0' libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' - zlib: '>=1.2.12,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.16.0-h73a0509_1014.tar.bz2 + url: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.16.0-had492bb_1012.tar.bz2 hash: - md5: be2ea75899a7b1f1dd59a862fac655ee - sha256: 508c63c893360cee44e82cf550548ae8bbcc96bd26b7f30f9197787a653dd6a1 + md5: adc2dea541141f47170f491872867844 + sha256: ef9d55daff8821ef55ac89960b42a754393b6605380a2e82e0fe182509140322 category: main optional: false - name: cairo @@ -2618,116 +2676,120 @@ package: dependencies: fontconfig: '>=2.13.96,<3.0a0' fonts-conda-ecosystem: '' - freetype: '>=2.10.4,<3.0a0' + freetype: '>=2.12.1,<3.0a0' icu: '>=70.1,<71.0a0' libglib: '>=2.72.1,<3.0a0' - libpng: '>=1.6.37,<1.7.0a0' + libpng: '>=1.6.38,<1.7.0a0' libzlib: '>=1.2.12,<2.0.0a0' pixman: '>=0.40.0,<1.0a0' - vc: '>=14.1,<15' - vs2015_runtime: '>=14.16.27033' - url: https://conda.anaconda.org/conda-forge/win-64/cairo-1.16.0-h0ac17fb_1012.tar.bz2 + vc: '>=14.2,<15' + vs2015_runtime: '>=14.29.30139' + zlib: '>=1.2.12,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/win-64/cairo-1.16.0-hd694305_1014.tar.bz2 hash: - md5: a1ca7ac59e74a41b71675f9293ae8dab - sha256: 1a9e8c5bdcd2b579bd89e0130540cd411a7e9e02115b1b05b3567d9ecfcc99b9 + md5: 91f08ed9ff25a969ddd06237454dae0d + sha256: 9f61fd45d0c9d27bd5e2bf4eeb3662d97691dc7d08b4007060776ce91f1a0d35 category: main optional: false - name: certifi - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: linux-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.7.4-pyhd8ed1ab_0.conda hash: - md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a - sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 + md5: 24e7fd6ca65997938fff9e5ab6f653e4 + sha256: dd3577bb5275062c388c46b075dcb795f47f8dac561da7dd35fe504b936934e5 category: main optional: false - name: certifi - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: osx-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.7.4-pyhd8ed1ab_0.conda hash: - md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a - sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 + md5: 24e7fd6ca65997938fff9e5ab6f653e4 + sha256: dd3577bb5275062c388c46b075dcb795f47f8dac561da7dd35fe504b936934e5 category: main optional: false - name: certifi - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.7.4-pyhd8ed1ab_0.conda hash: - md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a - sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 + md5: 24e7fd6ca65997938fff9e5ab6f653e4 + sha256: dd3577bb5275062c388c46b075dcb795f47f8dac561da7dd35fe504b936934e5 category: main optional: false - name: certifi - version: 2024.6.2 + version: 2024.7.4 manager: conda platform: win-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.7.4-pyhd8ed1ab_0.conda hash: - md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a - sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 + md5: 24e7fd6ca65997938fff9e5ab6f653e4 + sha256: dd3577bb5275062c388c46b075dcb795f47f8dac561da7dd35fe504b936934e5 category: main optional: false - name: cffi - version: 1.16.0 + version: 1.17.0 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libffi: '>=3.4,<4.0a0' libgcc-ng: '>=12' pycparser: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py38h6d47a40_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.0-py38heb5c249_0.conda hash: - md5: fc010dfb8ce6540d289436fbba499ee7 - sha256: ec0a62d4836d3ec2321d07cffa5aeef37c6818c6cce6383dc6be7205d09551b3 + md5: b41a6ee3a5b044185b5f46aaf6082388 + sha256: 04f394dbebcf09f845b95e63691aa20d8fc0e65cc94c78eb334c184335788cf8 category: main optional: false - name: cffi - version: 1.16.0 + version: 1.17.0 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libffi: '>=3.4,<4.0a0' pycparser: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py38h082e395_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.17.0-py38hc8bcfa4_0.conda hash: - md5: 046fe2a8edb11f1b8a7d3bd8e2fd1de7 - sha256: c79e5074c663670f75258f6fce8ebd0e65042bd22ecbb4979294c57ff4fa8fc5 + md5: d2a8f77ea8b928779611d1072e9ff89d + sha256: dfa9d415301f9431bc298869687d76abbeded8aff27a258ce28acaf175a47e1e category: main optional: false - name: cffi - version: 1.16.0 + version: 1.17.0 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' libffi: '>=3.4,<4.0a0' pycparser: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py38h73f40f7_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.17.0-py38h858044d_0.conda hash: - md5: 02911ce6163d7a3e8fe9d9398fb9986d - sha256: 375e0be4068f4b00facfa569aa26c92ed87858f45be875f2c4bf90f33733f4de + md5: 792d275788105bf78189bb55dc1e9c76 + sha256: c3c1486d52eac829dfca9d7d3d5596fea66e52dccc9b33d5d7b9acee276935af category: main optional: false - name: cffi - version: 1.16.0 + version: 1.17.0 manager: conda platform: win-64 dependencies: @@ -2737,10 +2799,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/cffi-1.16.0-py38h91455d4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.0-py38h4cb3324_0.conda hash: - md5: e9b2ac14b9c3d3eaeb2f69745e021e49 - sha256: 0704377274cfe0b3a5c308facecdeaaf2207303ee847842a4bbd3f70b7331ddc + md5: da2c9ba02e759024e994d0ecce7c860b + sha256: 09e73cc77c995d608647cf0e999790155c6adfd69554b148550d6acd8dc5fefc category: main optional: false - name: cfitsio @@ -2940,8 +3002,8 @@ package: manager: conda platform: osx-arm64 dependencies: - click: '>=3.0' python: '' + click: '>=3.0' url: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 hash: md5: 4fd2c6b53934bd7d96d1f3fdaf99b79f @@ -2992,8 +3054,8 @@ package: manager: conda platform: osx-arm64 dependencies: - click: '>=4.0' python: <4.0 + click: '>=4.0' url: https://conda.anaconda.org/conda-forge/noarch/cligj-0.7.2-pyhd8ed1ab_1.tar.bz2 hash: md5: a29b7c141d6b2de4bb67788a5f107734 @@ -3435,50 +3497,53 @@ package: category: main optional: false - name: debugpy - version: 1.8.1 + version: 1.8.5 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.1-py38h17151c0_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.5-py38h6d02427_0.conda hash: - md5: 5e76a89e52b7a304a3b8262169c37158 - sha256: b4ac0468f5856bee38bf89beef594f8b2ced255baead4ae4bb7cecaca02cfadb + md5: 41aaa2fe5a415fbf79ce09b0e2746320 + sha256: d985494382d0d2fa676a6bb0dc463b92aca84ddce720c299d5ed97d4c98cf938 category: main optional: false - name: debugpy - version: 1.8.1 + version: 1.8.5 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' libcxx: '>=16' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.1-py38h1f5f77c_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/debugpy-1.8.5-py38h8949568_0.conda hash: - md5: 330e7bdce942d7228484a73b926c1441 - sha256: aa6a0f3a79d1f428423ebe14e471d5d91079d96636c63bdec5942dc0f1e9868d + md5: 19bd309cc1b2132033d2e09f1e5267c8 + sha256: 76b11117f1b750b502e448ab64ca8d17135864e851d207b1f0afd15b4cfcfec0 category: main optional: false - name: debugpy - version: 1.8.1 + version: 1.8.5 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' libcxx: '>=16' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.1-py38hb9fa5a8_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/debugpy-1.8.5-py38h11842c7_0.conda hash: - md5: 7798cbde1099ac34325e9e5f8693613c - sha256: b967873a3ab27a81e254312ba034a77901710928c5ca894bfeea02ce6abf8d76 + md5: 4b9cccf16d79ee80988c217ef6ffaea6 + sha256: b7a062acc1d4eff83be4341ec738a435e67b4aab45d988ebba1f24e345131337 category: main optional: false - name: debugpy - version: 1.8.1 + version: 1.8.5 manager: conda platform: win-64 dependencies: @@ -3487,10 +3552,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.1-py38hd3f51b4_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.5-py38h2698bfa_0.conda hash: - md5: f411dc7f3c0ae3b8cc78ca8d179ba323 - sha256: 743d40284aca75e510cd816dd98f9596d6d2a74cdef1167ae20b2118ae7097e4 + md5: 92d3744401032b95411e55cf0f34dc1f + sha256: ac98f5168a08fdaac37be4315ede64597b5b46d167dc25384cb427498ea0eb60 category: main optional: false - name: decorator @@ -3668,8 +3733,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8.0,<4.0.0' sniffio: '' + python: '>=3.8.0,<4.0.0' url: https://conda.anaconda.org/conda-forge/noarch/dnspython-2.6.1-pyhd8ed1ab_1.conda hash: md5: 936e6aadb75534384d11d982fab74b61 @@ -3882,9 +3947,9 @@ package: manager: conda platform: osx-arm64 dependencies: - dnspython: '>=2.0.0' - idna: '>=2.0.0' python: '>=3.7' + idna: '>=2.0.0' + dnspython: '>=2.0.0' url: https://conda.anaconda.org/conda-forge/noarch/email-validator-2.2.0-pyhd8ed1ab_0.conda hash: md5: 3067adf57ee658ddf5bfad47b0041ce4 @@ -4106,51 +4171,51 @@ package: category: main optional: false - name: exceptiongroup - version: 1.2.0 + version: 1.2.2 manager: conda platform: linux-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda hash: - md5: 8d652ea2ee8eaee02ed8dc820bc794aa - sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d + md5: d02ae936e42063ca46af6cdad2dbd1e0 + sha256: e0edd30c4b7144406bb4da975e6bb97d6bc9c0e999aa4efe66ae108cada5d5b5 category: main optional: false - name: exceptiongroup - version: 1.2.0 + version: 1.2.2 manager: conda platform: osx-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda hash: - md5: 8d652ea2ee8eaee02ed8dc820bc794aa - sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d + md5: d02ae936e42063ca46af6cdad2dbd1e0 + sha256: e0edd30c4b7144406bb4da975e6bb97d6bc9c0e999aa4efe66ae108cada5d5b5 category: main optional: false - name: exceptiongroup - version: 1.2.0 + version: 1.2.2 manager: conda platform: osx-arm64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda hash: - md5: 8d652ea2ee8eaee02ed8dc820bc794aa - sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d + md5: d02ae936e42063ca46af6cdad2dbd1e0 + sha256: e0edd30c4b7144406bb4da975e6bb97d6bc9c0e999aa4efe66ae108cada5d5b5 category: main optional: false - name: exceptiongroup - version: 1.2.0 + version: 1.2.2 manager: conda platform: win-64 dependencies: python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda + url: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda hash: - md5: 8d652ea2ee8eaee02ed8dc820bc794aa - sha256: a6ae416383bda0e3ed14eaa187c653e22bec94ff2aa3b56970cdf0032761e80d + md5: d02ae936e42063ca46af6cdad2dbd1e0 + sha256: e0edd30c4b7144406bb4da975e6bb97d6bc9c0e999aa4efe66ae108cada5d5b5 category: main optional: false - name: executing @@ -4251,30 +4316,28 @@ package: category: main optional: false - name: fastapi - version: 0.111.0 + version: 0.112.0 manager: conda platform: linux-64 dependencies: email_validator: '>=2.0.0' - fastapi-cli: '>=0.0.2' + fastapi-cli: '>=0.0.5' httpx: '>=0.23.0' jinja2: '>=2.11.2' - orjson: '>=3.2.1' pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' python: '>=3.8' python-multipart: '>=0.0.7' starlette: '>=0.37.2,<0.38.0' typing-extensions: '>=4.8.0' - ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' uvicorn: '>=0.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.112.0-pyhd8ed1ab_0.conda hash: - md5: 7d347962e391cffc68f922c344f7cb3c - sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + md5: 8cb038d7fa460efb26ef62098edbe652 + sha256: 84b31c42b73264049b0cc6acd9bccc967c0826dae262401eda0e7c4c111add2f category: main optional: false - name: fastapi - version: 0.111.0 + version: 0.112.0 manager: conda platform: osx-64 dependencies: @@ -4283,44 +4346,40 @@ package: python-multipart: '>=0.0.7' typing-extensions: '>=4.8.0' pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' - starlette: '>=0.37.2,<0.38.0' jinja2: '>=2.11.2' + starlette: '>=0.37.2,<0.38.0' uvicorn: '>=0.12.0' email_validator: '>=2.0.0' - fastapi-cli: '>=0.0.2' - orjson: '>=3.2.1' - ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + fastapi-cli: '>=0.0.5' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.112.0-pyhd8ed1ab_0.conda hash: - md5: 7d347962e391cffc68f922c344f7cb3c - sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + md5: 8cb038d7fa460efb26ef62098edbe652 + sha256: 84b31c42b73264049b0cc6acd9bccc967c0826dae262401eda0e7c4c111add2f category: main optional: false - name: fastapi - version: 0.111.0 + version: 0.112.0 manager: conda platform: osx-arm64 dependencies: - email_validator: '>=2.0.0' - fastapi-cli: '>=0.0.2' - httpx: '>=0.23.0' - jinja2: '>=2.11.2' - orjson: '>=3.2.1' - pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' python: '>=3.8' + httpx: '>=0.23.0' python-multipart: '>=0.0.7' - starlette: '>=0.37.2,<0.38.0' typing-extensions: '>=4.8.0' - ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' + pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' + jinja2: '>=2.11.2' + starlette: '>=0.37.2,<0.38.0' uvicorn: '>=0.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + email_validator: '>=2.0.0' + fastapi-cli: '>=0.0.5' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.112.0-pyhd8ed1ab_0.conda hash: - md5: 7d347962e391cffc68f922c344f7cb3c - sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + md5: 8cb038d7fa460efb26ef62098edbe652 + sha256: 84b31c42b73264049b0cc6acd9bccc967c0826dae262401eda0e7c4c111add2f category: main optional: false - name: fastapi - version: 0.111.0 + version: 0.112.0 manager: conda platform: win-64 dependencies: @@ -4329,21 +4388,19 @@ package: python-multipart: '>=0.0.7' typing-extensions: '>=4.8.0' pydantic: '>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0' - starlette: '>=0.37.2,<0.38.0' jinja2: '>=2.11.2' + starlette: '>=0.37.2,<0.38.0' uvicorn: '>=0.12.0' email_validator: '>=2.0.0' - fastapi-cli: '>=0.0.2' - orjson: '>=3.2.1' - ujson: '>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.111.0-pyhd8ed1ab_0.conda + fastapi-cli: '>=0.0.5' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-0.112.0-pyhd8ed1ab_0.conda hash: - md5: 7d347962e391cffc68f922c344f7cb3c - sha256: 98cc823775b794b6ce45f02af5e4b711065ed0787c8eaec027434dabdb308bf7 + md5: 8cb038d7fa460efb26ef62098edbe652 + sha256: 84b31c42b73264049b0cc6acd9bccc967c0826dae262401eda0e7c4c111add2f category: main optional: false - name: fastapi-cli - version: 0.0.4 + version: 0.0.5 manager: conda platform: linux-64 dependencies: @@ -4351,14 +4408,14 @@ package: python: '>=3.8' typer: '>=0.12.3' uvicorn: '>=0.15.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.5-pyhd8ed1ab_0.conda hash: - md5: 2581ef67574e5b5400c0c151cc1c8b15 - sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + md5: d50cd55f356225d8440741bb911c2a78 + sha256: 72a8b8f55420207086cacf15066e234556669b4f3d6f5f8555a93a0013ed9bc9 category: main optional: false - name: fastapi-cli - version: 0.0.4 + version: 0.0.5 manager: conda platform: osx-64 dependencies: @@ -4366,29 +4423,29 @@ package: python: '>=3.8' uvicorn: '>=0.15.0' typer: '>=0.12.3' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.5-pyhd8ed1ab_0.conda hash: - md5: 2581ef67574e5b5400c0c151cc1c8b15 - sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + md5: d50cd55f356225d8440741bb911c2a78 + sha256: 72a8b8f55420207086cacf15066e234556669b4f3d6f5f8555a93a0013ed9bc9 category: main optional: false - name: fastapi-cli - version: 0.0.4 + version: 0.0.5 manager: conda platform: osx-arm64 dependencies: fastapi: '' python: '>=3.8' - typer: '>=0.12.3' uvicorn: '>=0.15.0' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + typer: '>=0.12.3' + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.5-pyhd8ed1ab_0.conda hash: - md5: 2581ef67574e5b5400c0c151cc1c8b15 - sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + md5: d50cd55f356225d8440741bb911c2a78 + sha256: 72a8b8f55420207086cacf15066e234556669b4f3d6f5f8555a93a0013ed9bc9 category: main optional: false - name: fastapi-cli - version: 0.0.4 + version: 0.0.5 manager: conda platform: win-64 dependencies: @@ -4396,10 +4453,10 @@ package: python: '>=3.8' uvicorn: '>=0.15.0' typer: '>=0.12.3' - url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/fastapi-cli-0.0.5-pyhd8ed1ab_0.conda hash: - md5: 2581ef67574e5b5400c0c151cc1c8b15 - sha256: 1b812ecef00b17b9b2714c4ea72de0272e817b95475b18af5400b26a6e571e71 + md5: d50cd55f356225d8440741bb911c2a78 + sha256: 72a8b8f55420207086cacf15066e234556669b4f3d6f5f8555a93a0013ed9bc9 category: main optional: false - name: ffmpeg @@ -4720,12 +4777,12 @@ package: manager: conda platform: osx-arm64 dependencies: - branca: '>=0.6.0' - jinja2: '>=2.9' numpy: '' - python: '>=3.8' requests: '' xyzservices: '' + python: '>=3.8' + jinja2: '>=2.9' + branca: '>=0.6.0' url: https://conda.anaconda.org/conda-forge/noarch/folium-0.17.0-pyhd8ed1ab_0.conda hash: md5: 9b96a3e6e0473b5722fa4fbefcefcded @@ -5070,10 +5127,10 @@ package: manager: conda platform: osx-arm64 dependencies: - font-ttf-dejavu-sans-mono: '' font-ttf-inconsolata: '' font-ttf-source-code-pro: '' font-ttf-ubuntu: '' + font-ttf-dejavu-sans-mono: '' url: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 hash: md5: f766549260d6815b0c52253f1fb1bb29 @@ -5096,24 +5153,25 @@ package: category: main optional: false - name: fonttools - version: 4.53.0 + version: 4.53.1 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' brotli: '' libgcc-ng: '>=12' munkres: '' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.0-py38hfb59056_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.1-py38h2019614_0.conda hash: - md5: 521c0726875843ca5c7224c6134c1750 - sha256: c8de15a92018b1fc9a1b3da1467736f0a97a4b06e555f309672b4141de50758f + md5: ab278a88d5031ff24b684d5a01f8b046 + sha256: a34be39303e4027e2ad0748d299f07d6e32b8a7015e53f14d70df6458b0ad261 category: main optional: false - name: fonttools - version: 4.53.0 + version: 4.53.1 manager: conda platform: osx-64 dependencies: @@ -5123,14 +5181,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.0-py38hc718529_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.1-py38hc718529_0.conda hash: - md5: ee68cefbf0ea3272d8161ed391cae81c - sha256: 71d61b872cee2f80c4f439b653a330814962ef6802f73b68ba1f0d6852c4e287 + md5: 176d3c2bdef6516ef46034486d4766cf + sha256: c7b112c048d1329151e086ca815b6a040ca0578a7145ec5e92647dbf5b82f510 category: main optional: false - name: fonttools - version: 4.53.0 + version: 4.53.1 manager: conda platform: osx-arm64 dependencies: @@ -5140,14 +5198,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* unicodedata2: '>=14.0.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.0-py38h3237794_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.1-py38h3237794_0.conda hash: - md5: 73832ed97fd30d0d7ca00128e386511c - sha256: 20bda6d44636e9a2263c199d690d8d18fad57b9ad1c9f1b3292f30c5b65cf38c + md5: 758043697c28d1e5b4955edc9236a8d8 + sha256: 52280a32c8756f1c5f115208c3c253597a7c0ed20bae3763dfcf31360c64a1b4 category: main optional: false - name: fonttools - version: 4.53.0 + version: 4.53.1 manager: conda platform: win-64 dependencies: @@ -5159,10 +5217,10 @@ package: unicodedata2: '>=14.0.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.0-py38h4cb3324_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.1-py38h4cb3324_0.conda hash: - md5: 1f605daf43f19302f8e347f3fce32b98 - sha256: bbe1e465ba56da6dea5e391a4c7f000b45547781b5d8701bebdf510c54ee122b + md5: e473a00fc836ecadce40a4918f50f61d + sha256: 96bc8f94c16cb59abbbd0fff7b92e184d3b28af8e36ad6a89a248d3e46d41e03 category: main optional: false - name: fqdn @@ -5586,14 +5644,14 @@ package: manager: conda platform: osx-arm64 dependencies: - fiona: '>=1.8.19' - folium: '' - geopandas-base: 0.13.2 - mapclassify: '>=2.4.0' matplotlib-base: '' - python: '>=3.8' rtree: '' + folium: '' xyzservices: '' + python: '>=3.8' + mapclassify: '>=2.4.0' + fiona: '>=1.8.19' + geopandas-base: 0.13.2 url: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.13.2-pyhd8ed1ab_1.conda hash: md5: 47226a55e4ae3bc9feb3a17925874817 @@ -5657,10 +5715,10 @@ package: platform: osx-arm64 dependencies: packaging: '' - pandas: '>=1.1.0' - pyproj: '>=3.0.1' python: '>=3.8' + pandas: '>=1.1.0' shapely: '>=1.7.1' + pyproj: '>=3.0.1' url: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.13.2-pyha770c72_1.conda hash: md5: c6036236caae7d8ac684c41c64073b9e @@ -6067,14 +6125,14 @@ package: category: main optional: false - name: git - version: 2.45.2 + version: 2.46.0 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/git-2.45.2-h57928b3_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/git-2.46.0-h57928b3_0.conda hash: - md5: 92dba9a3e8b104b54d08b3f3ed4700d2 - sha256: 87e76594216c26d1cb34bd011f8170d1a3b4269a3ae510776baf7edaf718b493 + md5: 7e8d2ae27a5e6fa1619bf78af7d658b3 + sha256: 8fc8fe1322d89f8ce49acf77204525b12a65029aad94512c0b7aa21c957ffef3 category: main optional: false - name: gl2ps @@ -6082,13 +6140,13 @@ package: manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=9.3.0' - libpng: '>=1.6.37,<1.7.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/gl2ps-1.4.2-h0708190_0.tar.bz2 + libgcc-ng: '>=12' + libpng: '>=1.6.43,<1.7.0a0' + libzlib: '>=1.3.1,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/gl2ps-1.4.2-hae5d5c5_1.conda hash: - md5: 438718bf8921ac70956d919d0e2cc487 - sha256: feaf757731cfb8231d8a6c5b3446bbc428aa1cca126f09628ccafaa98a80f022 + md5: 00e642ec191a19bf806a3915800e9524 + sha256: 68f071ea25e79ee427c0d6c35ccc137d66f093a37660a4e41bafe0c49d64f2d6 category: main optional: false - name: gl2ps @@ -6096,12 +6154,13 @@ package: manager: conda platform: osx-64 dependencies: - libpng: '>=1.6.37,<1.7.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/gl2ps-1.4.2-h4cff582_0.tar.bz2 + __osx: '>=10.13' + libpng: '>=1.6.43,<1.7.0a0' + libzlib: '>=1.3.1,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-64/gl2ps-1.4.2-hd82a5f3_1.conda hash: - md5: a9e91533b95cd019d58f4b3ef9bbddf0 - sha256: 668be06fc02b924eaf6c4f37c760804a8ca76bd119b5caa6eca51d8e96e957b3 + md5: 707318c6171d4d8b07b51e0de03c7595 + sha256: 2da5a699a75a9366996d469e05bbf2014f62102b2da70607a2230f9031ca7f52 category: main optional: false - name: gl2ps @@ -6109,12 +6168,13 @@ package: manager: conda platform: osx-arm64 dependencies: - libpng: '>=1.6.37,<1.7.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/gl2ps-1.4.2-h17b34a0_0.tar.bz2 + __osx: '>=11.0' + libpng: '>=1.6.43,<1.7.0a0' + libzlib: '>=1.3.1,<2.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/gl2ps-1.4.2-hc97c1ff_1.conda hash: - md5: 7b95a5cd771dca1a83a15f0661da8df1 - sha256: 0049faca32d9c303f5d407ef6ed05f99f76c533f03ce303d9882e702cbb3c862 + md5: 8e790b98d38f4d56b64308c642dd5533 + sha256: b6088d2b1eccebc8adc1e6c36df0849b300d957cff3e6a33fc9081d2e9efaf22 category: main optional: false - name: gl2ps @@ -6122,15 +6182,14 @@ package: manager: conda platform: win-64 dependencies: - libpng: '>=1.6.43,<1.7.0a0' - libzlib: '>=1.3.1,<2.0a0' - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-had7236b_1.conda + libpng: '>=1.6.37,<1.7.0a0' + vc: '>=14.1,<15.0a0' + vs2015_runtime: '>=14.16.27012' + zlib: '>=1.2.11,<1.3.0a0' + url: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-h0597ee9_0.tar.bz2 hash: - md5: 033491c5cb1ce4e915238307f0136fa0 - sha256: 5a18f0aa963adb4402dbce93516f40756beaa206e82c56592aafb1eb88060ba5 + md5: 9f17f1b93f610b4bea2a256d528fe8f6 + sha256: 6d4f45a6c4021c439b846356effac330d01a95a606e2eab9b5bd0cbdb1875b64 category: main optional: false - name: glew @@ -6725,15 +6784,16 @@ package: category: main optional: false - name: gstreamer-orc - version: 0.4.38 + version: 0.4.39 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-orc-0.4.38-hd590300_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-orc-0.4.39-h4bc722e_0.conda hash: - md5: 0403d9bfababea7e9d65741144410a70 - sha256: 01911f9d0c6dd42df09852c1ff1028556101c3992a3a2521a5c896027e805823 + md5: bd4ba5baa12faaad5ba06d13ee440a04 + sha256: 30cff05b87f16bd02874fe97376bc3766aea70bf76ba4c0319fca4c3f539369a category: main optional: false - name: h11 @@ -6767,8 +6827,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3' typing_extensions: '' + python: '>=3' url: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b21ed0883505ba1910994f1df031a428 @@ -6821,9 +6881,9 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.6.1' hpack: '>=4.0,<5' hyperframe: '>=6.0,<7' - python: '>=3.6.1' url: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b748fbf7060927a6e82df7cb5ee8f097 @@ -6836,8 +6896,8 @@ package: platform: win-64 dependencies: python: '>=3.6.1' - hyperframe: '>=6.0,<7' hpack: '>=4.0,<5' + hyperframe: '>=6.0,<7' url: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 hash: md5: b748fbf7060927a6e82df7cb5ee8f097 @@ -7215,12 +7275,12 @@ package: manager: conda platform: osx-arm64 dependencies: - anyio: '>=3.0,<5.0' certifi: '' - h11: '>=0.13,<0.15' - h2: '>=3,<5' python: '>=3.8' sniffio: 1.* + h2: '>=3,<5' + anyio: '>=3.0,<5.0' + h11: '>=0.13,<0.15' url: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda hash: md5: a6b9a0158301e697e4d0a36a3d60e133 @@ -7324,8 +7384,8 @@ package: dependencies: certifi: '' idna: '' - anyio: '' sniffio: '' + anyio: '' python: '>=3.8' httpcore: 1.* url: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -7339,12 +7399,12 @@ package: manager: conda platform: osx-arm64 dependencies: - anyio: '' certifi: '' - httpcore: 1.* idna: '' - python: '>=3.8' sniffio: '' + anyio: '' + python: '>=3.8' + httpcore: 1.* url: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda hash: md5: 9f359af5a886fd6ca6b2b6ea02e58332 @@ -7358,8 +7418,8 @@ package: dependencies: certifi: '' idna: '' - anyio: '' sniffio: '' + anyio: '' python: '>=3.8' httpcore: 1.* url: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda @@ -7570,55 +7630,55 @@ package: category: main optional: false - name: importlib-metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.2.0-pyha770c72_0.conda hash: - md5: b9f5330c0853ccabc39a9878c6f1a2ab - sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 + md5: c261d14fc7f49cdd403868998a18c318 + sha256: 15dd2beba1c6f780fec6c5351bbce815d27a29561f422fe830133c995ef90b8a category: main optional: false - name: importlib-metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.2.0-pyha770c72_0.conda hash: - md5: b9f5330c0853ccabc39a9878c6f1a2ab - sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 + md5: c261d14fc7f49cdd403868998a18c318 + sha256: 15dd2beba1c6f780fec6c5351bbce815d27a29561f422fe830133c995ef90b8a category: main optional: false - name: importlib-metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.2.0-pyha770c72_0.conda hash: - md5: b9f5330c0853ccabc39a9878c6f1a2ab - sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 + md5: c261d14fc7f49cdd403868998a18c318 + sha256: 15dd2beba1c6f780fec6c5351bbce815d27a29561f422fe830133c995ef90b8a category: main optional: false - name: importlib-metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: win-64 dependencies: python: '>=3.8' zipp: '>=0.5' - url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.2.1-pyha770c72_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.2.0-pyha770c72_0.conda hash: - md5: b9f5330c0853ccabc39a9878c6f1a2ab - sha256: 21c0aed99d05658760c87dcb3fce6e1175966d1bc51b7c31981e779e90574d27 + md5: c261d14fc7f49cdd403868998a18c318 + sha256: 15dd2beba1c6f780fec6c5351bbce815d27a29561f422fe830133c995ef90b8a category: main optional: false - name: importlib-resources @@ -7652,8 +7712,8 @@ package: manager: conda platform: osx-arm64 dependencies: - importlib_resources: '>=6.4.0,<6.4.1.0a0' python: '>=3.8' + importlib_resources: '>=6.4.0,<6.4.1.0a0' url: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.4.0-pyhd8ed1ab_0.conda hash: md5: dcbadab7a68738a028e195ab68ab2d2e @@ -7674,51 +7734,51 @@ package: category: main optional: false - name: importlib_metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: linux-64 dependencies: - importlib-metadata: '>=7.2.1,<7.2.2.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda + importlib-metadata: '>=8.2.0,<8.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-8.2.0-hd8ed1ab_0.conda hash: - md5: d6c936d009aa63e5f82d216c95cdcaee - sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 + md5: 0fd030dce707a6654472cf7619b0b01b + sha256: 4a0eacc41786d97176fb53c19d25c4f9b8ab4c9a0ee1fd6f09bc13ca197c21d9 category: main optional: false - name: importlib_metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: osx-64 dependencies: - importlib-metadata: '>=7.2.1,<7.2.2.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda + importlib-metadata: '>=8.2.0,<8.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-8.2.0-hd8ed1ab_0.conda hash: - md5: d6c936d009aa63e5f82d216c95cdcaee - sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 + md5: 0fd030dce707a6654472cf7619b0b01b + sha256: 4a0eacc41786d97176fb53c19d25c4f9b8ab4c9a0ee1fd6f09bc13ca197c21d9 category: main optional: false - name: importlib_metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: osx-arm64 dependencies: - importlib-metadata: '>=7.2.1,<7.2.2.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda + importlib-metadata: '>=8.2.0,<8.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-8.2.0-hd8ed1ab_0.conda hash: - md5: d6c936d009aa63e5f82d216c95cdcaee - sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 + md5: 0fd030dce707a6654472cf7619b0b01b + sha256: 4a0eacc41786d97176fb53c19d25c4f9b8ab4c9a0ee1fd6f09bc13ca197c21d9 category: main optional: false - name: importlib_metadata - version: 7.2.1 + version: 8.2.0 manager: conda platform: win-64 dependencies: - importlib-metadata: '>=7.2.1,<7.2.2.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.2.1-hd8ed1ab_0.conda + importlib-metadata: '>=8.2.0,<8.2.1.0a0' + url: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-8.2.0-hd8ed1ab_0.conda hash: - md5: d6c936d009aa63e5f82d216c95cdcaee - sha256: 24520c5f12ce9b78beb97b4f815ca7b763518cc84136e12f6db10aa23f55d0f8 + md5: 0fd030dce707a6654472cf7619b0b01b + sha256: 4a0eacc41786d97176fb53c19d25c4f9b8ab4c9a0ee1fd6f09bc13ca197c21d9 category: main optional: false - name: importlib_resources @@ -7774,18 +7834,18 @@ package: category: main optional: false - name: intel-openmp - version: 2024.1.0 + version: 2024.2.0 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda + url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.0-h57928b3_980.conda hash: - md5: 35d7ea07ad6c878bd7240d2d6c1b8657 - sha256: 77465396f2636c8b3b3a587f1636ee35c17a73e2a2c7e0ea0957b05f84704cf3 + md5: 9c28c39e64871a0adef7d1195bd58655 + sha256: e3ddfb67e0a922868e68f83d0b56755ff1c280ffa959a0c5ee6a922aaf7022b0 category: main optional: false - name: ipykernel - version: 6.29.4 + version: 6.29.5 manager: conda platform: linux-64 dependencies: @@ -7803,14 +7863,14 @@ package: pyzmq: '>=24' tornado: '>=6.1' traitlets: '>=5.4.0' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh3099207_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh3099207_0.conda hash: - md5: 36baf4c745655019de1f29df2535a72b - sha256: 202ab54ddc21011bf7ed7c8fa705767c9e7735a52281b010516faf3924bf0584 + md5: b40131ab6a36ac2c09b7c57d4d3fbf99 + sha256: 33cfd339bb4efac56edf93474b37ddc049e08b1b4930cf036c893cc1f5a1f32a category: main optional: false - name: ipykernel - version: 6.29.4 + version: 6.29.5 manager: conda platform: osx-64 dependencies: @@ -7826,43 +7886,43 @@ package: ipython: '>=7.23.1' matplotlib-inline: '>=0.1' debugpy: '>=1.6.5' + pyzmq: '>=24' comm: '>=0.1.1' traitlets: '>=5.4.0' - pyzmq: '>=24' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda hash: - md5: 1e991f9ed4a81d3482d46edbeb54721a - sha256: 634d840cf7ab02a31b164f7eca0e855b2b9aa9b3aff52a64b758bbbaf44a31de + md5: 9eb15d654daa0ef5a98802f586bb4ffc + sha256: 072534d4d379225b2c3a4e38bc7730b65ae171ac7f0c2d401141043336e97980 category: main optional: false - name: ipykernel - version: 6.29.4 + version: 6.29.5 manager: conda platform: osx-arm64 dependencies: + packaging: '' + psutil: '' + nest-asyncio: '' __osx: '' appnope: '' - comm: '>=0.1.1' - debugpy: '>=1.6.5' - ipython: '>=7.23.1' + python: '>=3.8' + tornado: '>=6.1' jupyter_client: '>=6.1.12' jupyter_core: '>=4.12,!=5.0.*' + ipython: '>=7.23.1' matplotlib-inline: '>=0.1' - nest-asyncio: '' - packaging: '' - psutil: '' - python: '>=3.8' + debugpy: '>=1.6.5' pyzmq: '>=24' - tornado: '>=6.1' + comm: '>=0.1.1' traitlets: '>=5.4.0' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh57ce528_0.conda hash: - md5: 1e991f9ed4a81d3482d46edbeb54721a - sha256: 634d840cf7ab02a31b164f7eca0e855b2b9aa9b3aff52a64b758bbbaf44a31de + md5: 9eb15d654daa0ef5a98802f586bb4ffc + sha256: 072534d4d379225b2c3a4e38bc7730b65ae171ac7f0c2d401141043336e97980 category: main optional: false - name: ipykernel - version: 6.29.4 + version: 6.29.5 manager: conda platform: win-64 dependencies: @@ -7877,13 +7937,13 @@ package: ipython: '>=7.23.1' matplotlib-inline: '>=0.1' debugpy: '>=1.6.5' + pyzmq: '>=24' comm: '>=0.1.1' traitlets: '>=5.4.0' - pyzmq: '>=24' - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh4bbf305_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.5-pyh4bbf305_0.conda hash: - md5: 899877a9ae762c02f2142b0531bee6a4 - sha256: c97cda9457c782ef6e52ec45ce48bd4a36cfa6ae1546b1de99b5cedc467dc341 + md5: 18df5fc4944a679e085e0e8f31775fc8 + sha256: dc569094125127c0078aa536f78733f383dd7e09507277ef8bcd1789786e7086 category: main optional: false - name: ipython @@ -7925,8 +7985,8 @@ package: backcall: '' python: '>=3.8' pygments: '>=2.4.0' - traitlets: '>=5' jedi: '>=0.16' + traitlets: '>=5' pexpect: '>4.3' prompt_toolkit: '>=3.0.30,<3.1.0,!=3.0.37' url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.12.2-pyhd1c38e8_0.conda @@ -7940,20 +8000,20 @@ package: manager: conda platform: osx-arm64 dependencies: + typing_extensions: '' + decorator: '' __osx: '' + matplotlib-inline: '' + stack_data: '' + pickleshare: '' appnope: '' backcall: '' - decorator: '' + python: '>=3.8' + pygments: '>=2.4.0' jedi: '>=0.16' - matplotlib-inline: '' + traitlets: '>=5' pexpect: '>4.3' - pickleshare: '' prompt_toolkit: '>=3.0.30,<3.1.0,!=3.0.37' - pygments: '>=2.4.0' - python: '>=3.8' - stack_data: '' - traitlets: '>=5' - typing_extensions: '' url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.12.2-pyhd1c38e8_0.conda hash: md5: acc618532cbc899f5721cc96407b16cc @@ -7975,8 +8035,8 @@ package: backcall: '' python: '>=3.8' pygments: '>=2.4.0' - traitlets: '>=5' jedi: '>=0.16' + traitlets: '>=5' prompt_toolkit: '>=3.0.30,<3.1.0,!=3.0.37' url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.12.2-pyh08f2357_0.conda hash: @@ -8015,8 +8075,8 @@ package: manager: conda platform: osx-arm64 dependencies: - arrow: '>=0.15.0' python: '>=3.7' + arrow: '>=0.15.0' url: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 4cb68948e0b8429534380243d063a27a @@ -8083,8 +8143,8 @@ package: manager: conda platform: osx-arm64 dependencies: - parso: '>=0.8.3,<0.9.0' python: '>=3.6' + parso: '>=0.8.3,<0.9.0' url: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda hash: md5: 81a3be0b2023e1ea8555781f0ad904a2 @@ -8135,8 +8195,8 @@ package: manager: conda platform: osx-arm64 dependencies: - markupsafe: '>=2.0' python: '>=3.7' + markupsafe: '>=2.0' url: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.4-pyhd8ed1ab_0.conda hash: md5: 7b86ecb7d3557821c649b3c31e3eb9f2 @@ -8187,8 +8247,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.8' setuptools: '' + python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/joblib-1.4.2-pyhd8ed1ab_0.conda hash: md5: 25df261d4523d9f9783bcdb7208d872f @@ -8441,7 +8501,7 @@ package: category: main optional: false - name: jsonschema - version: 4.22.0 + version: 4.23.0 manager: conda platform: linux-64 dependencies: @@ -8452,14 +8512,14 @@ package: python: '>=3.8' referencing: '>=0.28.4' rpds-py: '>=0.7.1' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_0.conda hash: - md5: b9661a4b1200d6bc7d8a4cdafdc91468 - sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a + md5: da304c192ad59975202859b367d0f6a2 + sha256: 7d0c4c0346b26be9f220682b7c5c0d84606d48c6dbc36fc238e4452dda733aff category: main optional: false - name: jsonschema - version: 4.22.0 + version: 4.23.0 manager: conda platform: osx-64 dependencies: @@ -8470,32 +8530,32 @@ package: jsonschema-specifications: '>=2023.03.6' referencing: '>=0.28.4' rpds-py: '>=0.7.1' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_0.conda hash: - md5: b9661a4b1200d6bc7d8a4cdafdc91468 - sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a + md5: da304c192ad59975202859b367d0f6a2 + sha256: 7d0c4c0346b26be9f220682b7c5c0d84606d48c6dbc36fc238e4452dda733aff category: main optional: false - name: jsonschema - version: 4.22.0 + version: 4.23.0 manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' attrs: '>=22.2.0' importlib_resources: '>=1.4.0' - jsonschema-specifications: '>=2023.03.6' pkgutil-resolve-name: '>=1.3.10' - python: '>=3.8' + jsonschema-specifications: '>=2023.03.6' referencing: '>=0.28.4' rpds-py: '>=0.7.1' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_0.conda hash: - md5: b9661a4b1200d6bc7d8a4cdafdc91468 - sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a + md5: da304c192ad59975202859b367d0f6a2 + sha256: 7d0c4c0346b26be9f220682b7c5c0d84606d48c6dbc36fc238e4452dda733aff category: main optional: false - name: jsonschema - version: 4.22.0 + version: 4.23.0 manager: conda platform: win-64 dependencies: @@ -8506,10 +8566,10 @@ package: jsonschema-specifications: '>=2023.03.6' referencing: '>=0.28.4' rpds-py: '>=0.7.1' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.23.0-pyhd8ed1ab_0.conda hash: - md5: b9661a4b1200d6bc7d8a4cdafdc91468 - sha256: 57a466e8c42635d8e930fa065dc6e461f4215aa259ab03873eacb03ddaeefc8a + md5: da304c192ad59975202859b367d0f6a2 + sha256: 7d0c4c0346b26be9f220682b7c5c0d84606d48c6dbc36fc238e4452dda733aff category: main optional: false - name: jsonschema-specifications @@ -8545,8 +8605,8 @@ package: manager: conda platform: osx-arm64 dependencies: - importlib_resources: '>=1.4.0' python: '>=3.8' + importlib_resources: '>=1.4.0' referencing: '>=0.31.0' url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda hash: @@ -8569,7 +8629,7 @@ package: category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.22.0 + version: 4.23.0 manager: conda platform: linux-64 dependencies: @@ -8577,79 +8637,75 @@ package: idna: '' isoduration: '' jsonpointer: '>1.13' - jsonschema: '>=4.22.0,<4.22.1.0a0' - python: '' + jsonschema: '>=4.23.0,<4.23.1.0a0' rfc3339-validator: '' rfc3986-validator: '>0.1.0' uri-template: '' - webcolors: '>=1.11' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda + webcolors: '>=24.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.23.0-hd8ed1ab_0.conda hash: - md5: 32ab666927ee17b9468c2c72bbd7ba1b - sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d + md5: 16b37612b3a2fd77f409329e213b530c + sha256: 007a0a506a0d1805b099629cb0ee743ad0afe7d9749e57339f32c168119e0139 category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.22.0 + version: 4.23.0 manager: conda platform: osx-64 dependencies: - python: '' idna: '' rfc3339-validator: '' uri-template: '' fqdn: '' isoduration: '' jsonpointer: '>1.13' - webcolors: '>=1.11' rfc3986-validator: '>0.1.0' - jsonschema: '>=4.22.0,<4.22.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.23.0,<4.23.1.0a0' + webcolors: '>=24.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.23.0-hd8ed1ab_0.conda hash: - md5: 32ab666927ee17b9468c2c72bbd7ba1b - sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d + md5: 16b37612b3a2fd77f409329e213b530c + sha256: 007a0a506a0d1805b099629cb0ee743ad0afe7d9749e57339f32c168119e0139 category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.22.0 + version: 4.23.0 manager: conda platform: osx-arm64 dependencies: - fqdn: '' idna: '' + rfc3339-validator: '' + uri-template: '' + fqdn: '' isoduration: '' jsonpointer: '>1.13' - jsonschema: '>=4.22.0,<4.22.1.0a0' - python: '' - rfc3339-validator: '' rfc3986-validator: '>0.1.0' - uri-template: '' - webcolors: '>=1.11' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.23.0,<4.23.1.0a0' + webcolors: '>=24.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.23.0-hd8ed1ab_0.conda hash: - md5: 32ab666927ee17b9468c2c72bbd7ba1b - sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d + md5: 16b37612b3a2fd77f409329e213b530c + sha256: 007a0a506a0d1805b099629cb0ee743ad0afe7d9749e57339f32c168119e0139 category: main optional: false - name: jsonschema-with-format-nongpl - version: 4.22.0 + version: 4.23.0 manager: conda platform: win-64 dependencies: - python: '' idna: '' rfc3339-validator: '' uri-template: '' fqdn: '' isoduration: '' jsonpointer: '>1.13' - webcolors: '>=1.11' rfc3986-validator: '>0.1.0' - jsonschema: '>=4.22.0,<4.22.1.0a0' - url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda + jsonschema: '>=4.23.0,<4.23.1.0a0' + webcolors: '>=24.6.0' + url: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.23.0-hd8ed1ab_0.conda hash: - md5: 32ab666927ee17b9468c2c72bbd7ba1b - sha256: 3c98d791bebd477597fe083b3cec35132ac974c61ba1e481dc6c29fac78b419d + md5: 16b37612b3a2fd77f409329e213b530c + sha256: 007a0a506a0d1805b099629cb0ee743ad0afe7d9749e57339f32c168119e0139 category: main optional: false - name: jupyter-lsp @@ -8685,9 +8741,9 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' importlib-metadata: '>=4.8.3' jupyter_server: '>=1.1.2' - python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda hash: md5: 885867f6adab3d7ecdf8ab6ca0785f51 @@ -8736,8 +8792,8 @@ package: jupyter_core: '>=4.12,!=5.0.*' importlib_metadata: '>=4.8.3' traitlets: '>=5.3' - pyzmq: '>=23.0' tornado: '>=6.2' + pyzmq: '>=23.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: md5: 3cdbb2fa84490e5fd44c9f9806c0d292 @@ -8749,13 +8805,13 @@ package: manager: conda platform: osx-arm64 dependencies: - importlib_metadata: '>=4.8.3' - jupyter_core: '>=4.12,!=5.0.*' python: '>=3.8' python-dateutil: '>=2.8.2' - pyzmq: '>=23.0' - tornado: '>=6.2' + jupyter_core: '>=4.12,!=5.0.*' + importlib_metadata: '>=4.8.3' traitlets: '>=5.3' + tornado: '>=6.2' + pyzmq: '>=23.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: md5: 3cdbb2fa84490e5fd44c9f9806c0d292 @@ -8772,8 +8828,8 @@ package: jupyter_core: '>=4.12,!=5.0.*' importlib_metadata: '>=4.8.3' traitlets: '>=5.3' - pyzmq: '>=23.0' tornado: '>=6.2' + pyzmq: '>=23.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda hash: md5: 3cdbb2fa84490e5fd44c9f9806c0d292 @@ -8884,14 +8940,14 @@ package: manager: conda platform: osx-arm64 dependencies: - jsonschema-with-format-nongpl: '>=4.18.0' - python: '>=3.8' - python-json-logger: '>=2.0.4' - pyyaml: '>=5.3' referencing: '' rfc3339-validator: '' + python: '>=3.8' + pyyaml: '>=5.3' rfc3986-validator: '>=0.1.1' traitlets: '>=5.3' + python-json-logger: '>=2.0.4' + jsonschema-with-format-nongpl: '>=4.18.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda hash: md5: ed45423c41b3da15ea1df39b1f80c2ca @@ -8918,52 +8974,47 @@ package: category: main optional: false - name: jupyter_server - version: 2.14.1 + version: 2.14.2 manager: conda platform: linux-64 dependencies: anyio: '>=3.1.0' - argon2-cffi: '' - jinja2: '' + argon2-cffi: '>=21.1' + jinja2: '>=3.0.3' jupyter_client: '>=7.4.4' jupyter_core: '>=4.12,!=5.0.*' jupyter_events: '>=0.9.0' - jupyter_server_terminals: '' + jupyter_server_terminals: '>=0.4.4' nbconvert-core: '>=6.4.4' nbformat: '>=5.3.0' - overrides: '' - packaging: '' - prometheus_client: '' + overrides: '>=5.0' + packaging: '>=22.0' + prometheus_client: '>=0.9' python: '>=3.8' pyzmq: '>=24' send2trash: '>=1.8.2' terminado: '>=0.8.3' tornado: '>=6.2.0' traitlets: '>=5.6.0' - websocket-client: '' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda + websocket-client: '>=1.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.2-pyhd8ed1ab_0.conda hash: - md5: 174af03c6e6038edd32021a48aa003c4 - sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c + md5: ca23c71f70a7c7935b3d03f0f1a5801d + sha256: edab71a05feceac54bdb90e755a257545af7832b9911607c1a70f09be44ba985 category: main optional: false - name: jupyter_server - version: 2.14.1 + version: 2.14.2 manager: conda platform: osx-64 dependencies: - packaging: '' - jinja2: '' - prometheus_client: '' - websocket-client: '' - argon2-cffi: '' - overrides: '' - jupyter_server_terminals: '' python: '>=3.8' terminado: '>=0.8.3' jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' + jinja2: '>=3.0.3' pyzmq: '>=24' + packaging: '>=22.0' nbconvert-core: '>=6.4.4' jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' @@ -8971,10 +9022,15 @@ package: anyio: '>=3.1.0' send2trash: '>=1.8.2' jupyter_events: '>=0.9.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda + argon2-cffi: '>=21.1' + jupyter_server_terminals: '>=0.4.4' + overrides: '>=5.0' + prometheus_client: '>=0.9' + websocket-client: '>=1.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.2-pyhd8ed1ab_0.conda hash: - md5: 174af03c6e6038edd32021a48aa003c4 - sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c + md5: ca23c71f70a7c7935b3d03f0f1a5801d + sha256: edab71a05feceac54bdb90e755a257545af7832b9911607c1a70f09be44ba985 category: main optional: false - name: jupyter_server @@ -8982,25 +9038,25 @@ package: manager: conda platform: osx-arm64 dependencies: - anyio: '>=3.1.0,<4' - argon2-cffi: '' - jinja2: '' - jupyter_client: '>=7.4.4' - jupyter_core: '>=4.12,!=5.0.*' - jupyter_events: '>=0.4.0' - jupyter_server_terminals: '' - nbconvert-core: '>=6.4.4' - nbformat: '>=5.3.0' - overrides: '' packaging: '' + jinja2: '' prometheus_client: '' - python: '>=3.8' - pyzmq: '>=24' + websocket-client: '' + argon2-cffi: '' send2trash: '' + overrides: '' + jupyter_server_terminals: '' + python: '>=3.8' terminado: '>=0.8.3' + jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' + pyzmq: '>=24' + nbconvert-core: '>=6.4.4' + anyio: '>=3.1.0,<4' + jupyter_client: '>=7.4.4' + nbformat: '>=5.3.0' traitlets: '>=5.6.0' - websocket-client: '' + jupyter_events: '>=0.4.0' url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.7.0-pyhd8ed1ab_0.conda hash: md5: 7488cd1f4d35a2af96faa765b7e5b2f0 @@ -9008,22 +9064,17 @@ package: category: main optional: false - name: jupyter_server - version: 2.14.1 + version: 2.14.2 manager: conda platform: win-64 dependencies: - packaging: '' - jinja2: '' - prometheus_client: '' - websocket-client: '' - argon2-cffi: '' - overrides: '' - jupyter_server_terminals: '' python: '>=3.8' terminado: '>=0.8.3' jupyter_core: '>=4.12,!=5.0.*' tornado: '>=6.2.0' + jinja2: '>=3.0.3' pyzmq: '>=24' + packaging: '>=22.0' nbconvert-core: '>=6.4.4' jupyter_client: '>=7.4.4' nbformat: '>=5.3.0' @@ -9031,10 +9082,15 @@ package: anyio: '>=3.1.0' send2trash: '>=1.8.2' jupyter_events: '>=0.9.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda + argon2-cffi: '>=21.1' + jupyter_server_terminals: '>=0.4.4' + overrides: '>=5.0' + prometheus_client: '>=0.9' + websocket-client: '>=1.7' + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.2-pyhd8ed1ab_0.conda hash: - md5: 174af03c6e6038edd32021a48aa003c4 - sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c + md5: ca23c71f70a7c7935b3d03f0f1a5801d + sha256: edab71a05feceac54bdb90e755a257545af7832b9911607c1a70f09be44ba985 category: main optional: false - name: jupyter_server_terminals @@ -9090,7 +9146,7 @@ package: category: main optional: false - name: jupyterlab - version: 4.2.2 + version: 4.2.4 manager: conda platform: linux-64 dependencies: @@ -9111,14 +9167,14 @@ package: tomli: '>=1.2.2' tornado: '>=6.2.0' traitlets: '' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.4-pyhd8ed1ab_0.conda hash: - md5: 405a9d330af26391c8001d56b3ef4239 - sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 + md5: 28f3334e97c39de2b7ac15743b041784 + sha256: e3b585b55634da48871ed3082c429652a62bf0cf7733641b1382b9c314f1c901 category: main optional: false - name: jupyterlab - version: 4.2.2 + version: 4.2.4 manager: conda platform: osx-64 dependencies: @@ -9139,42 +9195,42 @@ package: httpx: '>=0.25.0' jupyterlab_server: '>=2.27.1,<3' ipykernel: '>=6.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.4-pyhd8ed1ab_0.conda hash: - md5: 405a9d330af26391c8001d56b3ef4239 - sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 + md5: 28f3334e97c39de2b7ac15743b041784 + sha256: e3b585b55634da48871ed3082c429652a62bf0cf7733641b1382b9c314f1c901 category: main optional: false - name: jupyterlab - version: 4.2.2 + version: 4.2.4 manager: conda platform: osx-arm64 dependencies: - async-lru: '>=1.0.0' - httpx: '>=0.25.0' + packaging: '' + traitlets: '' + jupyter_core: '' + python: '>=3.8' + tornado: '>=6.2.0' + tomli: '>=1.2.2' + jinja2: '>=3.0.3' importlib_metadata: '>=4.8.3' + jupyter_server: '>=2.4.0,<3' importlib_resources: '>=1.4' - ipykernel: '>=6.5.0' - jinja2: '>=3.0.3' jupyter-lsp: '>=2.0.0' - jupyter_core: '' - jupyter_server: '>=2.4.0,<3' - jupyterlab_server: '>=2.27.1,<3' + async-lru: '>=1.0.0' notebook-shim: '>=0.2' - packaging: '' - python: '>=3.8' setuptools: '>=40.1.0' - tomli: '>=1.2.2' - tornado: '>=6.2.0' - traitlets: '' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda + httpx: '>=0.25.0' + jupyterlab_server: '>=2.27.1,<3' + ipykernel: '>=6.5.0' + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.4-pyhd8ed1ab_0.conda hash: - md5: 405a9d330af26391c8001d56b3ef4239 - sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 + md5: 28f3334e97c39de2b7ac15743b041784 + sha256: e3b585b55634da48871ed3082c429652a62bf0cf7733641b1382b9c314f1c901 category: main optional: false - name: jupyterlab - version: 4.2.2 + version: 4.2.4 manager: conda platform: win-64 dependencies: @@ -9195,10 +9251,10 @@ package: httpx: '>=0.25.0' jupyterlab_server: '>=2.27.1,<3' ipykernel: '>=6.5.0' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.4-pyhd8ed1ab_0.conda hash: - md5: 405a9d330af26391c8001d56b3ef4239 - sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 + md5: 28f3334e97c39de2b7ac15743b041784 + sha256: e3b585b55634da48871ed3082c429652a62bf0cf7733641b1382b9c314f1c901 category: main optional: false - name: jupyterlab_pygments @@ -9232,8 +9288,8 @@ package: manager: conda platform: osx-arm64 dependencies: - pygments: '>=2.4.1,<3' python: '>=3.7' + pygments: '>=2.4.1,<3' url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda hash: md5: afcd1b53bcac8844540358e33f33d28f @@ -9254,7 +9310,7 @@ package: category: main optional: false - name: jupyterlab_server - version: 2.27.2 + version: 2.27.3 manager: conda platform: linux-64 dependencies: @@ -9267,14 +9323,14 @@ package: packaging: '>=21.3' python: '>=3.8' requests: '>=2.31' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_0.conda hash: - md5: d1cb7b113daaadd89e5aa6a32b28bf0d - sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 + md5: af8239bf1ba7e8c69b689f780f653488 + sha256: a23b26d1a35bccdb91b9232119e5f402624e1e1a252b0e64cc20c6eb5b87cefb category: main optional: false - name: jupyterlab_server - version: 2.27.2 + version: 2.27.3 manager: conda platform: osx-64 dependencies: @@ -9287,34 +9343,34 @@ package: babel: '>=2.10' json5: '>=0.9.0' jsonschema: '>=4.18' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_0.conda hash: - md5: d1cb7b113daaadd89e5aa6a32b28bf0d - sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 + md5: af8239bf1ba7e8c69b689f780f653488 + sha256: a23b26d1a35bccdb91b9232119e5f402624e1e1a252b0e64cc20c6eb5b87cefb category: main optional: false - name: jupyterlab_server - version: 2.27.2 + version: 2.27.3 manager: conda platform: osx-arm64 dependencies: - babel: '>=2.10' - importlib-metadata: '>=4.8.3' + python: '>=3.8' + packaging: '>=21.3' jinja2: '>=3.0.3' + importlib-metadata: '>=4.8.3' + requests: '>=2.31' + jupyter_server: '>=1.21,<3' + babel: '>=2.10' json5: '>=0.9.0' jsonschema: '>=4.18' - jupyter_server: '>=1.21,<3' - packaging: '>=21.3' - python: '>=3.8' - requests: '>=2.31' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_0.conda hash: - md5: d1cb7b113daaadd89e5aa6a32b28bf0d - sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 + md5: af8239bf1ba7e8c69b689f780f653488 + sha256: a23b26d1a35bccdb91b9232119e5f402624e1e1a252b0e64cc20c6eb5b87cefb category: main optional: false - name: jupyterlab_server - version: 2.27.2 + version: 2.27.3 manager: conda platform: win-64 dependencies: @@ -9322,15 +9378,15 @@ package: packaging: '>=21.3' jinja2: '>=3.0.3' importlib-metadata: '>=4.8.3' - jupyter_server: '>=1.21,<3' requests: '>=2.31' + jupyter_server: '>=1.21,<3' babel: '>=2.10' json5: '>=0.9.0' jsonschema: '>=4.18' - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.3-pyhd8ed1ab_0.conda hash: - md5: d1cb7b113daaadd89e5aa6a32b28bf0d - sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 + md5: af8239bf1ba7e8c69b689f780f653488 + sha256: a23b26d1a35bccdb91b9232119e5f402624e1e1a252b0e64cc20c6eb5b87cefb category: main optional: false - name: jxrlib @@ -10085,10 +10141,10 @@ package: platform: win-64 dependencies: mkl: 2024.1.0 - url: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-22_win64_mkl.conda + url: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-23_win64_mkl.conda hash: - md5: 65c56ecdeceffd6c32d3d54db7e02c6e - sha256: 4faab445cbd9a13736a206b98fde962d0a9fa80dcbd38300951a8b2863e7c35c + md5: 693407a31c27e70c750b5ae153251d9a + sha256: fd52eb0ec4d0ca5727317dd608c41dacc8ccfc7e21d943b7aafbbf10ae28c97c category: main optional: false - name: libbrotlicommon @@ -10298,10 +10354,10 @@ package: platform: win-64 dependencies: libblas: 3.9.0 - url: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-22_win64_mkl.conda + url: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-23_win64_mkl.conda hash: - md5: 336c93ab102846c6131cf68e722a68f1 - sha256: 5503273924650330dc03edd1eb01ec4020b9967b5a4cafc377ba20b976d15590 + md5: 7ffb5b336cefd2e6d1e00ac1f7c9f2c9 + sha256: 80b471a22affadc322006399209e1d12eb4ab4e3125ed6d01b4031e09de16753 category: main optional: false - name: libclang @@ -10542,27 +10598,27 @@ package: category: main optional: false - name: libcxx - version: 17.0.6 + version: 18.1.8 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' - url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-17.0.6-h88467a6_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-18.1.8-heced48a_2.conda hash: - md5: 0fe355aecb8d24b8bc07c763209adbd9 - sha256: e7b57062c1edfcbd13d2129467c94cbff7f0a988ee75782bf48b1dc0e6300b8b + md5: 8c8198f9e93fcc0fd359ff37b4a8cd2d + sha256: e4df0dfd5fcc1e4ece36fb6b09f44436584df961c5cdbf328581522ff8d033b6 category: main optional: false - name: libcxx - version: 17.0.6 + version: 18.1.8 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-17.0.6-h5f092b4_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-18.1.8-h5a72898_2.conda hash: - md5: a96fd5dda8ce56c86a971e0fa02751d0 - sha256: 119d3d9306f537d4c89dc99ed99b94c396d262f0b06f7833243646f68884f2c2 + md5: 2d8d36fada9497ebc35894189fb52b7a + sha256: ed8d2977f87ca6221d17eb1b9272db5766d86d51c7fcb6135e5cf81aee516c8f category: main optional: false - name: libdb @@ -10627,16 +10683,16 @@ package: category: main optional: false - name: libdrm - version: 2.4.121 + version: 2.4.122 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' libpciaccess: '>=0.18,<0.19.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.121-h4ab18f5_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.122-h4ab18f5_0.conda hash: - md5: 3bcee3436b1effa9a3caee2b74175c08 - sha256: ad6b2b83f53b1ff524e5cd9617674658d97bdfdf1c9a118c011dfaf1d6ac039b + md5: bbfc4dbe5e97b385ef088f354d65e563 + sha256: 74c59a29b76bafbb022389c7cfa9b33b8becd7879b2c6b25a1a99735bf4e9c81 category: main optional: false - name: libedit @@ -10870,29 +10926,29 @@ package: category: main optional: false - name: libgcc-ng - version: 13.2.0 + version: 14.1.0 manager: conda platform: linux-64 dependencies: _libgcc_mutex: '0.1' _openmp_mutex: '>=4.5' - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_13.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda hash: - md5: 9358cdd61ef0d600d2a0dde2d53b006c - sha256: ffa0f472c8b37f864de855af2d3c057f1813162319f10ebd97332d73fc27ba60 + md5: ca0fad6a41ddaef54a153b78eccb5037 + sha256: b8e869ac96591cda2704bf7e77a301025e405227791a0bddf14a3dac65125538 category: main optional: false - name: libgcrypt - version: 1.10.3 + version: 1.11.0 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' - libgpg-error: '>=1.47,<2.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.10.3-hd590300_0.conda + libgpg-error: '>=1.50,<2.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.11.0-h4ab18f5_1.conda hash: - md5: 32d16ad533c59bb0a3c5ffaf16110829 - sha256: d1bd47faa29fec7288c7b212198432b07f890d3d6f646078da93b059c2e9daff + md5: 14858a47d4cc995892e79f2b340682d7 + sha256: 9e97e4a753d2ee238cfc7375f0882830f0d8c1667431bc9d070a0f6718355570 category: main optional: false - name: libgdal @@ -11229,27 +11285,27 @@ package: category: main optional: false - name: libgfortran-ng - version: 13.2.0 + version: 14.1.0 manager: conda platform: linux-64 dependencies: - libgfortran5: 13.2.0 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_13.conda + libgfortran5: 14.1.0 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.1.0-h69a702a_0.conda hash: - md5: 516e66b26eea14e7e322fe99e88e0f02 - sha256: 3ef5d92510e9cdd70ec2a9f1f83b8c1d327ff0f9bfc17831a8f8f06f10c2085c + md5: f4ca84fbd6d06b0a052fb2d5b96dde41 + sha256: ef624dacacf97b2b0af39110b36e2fd3e39e358a1a6b7b21b85c9ac22d8ffed9 category: main optional: false - name: libgfortran5 - version: 13.2.0 + version: 14.1.0 manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=13.2.0' - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_13.conda + libgcc-ng: '>=14.1.0' + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.1.0-hc5f4f2c_0.conda hash: - md5: 1e380198685bc1e993bbbc4b579f5916 - sha256: 19cffb68b19ff5f426d1cb3db670dccb73c09f54b8d3f8e304665e2cee68f14f + md5: 6456c2620c990cd8dde2428a27ba0bc5 + sha256: a67d66b1e60a8a9a9e4440cee627c959acb4810cb182e089a4b0729bfdfbdf90 category: main optional: false - name: libgfortran5 @@ -11363,15 +11419,15 @@ package: category: main optional: false - name: libgomp - version: 13.2.0 + version: 14.1.0 manager: conda platform: linux-64 dependencies: _libgcc_mutex: '0.1' - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_13.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda hash: - md5: d370d1855cca14dff6a819c90c77497c - sha256: c5949bec7eee93cdd5c367e6e5c5e92ee1c5139a827567af23853dd52721d8ed + md5: ae061a5ed5f05818acdf9adab72c146d + sha256: 7699df61a1f6c644b3576a40f54791561f2845983120477a16116b951c9cdb05 category: main optional: false - name: libgoogle-cloud @@ -11450,7 +11506,7 @@ package: category: main optional: false - name: libgpg-error - version: '1.49' + version: '1.50' manager: conda platform: linux-64 dependencies: @@ -11459,10 +11515,10 @@ package: libgcc-ng: '>=12' libgettextpo: '>=0.22.5,<1.0a0' libstdcxx-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.49-h4f305b6_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.50-h4f305b6_0.conda hash: - md5: dfcfd72c7a430d3616763ecfbefe4ca9 - sha256: b2664c2c11211a63856f23278efb49d3e65d902297989a0c12dcd228b5d97110 + md5: 0d7ff1a8e69565ca3add6925e18e708f + sha256: c60969d5c315f33fee90a1f2dd5d169e2834ace5a55f5a6f822aa7485a3a84cc category: main optional: false - name: libgrpc @@ -11556,7 +11612,7 @@ package: category: main optional: false - name: libhwloc - version: 2.10.0 + version: 2.11.1 manager: conda platform: win-64 dependencies: @@ -11565,10 +11621,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.10.0-default_h8125262_1001.conda + url: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.1-default_h8125262_1000.conda hash: - md5: e761885eb4c181074d172220d46319a0 - sha256: 7f1aa1b071269df72e88297c046ec153b7f9a81e6f135d2da4401c96f41b5052 + md5: 933bad6e4658157f1aec9b171374fde2 + sha256: 92728e292640186759d6dddae3334a1bc0b139740b736ffaeccb825fb8c07a2e category: main optional: false - name: libiconv @@ -11739,15 +11795,16 @@ package: manager: conda platform: linux-64 dependencies: - libexpat: '>=2.5.0,<3.0a0' + __glibc: '>=2.17,<3.0.a0' + libexpat: '>=2.6.2,<3.0a0' libgcc-ng: '>=12' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<2.0.0a0' - uriparser: '>=0.9.7,<1.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-h01aab08_1016.conda + libzlib: '>=1.3.1,<2.0a0' + uriparser: '>=0.9.8,<1.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-hbbc8833_1020.conda hash: - md5: 4d0907546d556ef7f14b1dcfa0e217ce - sha256: 7e8f2e2bf09e9fae7c046b35545b3c71bebf4d87b38771cc7d058e83ae4b81cc + md5: 6d76c5822cb38bc1ab5a06565c6cf626 + sha256: 5bd19933cb3790ec8632c11fa67c25d82654bea6c2bc4f51f8bcd8b122ae96c8 category: main optional: false - name: libkml @@ -11755,14 +11812,15 @@ package: manager: conda platform: osx-64 dependencies: - libcxx: '>=15.0.7' - libexpat: '>=2.5.0,<3.0a0' - libzlib: '>=1.2.13,<2.0.0a0' - uriparser: '>=0.9.7,<1.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/libkml-1.3.0-hab3ca0e_1016.conda + __osx: '>=10.13' + libcxx: '>=16' + libexpat: '>=2.6.2,<3.0a0' + libzlib: '>=1.3.1,<2.0a0' + uriparser: '>=0.9.8,<1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-64/libkml-1.3.0-hfcbc525_1020.conda hash: - md5: e574fb1d20c56e9c5e2bd5c12de4f96e - sha256: d08ec8ff3e487701db7a504be814a665be9c7e4a5cfd8443c1444155979bd937 + md5: 055d429f351b79c0a7b7d7e39ff45b28 + sha256: 20dec455f668ab2527d6a20204599253ac0b2d4d0325e4a1ce2316850128cc3e category: main optional: false - name: libkml @@ -11770,14 +11828,15 @@ package: manager: conda platform: osx-arm64 dependencies: - libcxx: '>=15.0.7' - libexpat: '>=2.5.0,<3.0a0' - libzlib: '>=1.2.13,<2.0.0a0' - uriparser: '>=0.9.7,<1.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-h4f02115_1016.conda + __osx: '>=11.0' + libcxx: '>=16' + libexpat: '>=2.6.2,<3.0a0' + libzlib: '>=1.3.1,<2.0a0' + uriparser: '>=0.9.8,<1.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-h00ed6cc_1020.conda hash: - md5: 2b8a6724c0edf1c31b4c053154f4a759 - sha256: 89c2735bf520951874c492f28dca8c001c7b5a4885c35c1b0ad1f9bc7e6ab43a + md5: 628dcff1d0a6bb93fc114bf09dd65470 + sha256: 254156e86db817d7f312441837ebf3835b01d83e939e1ce54664dd160b6ad716 category: main optional: false - name: libkml @@ -11839,10 +11898,10 @@ package: platform: win-64 dependencies: libblas: 3.9.0 - url: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-22_win64_mkl.conda + url: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-23_win64_mkl.conda hash: - md5: c752cc2af9f3d8d7b2fdebb915a33ef7 - sha256: 8b28b361a13819ed83a67d3bfdde750a13bc8b50b9af26d94fd61616d0f2d703 + md5: 3580796ab7b7d68143f45d4d94d866b7 + sha256: 4f4738602d26935f4d4b0154fb23d48c276c87413c3a5e05274809abfcbe1273 category: main optional: false - name: libllvm13 @@ -12447,17 +12506,17 @@ package: manager: conda platform: osx-arm64 dependencies: - beautifulsoup4: '' - geopandas: '' - jinja2: '' - numpy: '>=1.3' + requests: '' packaging: '' - pandas: '>=1.4' + jinja2: '' + geopandas: '' + beautifulsoup4: '' platformdirs: '' python: '>=3.8' - requests: '' + pandas: '>=1.4' scipy: '>=1.8' shapely: '>=2.0' + numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/libpysal-4.8.0-pyhd8ed1ab_1.conda hash: md5: ea5d04d8018c1f2ba75a1fd3c30e830b @@ -12924,15 +12983,15 @@ package: category: main optional: false - name: libstdcxx-ng - version: 13.2.0 + version: 14.1.0 manager: conda platform: linux-64 dependencies: - libgcc-ng: 13.2.0 - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_13.conda + libgcc-ng: 14.1.0 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda hash: - md5: 1053882642ed5bbc799e1e866ff86826 - sha256: 143171c6084e526122cc2976fbbfadf7b9f50e5d13036adf20feb7ed9d036dd2 + md5: 1cb187a157136398ddbaae90713e2498 + sha256: 88c42b388202ffe16adaa337e36cf5022c63cf09b0405cf06fc6aeacccbe6146 category: main optional: false - name: libsystemd0 @@ -12992,15 +13051,13 @@ package: manager: conda platform: linux-64 dependencies: - libgcc-ng: '>=9.3.0' - libogg: '>=1.3.4,<1.4.0a0' - libpng: '>=1.6.37,<1.7.0a0' + libgcc-ng: '>=12' + libogg: '>=1.3.5,<1.4.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/libtheora-1.1.1-h7f98852_1005.tar.bz2 + url: https://conda.anaconda.org/conda-forge/linux-64/libtheora-1.1.1-h4ab18f5_1006.conda hash: - md5: 1a7c35f56343b7e9e8db20b296c7566c - sha256: 048ce34ba5b143f099cca3d388dfc41acf24d634dd00c5b1c463fb81bf804070 + md5: 553281a034e9cf8693c9df49f6c78ea1 + sha256: 50c8cd416ac8425e415264de167b41ae8442de22a91098dfdd993ddbf9f13067 category: main optional: false - name: libtheora @@ -13008,14 +13065,13 @@ package: manager: conda platform: osx-64 dependencies: - libogg: '>=1.3.4,<1.4.0a0' - libpng: '>=1.6.37,<1.7.0a0' + __osx: '>=10.13' + libogg: '>=1.3.5,<1.4.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/libtheora-1.1.1-h0d85af4_1005.tar.bz2 + url: https://conda.anaconda.org/conda-forge/osx-64/libtheora-1.1.1-hfdf4475_1006.conda hash: - md5: e63b84ed4c2d84901332de92a98a2f2b - sha256: 7a22ace7fb4c0b2a54c9e707c1894f889c9d2381cafbe0e6a75ad1d17340f8b9 + md5: fc8c11f9f4edda643302e28aa0999b90 + sha256: 72421637a05c2e99120d29a00951190644a4439c8155df9e8a8340983934db13 category: main optional: false - name: libtheora @@ -13023,14 +13079,13 @@ package: manager: conda platform: osx-arm64 dependencies: - libogg: '>=1.3.4,<1.4.0a0' - libpng: '>=1.6.37,<1.7.0a0' + __osx: '>=11.0' + libogg: '>=1.3.5,<1.4.0a0' libvorbis: '>=1.3.7,<1.4.0a0' - zlib: '>=1.2.11,<1.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libtheora-1.1.1-h3422bc3_1005.tar.bz2 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libtheora-1.1.1-h99b78c6_1006.conda hash: - md5: 04067d41a078006c97cdb4e14e22c639 - sha256: caabfd950cd42d3b395f7330f4b3516ff4300ef2077532f1420b4506f01b8f55 + md5: 4b0af7570b8af42ac6796da8777589d1 + sha256: 05d8f9a4ae6669ebf8d69ec7f62c47b197b885ff989641d8a8043a1159d50c22 category: main optional: false - name: libtheora @@ -13038,13 +13093,14 @@ package: manager: conda platform: win-64 dependencies: - libogg: '>=1.3.4,<1.4.0a0' - vc: '>=14.1,<15.0a0' - vs2015_runtime: '>=14.16.27012' - url: https://conda.anaconda.org/conda-forge/win-64/libtheora-1.1.1-h8d14728_1005.tar.bz2 + libogg: '>=1.3.5,<1.4.0a0' + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/libtheora-1.1.1-hc70643c_1006.conda hash: - md5: 8ad3f8ea1dbd5ac4fe1299a3250cbd1b - sha256: 41bed432fee99b129f95bcfe057296373098fdb06be763b40ae9baba554b2e64 + md5: 90cdca71edde0b3e549e8cbb43308208 + sha256: 7c4f8dca38604fa17d54061ff03f3e79aff78537a12e1eaf3b4a01be743b5633 category: main optional: false - name: libthrift @@ -13706,53 +13762,53 @@ package: category: main optional: false - name: libzlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda hash: - md5: 27329162c0dc732bcf67a4e0cd488125 - sha256: 8ced4afed6322172182af503f21725d072a589a6eb918f8a58135c1e00d35980 + md5: 57d7dc60e9325e3de37ff8dffd18e814 + sha256: adf6096f98b537a11ae3729eaa642b0811478f0ea0402ca67b5108fe2cb0010d category: main optional: false - name: libzlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' - url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h87427d6_6.conda + url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-h87427d6_1.conda hash: - md5: c0ef3c38a80c02ae1d86588c055184fc - sha256: 1c70fca0720685242b5c68956f310665c7ed43f04807aa4227322eee7925881c + md5: b7575b5aa92108dcc9aaab0f05f2dbce + sha256: 80a62db652b1da0ccc100812a1d86e94f75028968991bfb17f9536f3aa72d91d category: main optional: false - name: libzlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-hfb2fe0b_6.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-hfb2fe0b_1.conda hash: - md5: 9c4e121cd926cab631bd1c4a61d18b17 - sha256: 8b29a2386d99b8f58178951dcf19117b532cd9c4aa07623bf1667eae99755d32 + md5: 636077128927cf79fd933276dc3aed47 + sha256: c34365dd37b0eab27b9693af32a1f7f284955517c2cc91f1b88a7ef4738ff03e category: main optional: false - name: libzlib - version: 1.3.1 + version: 1.2.13 manager: conda platform: win-64 dependencies: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-h2466b09_6.conda hash: - md5: d4483ca8afc57ddf1f6dded53b36c17f - sha256: b13846a54a15243e15f96fec06b526d8155adc6a1ac2b6ed47a88f6a71a94b68 + md5: 9f41e3481778398837720a84dd26b7b1 + sha256: 97f47db85265b596d08c044b6533013b7286fb66259c77d04da76b74414c896e category: main optional: false - name: llvm-openmp @@ -14057,12 +14113,12 @@ package: manager: conda platform: osx-arm64 dependencies: + scikit-learn: '' networkx: '' - numpy: '>=1.3' - pandas: '>=1.0' python: '>=3.6' - scikit-learn: '' + pandas: '>=1.0' scipy: '>=1.0' + numpy: '>=1.3' url: https://conda.anaconda.org/conda-forge/noarch/mapclassify-2.5.0-pyhd8ed1ab_1.conda hash: md5: db1aeaff6e248db425e049feffded7a9 @@ -14117,8 +14173,8 @@ package: manager: conda platform: osx-arm64 dependencies: - mdurl: '>=0.1,<1' python: '>=3.8' + mdurl: '>=0.1,<1' url: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_0.conda hash: md5: 93a8e71256479c62074356ef6ebf501b @@ -14396,8 +14452,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.6' traitlets: '' + python: '>=3.6' url: https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_0.conda hash: md5: 779345c95648be40d22aaa89de7d4254 @@ -14554,10 +14610,10 @@ package: dependencies: intel-openmp: 2024.* tbb: 2021.* - url: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_692.conda + url: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda hash: - md5: b43ec7ed045323edeff31e348eea8652 - sha256: abfdb5eb3a17af59a827ea49fcb4d2bf18e70b62498bf3720351962e636cb5b7 + md5: a17423859d3fb912c8f2e9797603ddb6 + sha256: 4f86e9ad74a7792c836cd4cb7fc415bcdb50718ffbaa90c5571297f71764b980 category: main optional: false - name: mpfr @@ -14565,12 +14621,13 @@ package: manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' gmp: '>=6.3.0,<7.0a0' libgcc-ng: '>=12' - url: https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h9458935_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h38ae2d0_2.conda hash: - md5: 8083b20f566639c22f78bcd6ca35b276 - sha256: 38c501f6b8dff124e57711c01da23e204703a3c14276f4cf6abd28850b2b9893 + md5: 168e18a2bba4f8520e6c5e38982f5847 + sha256: 016981edf60146a6c553e22457ca3d121ff52b98d24b2191b82ef2aefa89cc7f category: main optional: false - name: mpfr @@ -14578,11 +14635,12 @@ package: manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' gmp: '>=6.3.0,<7.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/mpfr-4.2.1-h4f6b447_1.conda + url: https://conda.anaconda.org/conda-forge/osx-64/mpfr-4.2.1-hc80595b_2.conda hash: - md5: b90df08f0deb2f58631447c1462c92a7 - sha256: 002209e7d1f21cdd04de17050ab2050de4347e5bf04210ce6a636cbabf43e1d0 + md5: fc9b5179824146b67ad5a0b053b253ff + sha256: 24e27ad9a71f51d2858c72e7526a7aebec1a28524003fa79a9a5d682f0d5d125 category: main optional: false - name: mpfr @@ -14590,11 +14648,12 @@ package: manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' gmp: '>=6.3.0,<7.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-h41d338b_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-h1cfca0a_2.conda hash: - md5: 616d9bb6983991de582589b9a06e4cea - sha256: a0b183cdf8bd1f2462d965f7a065cbfc32669d95bb6c8f970f7c7f63d2938436 + md5: 56b5b819e0ad2c08a67e630211629896 + sha256: 4ed8519e032d1f5be5e5c1324d630aee13e81498b35999a4ff8bb7f38c3dc44e category: main optional: false - name: mpg123 @@ -15024,10 +15083,10 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' jupyter_client: '>=6.1.12' jupyter_core: '>=4.12,!=5.0.*' nbformat: '>=5.1' - python: '>=3.8' traitlets: '>=5.4' url: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda hash: @@ -15112,23 +15171,23 @@ package: manager: conda platform: osx-arm64 dependencies: + packaging: '' beautifulsoup4: '' - bleach: '' defusedxml: '' - entrypoints: '>=0.2.2' - jinja2: '>=3.0' - jupyter_core: '>=4.7' + bleach: '' + tinycss2: '' jupyterlab_pygments: '' + python: '>=3.8' + jinja2: '>=3.0' + entrypoints: '>=0.2.2' markupsafe: '>=2.0' - mistune: '>=2.0.3,<4' - nbclient: '>=0.5.0' - nbformat: '>=5.1' - packaging: '' + jupyter_core: '>=4.7' + traitlets: '>=5.0' pandocfilters: '>=1.4.1' + nbformat: '>=5.1' pygments: '>=2.4.1' - python: '>=3.8' - tinycss2: '' - traitlets: '>=5.0' + nbclient: '>=0.5.0' + mistune: '>=2.0.3,<4' url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda hash: md5: e2d2abb421c13456a9a9f80272fdf543 @@ -15200,11 +15259,11 @@ package: manager: conda platform: osx-arm64 dependencies: - jsonschema: '>=2.6' - jupyter_core: '>=4.12,!=5.0.*' python: '>=3.8' - python-fastjsonschema: '>=2.15' + jupyter_core: '>=4.12,!=5.0.*' traitlets: '>=5.1' + jsonschema: '>=2.6' + python-fastjsonschema: '>=2.15' url: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda hash: md5: 0b57b5368ab7fc7cdc9e3511fa867214 @@ -15491,14 +15550,14 @@ package: category: main optional: false - name: nodejs - version: 20.12.2 + version: 22.5.1 manager: conda platform: win-64 dependencies: {} - url: https://conda.anaconda.org/conda-forge/win-64/nodejs-20.12.2-h57928b3_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/nodejs-22.5.1-h57928b3_0.conda hash: - md5: 28d4536e0beff7b51232a5b16f9c3444 - sha256: 31b275bf914d57941e818b31f7ee8367c6c6a8532a2918639c87816bad1323af + md5: d2a82d7978da16598d53d2a254a46deb + sha256: 9fa72667f364172fbb256bdd373c80c514cf022c97fb2fde98808d5ab20f042b category: main optional: false - name: notebook @@ -15540,12 +15599,12 @@ package: manager: conda platform: osx-arm64 dependencies: - jupyter_server: '>=2.4.0,<3' - jupyterlab: '>=4.2.0,<4.3' - jupyterlab_server: '>=2.27.1,<3' - notebook-shim: '>=0.2,<0.3' python: '>=3.8' tornado: '>=6.2.0' + jupyter_server: '>=2.4.0,<3' + notebook-shim: '>=0.2,<0.3' + jupyterlab_server: '>=2.27.1,<3' + jupyterlab: '>=4.2.0,<4.3' url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda hash: md5: 08fa71a038c2cac2e636a5a456df15d5 @@ -15600,8 +15659,8 @@ package: manager: conda platform: osx-arm64 dependencies: - jupyter_server: '>=1.8,<3' python: '>=3.7' + jupyter_server: '>=1.8,<3' url: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda hash: md5: 3d85618e2c97ab896b5b5e298d32b5b3 @@ -15659,52 +15718,52 @@ package: category: main optional: false - name: nss - version: '3.100' + version: '3.103' manager: conda platform: linux-64 dependencies: __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' - libsqlite: '>=3.45.3,<4.0a0' + libsqlite: '>=3.46.0,<4.0a0' libstdcxx-ng: '>=12' - libzlib: '>=1.2.13,<2.0.0a0' + libzlib: '>=1.3.1,<2.0a0' nspr: '>=4.35,<5.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/nss-3.100-hca3bf56_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/nss-3.103-h593d115_0.conda hash: - md5: 949c4a82290ee58b3c970cef4bcfd4ad - sha256: a4146d2b6636999a21afcaf957029d066637bf26239fd3170242501e38fb1fa4 + md5: 233bfe41968d6fb04eba9258bb5061ad + sha256: f69c027c056a620f06b5f69c3c2a437cc8768bbcbe48664cfdb46ffee7d7753d category: main optional: false - name: nss - version: '3.100' + version: '3.103' manager: conda platform: osx-64 dependencies: __osx: '>=10.13' libcxx: '>=16' - libsqlite: '>=3.45.3,<4.0a0' - libzlib: '>=1.2.13,<2.0.0a0' + libsqlite: '>=3.46.0,<4.0a0' + libzlib: '>=1.3.1,<2.0a0' nspr: '>=4.35,<5.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/nss-3.100-h6606ded_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/nss-3.103-he7eb89d_0.conda hash: - md5: 614b1b9b0a0b1bfbfa9d04a10afa4240 - sha256: 694ab59a00e6ebb17816124d6d71dcb9b7bac1ad0d1963c918d58841cded51c8 + md5: 2a7c2b52e8157c187b5be0ed958a26db + sha256: c45b554bbe1b9e52e359845b587a69b35f33dc47ca45a6ce8f4aa44cbb3f5ded category: main optional: false - name: nss - version: '3.100' + version: '3.103' manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' libcxx: '>=16' - libsqlite: '>=3.45.3,<4.0a0' - libzlib: '>=1.2.13,<2.0.0a0' + libsqlite: '>=3.46.0,<4.0a0' + libzlib: '>=1.3.1,<2.0a0' nspr: '>=4.35,<5.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.100-hc6e9f88_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.103-hc42bcbf_0.conda hash: - md5: 5510f8855b43310ed7609395f8d777dd - sha256: e6da8091c7a522f0ce1ba363efd563de0c796d0b53a43d127af2e4cbe584ccbd + md5: 1c0c33f137496c66ea06ec800831ae24 + sha256: 248c55f84996f5b1241656f4d55bc060ec9396e0ed146a2c299acac4f5ae5300 category: main optional: false - name: numba @@ -15882,8 +15941,8 @@ package: manager: conda platform: osx-arm64 dependencies: - numpy: '>=1.15' python: '>=3.5' + numpy: '>=1.15' url: https://conda.anaconda.org/conda-forge/noarch/numpy-financial-1.0.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 3483f2da98bccd9363d09e1c9fee6f72 @@ -16337,61 +16396,6 @@ package: sha256: 05d5c8075c7b96868f056b6f38ffaf63bb9a119928f926f6913caade5b60db5e category: main optional: false -- name: orjson - version: 3.10.4 - manager: conda - platform: linux-64 - dependencies: - libgcc-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/orjson-3.10.4-py38h31a4407_0.conda - hash: - md5: 7567de9ac0921ede5354462e7f2d069c - sha256: 3f78982926735e2ab67a77efe22f0c4149f66f9f8edb8f82e8c4f5df54470297 - category: main - optional: false -- name: orjson - version: 3.10.4 - manager: conda - platform: osx-64 - dependencies: - __osx: '>=10.13' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/orjson-3.10.4-py38h2c15f49_0.conda - hash: - md5: bd899fa24071082e021593c95373b66d - sha256: ce5d9061d9f294c3cf3ac4b725b8f11c550f648244d47bcab0f3aa4d5dcf6f9e - category: main - optional: false -- name: orjson - version: 3.10.4 - manager: conda - platform: osx-arm64 - dependencies: - __osx: '>=11.0' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/orjson-3.10.4-py38h186058e_0.conda - hash: - md5: b946c628b49ef67d725a8606415e7a2d - sha256: fe728309cece3ba21aeff932750c05b252247c2df85c9074fa5f59fd605b56c6 - category: main - optional: false -- name: orjson - version: 3.10.4 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/win-64/orjson-3.10.4-py38h5267af6_0.conda - hash: - md5: 1aa711fd0fe698c9474c7f4a3a63138b - sha256: da67ff90d3dc76a5dac3e63e4cca264a77aa20a808f5dd83a2557702801d7d49 - category: main - optional: false - name: osmnx version: 1.8.1 manager: conda @@ -16445,18 +16449,18 @@ package: manager: conda platform: osx-arm64 dependencies: - folium: '' - gdal: '' - geopandas: '' - matplotlib-base: '' - networkx: '' numpy: '' - pandas: '' - python: '>=3.8' - rasterio: '' requests: '' - scikit-learn: '' + pandas: '' scipy: '' + matplotlib-base: '' + scikit-learn: '' + networkx: '' + geopandas: '' + rasterio: '' + gdal: '' + folium: '' + python: '>=3.8' shapely: '>=2.0' url: https://conda.anaconda.org/conda-forge/noarch/osmnx-1.8.1-pyhd8ed1ab_0.conda hash: @@ -16519,8 +16523,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.6' typing_utils: '' + python: '>=3.6' url: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda hash: md5: 24fba5a9d161ad8103d4e84c0e1a3ed4 @@ -16836,11 +16840,11 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' dill: '>=0.3.8' - multiprocess: '>=0.70.16' pox: '>=0.3.4' + multiprocess: '>=0.70.16' ppft: '>=1.7.6.8' - python: '>=3.8' url: https://conda.anaconda.org/conda-forge/noarch/pathos-0.3.2-pyhd8ed1ab_1.conda hash: md5: 22ed208c1b54e7c2ec6616665fba6b0f @@ -16896,9 +16900,9 @@ package: manager: conda platform: osx-arm64 dependencies: - numpy: '>=1.4.0' - python: '>=3.6' six: '' + python: '>=3.6' + numpy: '>=1.4.0' url: https://conda.anaconda.org/conda-forge/noarch/patsy-0.5.6-pyhd8ed1ab_0.conda hash: md5: a5b55d1cb110cdcedc748b5c3e16e687 @@ -17041,8 +17045,8 @@ package: manager: conda platform: osx-arm64 dependencies: - ptyprocess: '>=0.5' python: '>=3.7' + ptyprocess: '>=0.5' url: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda hash: md5: 629f3203c99b32e0988910c93e77f3b6 @@ -17190,59 +17194,59 @@ package: category: main optional: false - name: pip - version: '24.0' + version: '24.2' manager: conda platform: linux-64 dependencies: - python: '>=3.7' + python: '>=3.8' setuptools: '' wheel: '' - url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pip-24.2-pyhd8ed1ab_0.conda hash: - md5: f586ac1e56c8638b64f9c8122a7b8a67 - sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a + md5: 6721aef6bfe5937abe70181545dd2c51 + sha256: 15b480571a7a4d896aa187648cce99f98bac3926253f028f228d2e9e1cf7c1e1 category: main optional: false - name: pip - version: '24.0' + version: '24.2' manager: conda platform: osx-64 dependencies: setuptools: '' wheel: '' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pip-24.2-pyhd8ed1ab_0.conda hash: - md5: f586ac1e56c8638b64f9c8122a7b8a67 - sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a + md5: 6721aef6bfe5937abe70181545dd2c51 + sha256: 15b480571a7a4d896aa187648cce99f98bac3926253f028f228d2e9e1cf7c1e1 category: main optional: false - name: pip - version: '24.0' + version: '24.2' manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' setuptools: '' wheel: '' - url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pip-24.2-pyhd8ed1ab_0.conda hash: - md5: f586ac1e56c8638b64f9c8122a7b8a67 - sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a + md5: 6721aef6bfe5937abe70181545dd2c51 + sha256: 15b480571a7a4d896aa187648cce99f98bac3926253f028f228d2e9e1cf7c1e1 category: main optional: false - name: pip - version: '24.0' + version: '24.2' manager: conda platform: win-64 dependencies: setuptools: '' wheel: '' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda + python: '>=3.8' + url: https://conda.anaconda.org/conda-forge/noarch/pip-24.2-pyhd8ed1ab_0.conda hash: - md5: f586ac1e56c8638b64f9c8122a7b8a67 - sha256: b7c1c5d8f13e8cb491c4bd1d0d1896a4cf80fc47de01059ad77509112b664a4a + md5: 6721aef6bfe5937abe70181545dd2c51 + sha256: 15b480571a7a4d896aa187648cce99f98bac3926253f028f228d2e9e1cf7c1e1 category: main optional: false - name: pixman @@ -17393,59 +17397,59 @@ package: category: main optional: false - name: plotly - version: 5.22.0 + version: 5.23.0 manager: conda platform: linux-64 dependencies: packaging: '' python: '>=3.6' tenacity: '>=6.2.0' - url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.23.0-pyhd8ed1ab_0.conda hash: - md5: 5b409a5f738e7d76c2b426eddb7e9956 - sha256: 16cada008ce6bf231bcb00a9aca6bddd03d4d0f1f7f2cd83882aa0023845c33a + md5: 41e535b9e479c72a6bffc69a4c85837c + sha256: 1342268311791c6485f9e06d6f912412c954b09020bf6eb683b916f2b4c5a4a7 category: main optional: false - name: plotly - version: 5.22.0 + version: 5.23.0 manager: conda platform: osx-64 dependencies: packaging: '' python: '>=3.6' tenacity: '>=6.2.0' - url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.23.0-pyhd8ed1ab_0.conda hash: - md5: 5b409a5f738e7d76c2b426eddb7e9956 - sha256: 16cada008ce6bf231bcb00a9aca6bddd03d4d0f1f7f2cd83882aa0023845c33a + md5: 41e535b9e479c72a6bffc69a4c85837c + sha256: 1342268311791c6485f9e06d6f912412c954b09020bf6eb683b916f2b4c5a4a7 category: main optional: false - name: plotly - version: 5.22.0 + version: 5.23.0 manager: conda platform: osx-arm64 dependencies: packaging: '' python: '>=3.6' tenacity: '>=6.2.0' - url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.23.0-pyhd8ed1ab_0.conda hash: - md5: 5b409a5f738e7d76c2b426eddb7e9956 - sha256: 16cada008ce6bf231bcb00a9aca6bddd03d4d0f1f7f2cd83882aa0023845c33a + md5: 41e535b9e479c72a6bffc69a4c85837c + sha256: 1342268311791c6485f9e06d6f912412c954b09020bf6eb683b916f2b4c5a4a7 category: main optional: false - name: plotly - version: 5.22.0 + version: 5.23.0 manager: conda platform: win-64 dependencies: packaging: '' python: '>=3.6' tenacity: '>=6.2.0' - url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.22.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/plotly-5.23.0-pyhd8ed1ab_0.conda hash: - md5: 5b409a5f738e7d76c2b426eddb7e9956 - sha256: 16cada008ce6bf231bcb00a9aca6bddd03d4d0f1f7f2cd83882aa0023845c33a + md5: 41e535b9e479c72a6bffc69a4c85837c + sha256: 1342268311791c6485f9e06d6f912412c954b09020bf6eb683b916f2b4c5a4a7 category: main optional: false - name: ply @@ -17507,10 +17511,10 @@ package: manager: conda platform: osx-arm64 dependencies: - packaging: '>=20.0' - platformdirs: '>=2.5.0' python: '>=3.7' + packaging: '>=20.0' requests: '>=2.19.0' + platformdirs: '>=2.5.0' url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda hash: md5: 8dab97d8a9616e07d779782995710aed @@ -18017,8 +18021,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' wcwidth: '' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda hash: md5: 1247c861065d227781231950e14fe817 @@ -18345,51 +18349,51 @@ package: category: main optional: false - name: pure_eval - version: 0.2.2 + version: 0.2.3 manager: conda platform: linux-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda hash: - md5: 6784285c7e55cb7212efabc79e4c2883 - sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + md5: 0f051f09d992e0d08941706ad519ee0e + sha256: dcfcb3cee1ae0a89729601582cc3edea20ba13c9493967a03a693c67567af0c8 category: main optional: false - name: pure_eval - version: 0.2.2 + version: 0.2.3 manager: conda platform: osx-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda hash: - md5: 6784285c7e55cb7212efabc79e4c2883 - sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + md5: 0f051f09d992e0d08941706ad519ee0e + sha256: dcfcb3cee1ae0a89729601582cc3edea20ba13c9493967a03a693c67567af0c8 category: main optional: false - name: pure_eval - version: 0.2.2 + version: 0.2.3 manager: conda platform: osx-arm64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda hash: - md5: 6784285c7e55cb7212efabc79e4c2883 - sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + md5: 0f051f09d992e0d08941706ad519ee0e + sha256: dcfcb3cee1ae0a89729601582cc3edea20ba13c9493967a03a693c67567af0c8 category: main optional: false - name: pure_eval - version: 0.2.2 + version: 0.2.3 manager: conda platform: win-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda hash: - md5: 6784285c7e55cb7212efabc79e4c2883 - sha256: 72792f9fc2b1820e37cc57f84a27bc819c71088c3002ca6db05a2e56404f9d44 + md5: 0f051f09d992e0d08941706ad519ee0e + sha256: dcfcb3cee1ae0a89729601582cc3edea20ba13c9493967a03a693c67567af0c8 category: main optional: false - name: pvlib @@ -18443,18 +18447,18 @@ package: manager: conda platform: osx-arm64 dependencies: - ephem: '' + requests: '' h5py: '' + pytz: '' importlib-metadata: '' - numba: '>=0.17.0' - numpy: '>=1.17.3' - pandas: '>=1.3.0' pip: '' + statsmodels: '' + ephem: '' python: '>=3.8' - pytz: '' - requests: '' + numpy: '>=1.17.3' scipy: '>=1.6.0' - statsmodels: '' + pandas: '>=1.3.0' + numba: '>=0.17.0' url: https://conda.anaconda.org/conda-forge/noarch/pvlib-0.11.0-pyha770c72_0.conda hash: md5: c9f4459108b58bd349251f93ebd561cb @@ -18648,82 +18652,83 @@ package: category: main optional: false - name: pydantic - version: 2.7.4 + version: 2.8.2 manager: conda platform: linux-64 dependencies: annotated-types: '>=0.4.0' - pydantic-core: 2.18.4 + pydantic-core: 2.20.1 python: '>=3.7' typing-extensions: '>=4.6.1' - url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.8.2-pyhd8ed1ab_0.conda hash: - md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 - sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + md5: 539a038a24a959662df1fcaa2cfc5c3e + sha256: 5a877153f7eaaab9724db5b64366a35e346007c9c104c1d6a6042f83b2f4f0df category: main optional: false - name: pydantic - version: 2.7.4 + version: 2.8.2 manager: conda platform: osx-64 dependencies: python: '>=3.7' typing-extensions: '>=4.6.1' annotated-types: '>=0.4.0' - pydantic-core: 2.18.4 - url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + pydantic-core: 2.20.1 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.8.2-pyhd8ed1ab_0.conda hash: - md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 - sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + md5: 539a038a24a959662df1fcaa2cfc5c3e + sha256: 5a877153f7eaaab9724db5b64366a35e346007c9c104c1d6a6042f83b2f4f0df category: main optional: false - name: pydantic - version: 2.7.4 + version: 2.8.2 manager: conda platform: osx-arm64 dependencies: - annotated-types: '>=0.4.0' - pydantic-core: 2.18.4 python: '>=3.7' typing-extensions: '>=4.6.1' - url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + annotated-types: '>=0.4.0' + pydantic-core: 2.20.1 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.8.2-pyhd8ed1ab_0.conda hash: - md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 - sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + md5: 539a038a24a959662df1fcaa2cfc5c3e + sha256: 5a877153f7eaaab9724db5b64366a35e346007c9c104c1d6a6042f83b2f4f0df category: main optional: false - name: pydantic - version: 2.7.4 + version: 2.8.2 manager: conda platform: win-64 dependencies: python: '>=3.7' typing-extensions: '>=4.6.1' annotated-types: '>=0.4.0' - pydantic-core: 2.18.4 - url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + pydantic-core: 2.20.1 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.8.2-pyhd8ed1ab_0.conda hash: - md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 - sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + md5: 539a038a24a959662df1fcaa2cfc5c3e + sha256: 5a877153f7eaaab9724db5b64366a35e346007c9c104c1d6a6042f83b2f4f0df category: main optional: false - name: pydantic-core - version: 2.18.4 + version: 2.20.1 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing-extensions: '>=4.6.0,!=4.7.0' - url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.4-py38h31a4407_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.20.1-py38h4005ec7_0.conda hash: - md5: 70e3a9f41eed4af00034a0927c36d09a - sha256: a8f6fbce9f4ed00371a8beee8b2b18b931c76ed795435f4ae68e29b032dd7583 + md5: 7fcbd5ffc4f54bbc3e5e0f87726f8d87 + sha256: 0e44a7f67fb3fabfc70f92ec12e4ceebf8a57f2f650bb6b73e4e02552f0cba4d category: main optional: false - name: pydantic-core - version: 2.18.4 + version: 2.20.1 manager: conda platform: osx-64 dependencies: @@ -18731,14 +18736,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing-extensions: '>=4.6.0,!=4.7.0' - url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.4-py38h2c15f49_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.20.1-py38h2c15f49_0.conda hash: - md5: a309f1a13d51e35670e9f024933af351 - sha256: 88911f8585d7c31853a24859036c82270306e1c7db66115215ddf8ec7e735a6c + md5: 6744f04d74f6bd4d1f01c5e3d8779cd1 + sha256: 35bb3421abfb735ac0813cb78e8a7391d720055d53a17963a848f5fa9440107b category: main optional: false - name: pydantic-core - version: 2.18.4 + version: 2.20.1 manager: conda platform: osx-arm64 dependencies: @@ -18746,14 +18751,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing-extensions: '>=4.6.0,!=4.7.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.4-py38h186058e_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.20.1-py38h186058e_0.conda hash: - md5: 47c3a719453bcf59dae095c7e27855c0 - sha256: 16851b8531654aa58ea3bf164d129da834a77e80bf056af1d4e1063b88bae0aa + md5: 6e5b0db53c0e76baf85d1406597be936 + sha256: 28a23b50ae13f369b043683584785dc3f62622e2015137b17aa71da6b57644f9 category: main optional: false - name: pydantic-core - version: 2.18.4 + version: 2.20.1 manager: conda platform: win-64 dependencies: @@ -18763,10 +18768,66 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.4-py38h2e0ef18_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.20.1-py38h2e0ef18_0.conda + hash: + md5: b3b4f5276e0056e697c639dbf5f928ab + sha256: 3d30abcf2d780ce40f27b43045a24b35f7420ef01675c7c35e111804599c1501 + category: main + optional: false +- name: pydantic-settings + version: 2.4.0 + manager: conda + platform: linux-64 + dependencies: + pydantic: '>=2.7.0' + python: '>=3.8' + python-dotenv: '>=0.21.0' + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.4.0-pyhd8ed1ab_0.conda + hash: + md5: 2cf6370f63f9c77177498f2b7a4bf549 + sha256: d2d9c7981b281c1abd5c8ad0786c8645ac0ab228e7aaaf8fc63cf166d6c31878 + category: main + optional: false +- name: pydantic-settings + version: 2.4.0 + manager: conda + platform: osx-64 + dependencies: + python: '>=3.8' + python-dotenv: '>=0.21.0' + pydantic: '>=2.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.4.0-pyhd8ed1ab_0.conda + hash: + md5: 2cf6370f63f9c77177498f2b7a4bf549 + sha256: d2d9c7981b281c1abd5c8ad0786c8645ac0ab228e7aaaf8fc63cf166d6c31878 + category: main + optional: false +- name: pydantic-settings + version: 2.4.0 + manager: conda + platform: osx-arm64 + dependencies: + python: '>=3.8' + python-dotenv: '>=0.21.0' + pydantic: '>=2.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.4.0-pyhd8ed1ab_0.conda + hash: + md5: 2cf6370f63f9c77177498f2b7a4bf549 + sha256: d2d9c7981b281c1abd5c8ad0786c8645ac0ab228e7aaaf8fc63cf166d6c31878 + category: main + optional: false +- name: pydantic-settings + version: 2.4.0 + manager: conda + platform: win-64 + dependencies: + python: '>=3.8' + python-dotenv: '>=0.21.0' + pydantic: '>=2.7.0' + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-settings-2.4.0-pyhd8ed1ab_0.conda hash: - md5: 9e531114195444f790af7c877ae40bad - sha256: 60ff0f8f015195b479f0498d2fcb898c1d12837e9787c211e350151f21689ce2 + md5: 2cf6370f63f9c77177498f2b7a4bf549 + sha256: d2d9c7981b281c1abd5c8ad0786c8645ac0ab228e7aaaf8fc63cf166d6c31878 category: main optional: false - name: pygments @@ -19501,8 +19562,8 @@ package: manager: conda platform: osx-arm64 dependencies: - bidict: '>=0.21.0' python: '>=3.8' + bidict: '>=0.21.0' python-engineio: '>=4.8.0' url: https://conda.anaconda.org/conda-forge/noarch/python-socketio-5.11.3-pyhd8ed1ab_0.conda hash: @@ -19773,50 +19834,53 @@ package: category: main optional: false - name: pyyaml - version: 6.0.1 + version: 6.0.2 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yaml: '>=0.2.5,<0.3.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py38h01eb140_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py38h2019614_0.conda hash: - md5: 5f05353ae9a6c37e1b4aebc9f7834d23 - sha256: 7741529957e3b3428af73f003f043c9983ed672c69dc4aafef848b2583c4571b + md5: 47a3b59acbb1626316500e178e25b944 + sha256: d1ed7517fe3de38fe58b830294aa1129a5ced37db18cc8c8a558938f573e6af2 category: main optional: false - name: pyyaml - version: 6.0.1 + version: 6.0.2 manager: conda platform: osx-64 dependencies: + __osx: '>=10.13' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yaml: '>=0.2.5,<0.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py38hcafd530_1.conda + url: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.2-py38hc718529_0.conda hash: - md5: 17cfcfdd18fa2fe701ff68c9bbcea9a5 - sha256: cd1dceaa9bb8296ddea04cfb5e933bf5ab2b189c566bb55e1a3c9a38efffa82d + md5: 0a73cc4551ded3712d3035f2015a217a + sha256: b2ab34de09e383cc937d20baa1f89f4f3f87694dcaa5f7a988976385d8d50e04 category: main optional: false - name: pyyaml - version: 6.0.1 + version: 6.0.2 manager: conda platform: osx-arm64 dependencies: + __osx: '>=11.0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yaml: '>=0.2.5,<0.3.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py38hb192615_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.2-py38h3237794_0.conda hash: - md5: 72ee6bc5ee0182fb7c5f26461504cbf5 - sha256: a4bcd94eda8611ade946a52cb52cf60ca6aa4d69915a9c68a9d9b7cbf02e4ac0 + md5: 51dad04e9f3b1b760b43d765f7137e35 + sha256: bc56d0a8f16006da98deb409fc00517f41b0a8068faa87dd9bd44d4fa6fbac86 category: main optional: false - name: pyyaml - version: 6.0.1 + version: 6.0.2 manager: conda platform: win-64 dependencies: @@ -19826,48 +19890,49 @@ package: vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' yaml: '>=0.2.5,<0.3.0a0' - url: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.1-py38h91455d4_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.2-py38h4cb3324_0.conda hash: - md5: 4d9ea280b4f91fa5b0c0d34f2fce99cb - sha256: 1cd8fe0f885c7e491b41e55611f546d011db8ac45941202eb2ef1549f6df0507 + md5: 4a62bed38f38a9aeecd2889ec9c48bb2 + sha256: ad8dfd7da1af2b8e6959c00e442b36db37e989e7150513de76567968ed145ca6 category: main optional: false - name: pyzmq - version: 26.0.3 + version: 26.1.0 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' libsodium: '>=1.0.18,<1.0.19.0a0' libstdcxx-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* zeromq: '>=4.3.5,<4.4.0a0' - url: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.0.3-py38ha44f8e3_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.1.0-py38hb4a53f8_0.conda hash: - md5: e56d476793b697ba90c56dfdcdd4d92c - sha256: b75d015730ee80c9f44ee2ccc8a865144f939e3ebbc566a8b32c1a9d91670bc0 + md5: e0c9bf189130f72516b59c59044ecede + sha256: 40a4cf95e96b2f637b18c2798a3b80cbda3d2c12f6e41ce7b1ec2713e6f4ae19 category: main optional: false - name: pyzmq - version: 26.0.3 + version: 26.1.0 manager: conda platform: osx-64 dependencies: - __osx: '>=10.9' + __osx: '>=10.13' libcxx: '>=16' libsodium: '>=1.0.18,<1.0.19.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* zeromq: '>=4.3.5,<4.4.0a0' - url: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-26.0.3-py38h80f5319_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-26.1.0-py38h123d167_0.conda hash: - md5: 140c393064918b2f861db6afa6c664ec - sha256: 8e0f9d099d990d6f79d6a9aa5fdfd1765600bbb07cd0dd0aafd70878707f4be2 + md5: 22566d7ef527040bc916a827ceb39bfe + sha256: b57b24f842c6cdd0694e5d6b91393badb2491bdf5dca6ef07cfbd3b3f10b9fb0 category: main optional: false - name: pyzmq - version: 26.0.3 + version: 26.1.0 manager: conda platform: osx-arm64 dependencies: @@ -19877,14 +19942,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* zeromq: '>=4.3.5,<4.4.0a0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-26.0.3-py38h0d2f7f4_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-26.1.0-py38h0d2f7f4_0.conda hash: - md5: bfd47d2cf85cdbe34f5c297ad17d7b64 - sha256: cd75235b328c4a1a047da3c811c8b9d00b71c91706e2c4d8f01d610c5df54661 + md5: 3bb17e869fa1b3738053e382b47d7592 + sha256: 817226230c012e23c75acc93c12823fbd752c241ee4ac9248a7dcd9509015339 category: main optional: false - name: pyzmq - version: 26.0.3 + version: 26.1.0 manager: conda platform: win-64 dependencies: @@ -19895,10 +19960,10 @@ package: vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' zeromq: '>=4.3.5,<4.3.6.0a0' - url: https://conda.anaconda.org/conda-forge/win-64/pyzmq-26.0.3-py38h3c56b06_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/pyzmq-26.1.0-py38h3c56b06_0.conda hash: - md5: 4b876a01672a8d6673679b8716b6eae9 - sha256: a55dd743205b40a6297a7439836a13027a07a06685597b75290541acc8ae7281 + md5: 87ec9559dd9511f5a22f99cbb861e3de + sha256: e6b1a94d1efe1d0987efb105e094c0068e7fea9552feebfab57b6def75857bd5 category: main optional: false - name: qt-main @@ -20323,8 +20388,8 @@ package: manager: conda platform: osx-arm64 dependencies: - attrs: '>=22.2.0' python: '>=3.8' + attrs: '>=22.2.0' rpds-py: '>=0.7.0' url: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda hash: @@ -20383,10 +20448,10 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' + idna: '>=2.5,<4' certifi: '>=2017.4.17' charset-normalizer: '>=2,<4' - idna: '>=2.5,<4' - python: '>=3.8' urllib3: '>=1.21.1,<3' url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda hash: @@ -20441,8 +20506,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.5' six: '' + python: '>=3.5' url: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 hash: md5: fed45fc5ea0813240707998abe49f520 @@ -20545,10 +20610,10 @@ package: manager: conda platform: osx-arm64 dependencies: - markdown-it-py: '>=2.2.0' - pygments: '>=2.13.0,<3.0.0' python: '>=3.7.0' typing_extensions: '>=4.0.0,<5.0.0' + pygments: '>=2.13.0,<3.0.0' + markdown-it-py: '>=2.2.0' url: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda hash: md5: ba445bf767ae6f0d959ff2b40c20912b @@ -20571,49 +20636,50 @@ package: category: main optional: false - name: rpds-py - version: 0.18.1 + version: 0.20.0 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.18.1-py38h31a4407_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.20.0-py38h4005ec7_0.conda hash: - md5: cf9114ac315a75ef2cbb68c4fcbb5559 - sha256: f892a7a48b54dc982f0921e6878c2feee5304726151075dca91aeab059652ad5 + md5: e18d1fb2fddcc693a91d7dc326916b2b + sha256: 348c5e6308dcf94d97bd99da41efeaac91529ff51f1e844d8544c2da20956c8e category: main optional: false - name: rpds-py - version: 0.18.1 + version: 0.20.0 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.18.1-py38h2c15f49_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.20.0-py38h2c15f49_0.conda hash: - md5: 208479e5daacf3cdeed1baf811b7b7d7 - sha256: 3f3ff557b564de1a81cc2e5c849887a9fb190dd417605ba154f5f2eb047da09b + md5: dc2e5e43d94bf656b56b5abe0756b697 + sha256: 645ba1cfea60d8d3094e92947e4ebfc9da9bff662676457623e625ec0d14d23f category: main optional: false - name: rpds-py - version: 0.18.1 + version: 0.20.0 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.18.1-py38h186058e_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.20.0-py38h186058e_0.conda hash: - md5: 49de491baa738aa885652276f228e6f5 - sha256: b3cbca052f28426d56cccbf1b0b92d074d6aa5a8801a20428f7e234a4acfd490 + md5: 997c7ac533c5e87819d2c269bb4bfaf3 + sha256: 7e60eb8a64590f28a03184f7465e3c7c261d4e895d0938f8ecb019000ead4cf6 category: main optional: false - name: rpds-py - version: 0.18.1 + version: 0.20.0 manager: conda platform: win-64 dependencies: @@ -20622,66 +20688,66 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.18.1-py38h2e0ef18_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.20.0-py38h2e0ef18_0.conda hash: - md5: 59e7e8163e8e8eff0d5d51591879e8d8 - sha256: 4e098feccfd60abb17f9f64fa21ea87db357907d5e16c03c347290da69a29e34 + md5: c9786281a438c8a5aa125759b037bdf0 + sha256: 2508c1c0f0db1b5730c53f32f70a045b43a004b51e4a4862ef00590dfab0c8dd category: main optional: false - name: rtree - version: 1.2.0 + version: 1.3.0 manager: conda platform: linux-64 dependencies: libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py38hcf07b61_1.conda + url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.3.0-py38h00415a3_1.conda hash: - md5: eba2af11ad65758b20ea379f925bebaa - sha256: f40795a4f818bcec13cb15a2b23f3014ec1d2d28f6cb8e94f2e76ed6579403eb + md5: c3f0e9a16c9871cfb50145721f50aae5 + sha256: e21e28ec755440f27f3b925ceed960a4002bd515436b58af7a52bd9e7e1ee527 category: main optional: false - name: rtree - version: 1.2.0 + version: 1.3.0 manager: conda platform: osx-64 dependencies: libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py38h2d351f8_1.conda + url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.3.0-py38h38b2175_1.conda hash: - md5: 00295fe0031c1b6160f96ed2fab4050c - sha256: e70e23345261a99fa0cb174dfdc04ffe76a76087f8f4be9fa7992a849d885516 + md5: 1e52389d18c16d618b1df74783dd7a3a + sha256: 7c57051d16ed40c6006351231dcd8e045442e0ba7d884fea10065b04552743a5 category: main optional: false - name: rtree - version: 1.2.0 + version: 1.3.0 manager: conda platform: osx-arm64 dependencies: libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py38h7841be0_1.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.3.0-py38h0d3ea80_1.conda hash: - md5: 0b91970b11d93f330b6b4d746d45bc84 - sha256: db3aeeaeac6dd03cb908a4240ab5d7f76f20e4e69e23a537e22e5bab106bdc00 + md5: a3c0400a1c5289fb24ad68e411373c6e + sha256: 76bfe260e4644ff53196f3fe4a002d8c9c0477c9e64d0b5dd0e27aa21d2f7745 category: main optional: false - name: rtree - version: 1.2.0 + version: 1.3.0 manager: conda platform: win-64 dependencies: libspatialindex: '>=2.0.0,<2.0.1.0a0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py38ha8ef549_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.3.0-py38hf7b70c9_1.conda hash: - md5: 87e570febe511a49a784797e0e44a68b - sha256: 40754ecf98cbd473fd589aa7a1aa9dc6b3304cbaa729c40a9add53770f871edc + md5: 477565b0444aaffbd7a773392450cbde + sha256: 2d6179f5269cb529451b2cc2c607236f75802f79bb75a195107bc11db945a9bb category: main optional: false - name: s2n @@ -20740,11 +20806,11 @@ package: dependencies: matplotlib-base: '' multiprocess: '' + python: '>=3.8' + scipy: '>=1.7.3' numpy: '>=1.20.3' pandas: '>=1.1.2' pathos: '>=0.2.5' - python: '>=3.8' - scipy: '>=1.7.3' url: https://conda.anaconda.org/conda-forge/noarch/salib-1.5.0-pyhd8ed1ab_0.conda hash: md5: 86437b51c934e7314e4e69f5c0b75332 @@ -20990,51 +21056,51 @@ package: category: main optional: false - name: setuptools - version: 70.1.0 + version: 72.1.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-72.1.0-pyhd8ed1ab_0.conda hash: - md5: 258e66f95f814d51ada2a1fe9274039b - sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 + md5: e06d4c26df4f958a8d38696f2c344d15 + sha256: d239e7f1b1a5617eeadda4e91183592f5a15219e97e16bc721d7b0597ee89a80 category: main optional: false - name: setuptools - version: 70.1.0 + version: 72.1.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-72.1.0-pyhd8ed1ab_0.conda hash: - md5: 258e66f95f814d51ada2a1fe9274039b - sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 + md5: e06d4c26df4f958a8d38696f2c344d15 + sha256: d239e7f1b1a5617eeadda4e91183592f5a15219e97e16bc721d7b0597ee89a80 category: main optional: false - name: setuptools - version: 70.1.0 + version: 72.1.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-72.1.0-pyhd8ed1ab_0.conda hash: - md5: 258e66f95f814d51ada2a1fe9274039b - sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 + md5: e06d4c26df4f958a8d38696f2c344d15 + sha256: d239e7f1b1a5617eeadda4e91183592f5a15219e97e16bc721d7b0597ee89a80 category: main optional: false - name: setuptools - version: 70.1.0 + version: 72.1.0 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.1.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-72.1.0-pyhd8ed1ab_0.conda hash: - md5: 258e66f95f814d51ada2a1fe9274039b - sha256: a43d33436f4ac57ebd6ee15f700b33b26a2d37b7e43981b1fa036908579dafd6 + md5: e06d4c26df4f958a8d38696f2c344d15 + sha256: d239e7f1b1a5617eeadda4e91183592f5a15219e97e16bc721d7b0597ee89a80 category: main optional: false - name: shapely @@ -21180,8 +21246,8 @@ package: manager: conda platform: osx-arm64 dependencies: - python: '>=3.7' wsproto: '' + python: '>=3.7' url: https://conda.anaconda.org/conda-forge/noarch/simple-websocket-1.0.0-pyhd8ed1ab_1.conda hash: md5: 4e9136be6c66312f63b3a8ef60443389 @@ -21392,11 +21458,11 @@ package: dependencies: numpy: '' pyparsing: '>=2.1.6' - python: '' - url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-pyhd8ed1ab_1.conda hash: - md5: cb83a3d6ecf73f50117635192414426a - sha256: ebb8f5f9e362f186fb7d732e656f85c969b86309494436eba51cc3b8b96683f7 + md5: 5abeaa41ec50d4d1421a8bc8fbc93054 + sha256: 4c2281d61c325f9208ce18e030efc94e44c9a4f0d28a6c5737ff79740e1db2d4 category: main optional: false - name: snuggs @@ -21404,13 +21470,13 @@ package: manager: conda platform: osx-64 dependencies: - python: '' numpy: '' + python: '>=3.6' pyparsing: '>=2.1.6' - url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-pyhd8ed1ab_1.conda hash: - md5: cb83a3d6ecf73f50117635192414426a - sha256: ebb8f5f9e362f186fb7d732e656f85c969b86309494436eba51cc3b8b96683f7 + md5: 5abeaa41ec50d4d1421a8bc8fbc93054 + sha256: 4c2281d61c325f9208ce18e030efc94e44c9a4f0d28a6c5737ff79740e1db2d4 category: main optional: false - name: snuggs @@ -21419,12 +21485,12 @@ package: platform: osx-arm64 dependencies: numpy: '' + python: '>=3.6' pyparsing: '>=2.1.6' - python: '' - url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-pyhd8ed1ab_1.conda hash: - md5: cb83a3d6ecf73f50117635192414426a - sha256: ebb8f5f9e362f186fb7d732e656f85c969b86309494436eba51cc3b8b96683f7 + md5: 5abeaa41ec50d4d1421a8bc8fbc93054 + sha256: 4c2281d61c325f9208ce18e030efc94e44c9a4f0d28a6c5737ff79740e1db2d4 category: main optional: false - name: snuggs @@ -21432,13 +21498,13 @@ package: manager: conda platform: win-64 dependencies: - python: '' numpy: '' + python: '>=3.6' pyparsing: '>=2.1.6' - url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 + url: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-pyhd8ed1ab_1.conda hash: - md5: cb83a3d6ecf73f50117635192414426a - sha256: ebb8f5f9e362f186fb7d732e656f85c969b86309494436eba51cc3b8b96683f7 + md5: 5abeaa41ec50d4d1421a8bc8fbc93054 + sha256: 4c2281d61c325f9208ce18e030efc94e44c9a4f0d28a6c5737ff79740e1db2d4 category: main optional: false - name: soupsieve @@ -21645,9 +21711,9 @@ package: manager: conda platform: osx-arm64 dependencies: - anyio: <5,>=3.4.0 python: '>=3.8' typing_extensions: '>=3.10.0' + anyio: <5,>=3.4.0 url: https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda hash: md5: 7e5550dfa3ed2c2019988cbb9f8302ea @@ -21832,8 +21898,8 @@ package: manager: conda platform: osx-arm64 dependencies: - pyparsing: '>=2.0.1' python: '>=3.6' + pyparsing: '>=2.0.1' url: https://conda.anaconda.org/conda-forge/noarch/svgwrite-1.4.3-pyhd8ed1ab_0.tar.bz2 hash: md5: 9d1eb6e4bf36cf72e0662ed9246f4e1b @@ -21945,14 +22011,14 @@ package: manager: conda platform: win-64 dependencies: - libhwloc: '>=2.10.0,<2.10.1.0a0' + libhwloc: '>=2.11.1,<2.11.2.0a0' ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_3.conda hash: - md5: e98333643abc739ebea1bac97a479828 - sha256: 87461c83a4f0d4f119af7368f20c47bbe0c27d963a7c22a3d08c71075077f855 + md5: a16e2a639e87c554abee5192ce6ee308 + sha256: 721a88d702e31efd9437d387774ef9157846743e66648f5f863b29ae322e8479 category: main optional: false - name: tbb-devel @@ -22002,58 +22068,58 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-hb551fcf_1.conda + url: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-h053bfa6_3.conda hash: - md5: ce48530b0800c691735f1b96c36cb842 - sha256: 0dac2867318c12575eb73e65aa9babd2fff1ec37068d0cc5d3fa942873af75bc + md5: 54ef2db0b2deac00879f51448e8439b5 + sha256: e81b7a997b74bd0f0b48623be7b201deca7a9d529348e1a313fdfcd4e35de2fa category: main optional: false - name: tenacity - version: 8.4.1 + version: 9.0.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda hash: - md5: 2fcb668e39c694ece9a7748e3fad1a7e - sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f + md5: 42af51ad3b654ece73572628ad2882ae + sha256: 0d33171e1d303b57867f0cfcffb8a35031700acb3c52b1862064d8f4e1085538 category: main optional: false - name: tenacity - version: 8.4.1 + version: 9.0.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda hash: - md5: 2fcb668e39c694ece9a7748e3fad1a7e - sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f + md5: 42af51ad3b654ece73572628ad2882ae + sha256: 0d33171e1d303b57867f0cfcffb8a35031700acb3c52b1862064d8f4e1085538 category: main optional: false - name: tenacity - version: 8.4.1 + version: 9.0.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda hash: - md5: 2fcb668e39c694ece9a7748e3fad1a7e - sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f + md5: 42af51ad3b654ece73572628ad2882ae + sha256: 0d33171e1d303b57867f0cfcffb8a35031700acb3c52b1862064d8f4e1085538 category: main optional: false - name: tenacity - version: 8.4.1 + version: 9.0.0 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/tenacity-8.4.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/tenacity-9.0.0-pyhd8ed1ab_0.conda hash: - md5: 2fcb668e39c694ece9a7748e3fad1a7e - sha256: aa0c9862d3c0e31fc2e37c7987fd82af538ce64064f2056d3105dcee070f531f + md5: 42af51ad3b654ece73572628ad2882ae + sha256: 0d33171e1d303b57867f0cfcffb8a35031700acb3c52b1862064d8f4e1085538 category: main optional: false - name: terminado @@ -22683,8 +22749,8 @@ package: manager: conda platform: osx-arm64 dependencies: - click: '>=8.0.0' python: '>=3.7' + click: '>=8.0.0' typing_extensions: '>=3.7.4.3' url: https://conda.anaconda.org/conda-forge/noarch/typer-slim-0.12.3-pyhd8ed1ab_0.conda hash: @@ -23048,67 +23114,6 @@ package: sha256: a62f3fb56849dc37270f9078e1c8ba32328bc3ba4d32cf1f7dace48b431d5abe category: main optional: false -- name: ujson - version: 5.10.0 - manager: conda - platform: linux-64 - dependencies: - libgcc-ng: '>=12' - libstdcxx-ng: '>=12' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/ujson-5.10.0-py38h854fd01_0.conda - hash: - md5: ae47f30506d4e23b6c93ed51ad12999e - sha256: eff2881d88f917cb74a05846013fe08653339c757d5bfc466cbb1079b1dade07 - category: main - optional: false -- name: ujson - version: 5.10.0 - manager: conda - platform: osx-64 - dependencies: - __osx: '>=10.13' - libcxx: '>=16' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/ujson-5.10.0-py38h8949568_0.conda - hash: - md5: df23dfb6607b809217ae8c76a1ac464e - sha256: 8bcd0b1c8558c39b2c76b8d27aab77849e3fc8ba3bb3f0811443db64665149ad - category: main - optional: false -- name: ujson - version: 5.10.0 - manager: conda - platform: osx-arm64 - dependencies: - __osx: '>=11.0' - libcxx: '>=16' - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/ujson-5.10.0-py38h11842c7_0.conda - hash: - md5: 05ad10c41bd72492bacf1f46247281f4 - sha256: 77a39c748699b79b562cb005b0a948f2ace23ad8fd27939f562aa6be90200272 - category: main - optional: false -- name: ujson - version: 5.10.0 - manager: conda - platform: win-64 - dependencies: - python: '>=3.8,<3.9.0a0' - python_abi: 3.8.* - ucrt: '>=10.0.20348.0' - vc: '>=14.2,<15' - vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/ujson-5.10.0-py38h2698bfa_0.conda - hash: - md5: a641eeaa10c7df169a04bf1a17e96350 - sha256: a0cdc93125fa4c13b520a08d9ebfd981237c348de80e099d4c9a765894703ad3 - category: main - optional: false - name: unicodedata2 version: 15.1.0 manager: conda @@ -23272,12 +23277,14 @@ package: platform: linux-64 dependencies: brotli-python: '>=1.0.9' + h2: '>=4,<5' pysocks: '>=1.5.6,<2.0,!=1.5.7' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda + python: '>=3.8' + zstandard: '>=0.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_1.conda hash: - md5: 92cdb6fe54b78739ad70637e4f0deb07 - sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 + md5: e804c43f58255e977093a2298e442bb8 + sha256: 00c47c602c03137e7396f904eccede8cc64cc6bad63ce1fc355125df8882a748 category: main optional: false - name: urllib3 @@ -23285,13 +23292,15 @@ package: manager: conda platform: osx-64 dependencies: - python: '>=3.7' + python: '>=3.8' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda + h2: '>=4,<5' + zstandard: '>=0.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_1.conda hash: - md5: 92cdb6fe54b78739ad70637e4f0deb07 - sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 + md5: e804c43f58255e977093a2298e442bb8 + sha256: 00c47c602c03137e7396f904eccede8cc64cc6bad63ce1fc355125df8882a748 category: main optional: false - name: urllib3 @@ -23299,13 +23308,15 @@ package: manager: conda platform: osx-arm64 dependencies: + python: '>=3.8' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda + h2: '>=4,<5' + zstandard: '>=0.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_1.conda hash: - md5: 92cdb6fe54b78739ad70637e4f0deb07 - sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 + md5: e804c43f58255e977093a2298e442bb8 + sha256: 00c47c602c03137e7396f904eccede8cc64cc6bad63ce1fc355125df8882a748 category: main optional: false - name: urllib3 @@ -23313,13 +23324,15 @@ package: manager: conda platform: win-64 dependencies: - python: '>=3.7' + python: '>=3.8' brotli-python: '>=1.0.9' pysocks: '>=1.5.6,<2.0,!=1.5.7' - url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_0.conda + h2: '>=4,<5' + zstandard: '>=0.18.0' + url: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.2-pyhd8ed1ab_1.conda hash: - md5: 92cdb6fe54b78739ad70637e4f0deb07 - sha256: 8cd972048f297b8e0601158ce352f5ca9510dda9f2706a46560220aa58b9f038 + md5: e804c43f58255e977093a2298e442bb8 + sha256: 00c47c602c03137e7396f904eccede8cc64cc6bad63ce1fc355125df8882a748 category: main optional: false - name: utfcpp @@ -23415,7 +23428,7 @@ package: category: main optional: false - name: uvicorn - version: 0.30.1 + version: 0.30.4 manager: conda platform: linux-64 dependencies: @@ -23424,14 +23437,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing_extensions: '>=4.0' - url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-0.30.1-py38h578d9bd_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-0.30.4-py38h578d9bd_0.conda hash: - md5: dc649127be96bd22e1b0ea884e427875 - sha256: 028ccb0830238f9b997c9658640dd1c77813a6972a1608ac95c9b02bc5d56dd3 + md5: c59df83d1e6cd77d5736ca1a182d9032 + sha256: 8e63a14010bd5bd56addf248f600fe22d59b1b58eca7f858c4dced06b1b9b70f category: main optional: false - name: uvicorn - version: 0.30.1 + version: 0.30.4 manager: conda platform: osx-64 dependencies: @@ -23440,14 +23453,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing_extensions: '>=4.0' - url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-0.30.1-py38h50d1736_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-0.30.4-py38h50d1736_0.conda hash: - md5: 2e1dfbcdd695053d338830b62ab12d15 - sha256: f45ce6c3a4582ab094ea0bc9f404c502dbb75faa2c2c429d2fcb8c87c9251aa0 + md5: d0a12310b3caf675ae08808c5c6b54e0 + sha256: 4c5b1db7e78434b040d47fc2cafb0f61a3aaf3466089c6ac764d050448229188 category: main optional: false - name: uvicorn - version: 0.30.1 + version: 0.30.4 manager: conda platform: osx-arm64 dependencies: @@ -23456,14 +23469,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing_extensions: '>=4.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-0.30.1-py38h10201cd_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-0.30.4-py38h10201cd_0.conda hash: - md5: 1323d54950e3e29fb41dd76e2dc06aeb - sha256: 90940b00808a3ab2c242673f682d0a9c1c3e48c1451119c518a301eec9125760 + md5: 0233e81ff5b7e646dfd953a52387230c + sha256: 16175761c1c0117dbef47f640af2cf2478af97856e1cc478d80736ebe8ed7f43 category: main optional: false - name: uvicorn - version: 0.30.1 + version: 0.30.4 manager: conda platform: win-64 dependencies: @@ -23472,14 +23485,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* typing_extensions: '>=4.0' - url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-0.30.1-py38haa244fe_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-0.30.4-py38haa244fe_0.conda hash: - md5: 223898c18ce5a4f87c46a3c797f58a9c - sha256: 5d51c3f48481aed643d592b2b15410344fbbe2e56ffe1d775330d2c61efe4869 + md5: d6f809e8dd84a0cd97779b4dd629b2a3 + sha256: 1c6778629d178bd7158b32a6a1706121028f8124544dc67bd887459c1c1d092f category: main optional: false - name: uvicorn-standard - version: 0.30.1 + version: 0.30.4 manager: conda platform: linux-64 dependencies: @@ -23487,18 +23500,18 @@ package: python-dotenv: '>=0.13' python_abi: 3.8.* pyyaml: '>=5.1' - uvicorn: 0.30.1 + uvicorn: 0.30.4 uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' watchfiles: '>=0.13' websockets: '>=10.4' - url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-standard-0.30.1-h578d9bd_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/uvicorn-standard-0.30.4-h578d9bd_0.conda hash: - md5: 878844f126b5cbe2708dfd70eb5242b1 - sha256: f56977cabd8966db28ab84cd38434b57ebd34d591dd06dd78a9ec402de28c02a + md5: ce29104e9017a93ea231deeb36e0bac5 + sha256: 999ce40d5fbaa6184ba6ad415cf638d8cde725b7a566665a76a072af83fdd9b8 category: main optional: false - name: uvicorn-standard - version: 0.30.1 + version: 0.30.4 manager: conda platform: osx-64 dependencies: @@ -23506,18 +23519,18 @@ package: python-dotenv: '>=0.13' python_abi: 3.8.* pyyaml: '>=5.1' - uvicorn: 0.30.1 + uvicorn: 0.30.4 uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' watchfiles: '>=0.13' websockets: '>=10.4' - url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-standard-0.30.1-h50d1736_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/uvicorn-standard-0.30.4-h50d1736_0.conda hash: - md5: 62f8229b71c9f2ffceb32c23fd7547b5 - sha256: a06b8a1aa5962e39bf7753178ce330b8da41b04dc9943097498f032d37022e29 + md5: f2ef2d5fd153086e01e25eae3d047e15 + sha256: c8fb52def77483f2a9774ca97a23925629b130942ae6cf71aa6a63f1a4090b19 category: main optional: false - name: uvicorn-standard - version: 0.30.1 + version: 0.30.4 manager: conda platform: osx-arm64 dependencies: @@ -23525,18 +23538,18 @@ package: python-dotenv: '>=0.13' python_abi: 3.8.* pyyaml: '>=5.1' - uvicorn: 0.30.1 + uvicorn: 0.30.4 uvloop: '>=0.14.0,!=0.15.0,!=0.15.1' watchfiles: '>=0.13' websockets: '>=10.4' - url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-standard-0.30.1-h150bfb4_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/uvicorn-standard-0.30.4-h150bfb4_0.conda hash: - md5: 04998e379e5bb56396f2e28562431721 - sha256: 3e4ef8b2ba839dfa7f26a84893bdc0e16f27b2ac6dc9135cdbc18fab39b2c184 + md5: 5da9414680c3f371c10a7e42169ea8bf + sha256: d5398c8f9f9e6319fee5f8259b2b85db9da169f28b1e03e64681ac2be8620033 category: main optional: false - name: uvicorn-standard - version: 0.30.1 + version: 0.30.4 manager: conda platform: win-64 dependencies: @@ -23545,13 +23558,13 @@ package: python-dotenv: '>=0.13' python_abi: 3.8.* pyyaml: '>=5.1' - uvicorn: 0.30.1 + uvicorn: 0.30.4 watchfiles: '>=0.13' websockets: '>=10.4' - url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-standard-0.30.1-haa244fe_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/uvicorn-standard-0.30.4-haa244fe_0.conda hash: - md5: ec7d831fa142c356abd6c8c9b6a2271c - sha256: 148498e9c6d06cab2231f90b7fd699c622dba9a3814915148e99d0cea91c917a + md5: 41acc9b4bc56d7b986f4e479fb0f00d1 + sha256: a66303c766b299fb382d00f9794b0fcfad04d3d4a003f9c02a660e92de7f8475 category: main optional: false - name: uvloop @@ -23821,22 +23834,23 @@ package: category: main optional: false - name: watchfiles - version: 0.22.0 + version: 0.23.0 manager: conda platform: linux-64 dependencies: + __glibc: '>=2.17,<3.0.a0' anyio: '>=3.0.0' libgcc-ng: '>=12' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-0.22.0-py38h31a4407_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/watchfiles-0.23.0-py38h4005ec7_0.conda hash: - md5: a0d8804ab4ab98e53675145913e7556a - sha256: e29a47a84379e0e3bfeea8e9551f0bea693b75c261615d130954e414485372a8 + md5: 73b5343525e212ebe0e0150fd0ffb92b + sha256: 1bb13fe77029035290d7876cbd6832e5eaf57d66aa1b84f89301fffd2b649243 category: main optional: false - name: watchfiles - version: 0.22.0 + version: 0.23.0 manager: conda platform: osx-64 dependencies: @@ -23844,14 +23858,14 @@ package: anyio: '>=3.0.0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-0.22.0-py38h2c15f49_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/watchfiles-0.23.0-py38h2c15f49_0.conda hash: - md5: ef538bcab09347480bf5aa7f9db3ab7d - sha256: 8713a1961cc63998f813e187672f3f01091a42c0f875e0492adcec21e4f3e8a5 + md5: c194be1e0f9e08763321cd77368f8c8a + sha256: 2478ea7e31ec2b2b3428216295b99be2c57a320bdbd3c16a3b29859238d753b2 category: main optional: false - name: watchfiles - version: 0.22.0 + version: 0.23.0 manager: conda platform: osx-arm64 dependencies: @@ -23859,14 +23873,14 @@ package: anyio: '>=3.0.0' python: '>=3.8,<3.9.0a0' python_abi: 3.8.* - url: https://conda.anaconda.org/conda-forge/osx-arm64/watchfiles-0.22.0-py38h186058e_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/watchfiles-0.23.0-py38h186058e_0.conda hash: - md5: 1e3e6cce6e9f3733fb278a80b7db1045 - sha256: a61266606f5b483f667adebe29a4f69ab7051a977d6d1cf14bd6d9ee73ab14b2 + md5: 44046a2f501be9fdaddc7c8ae3e94ac2 + sha256: f537d0f32bd19f418f9b5e0c890fbd495c60424edd4e32cdda0f3e1001ae4d6a category: main optional: false - name: watchfiles - version: 0.22.0 + version: 0.23.0 manager: conda platform: win-64 dependencies: @@ -23876,10 +23890,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/watchfiles-0.22.0-py38h2e0ef18_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/watchfiles-0.23.0-py38h2e0ef18_0.conda hash: - md5: a0138158474a4f73a6bd050039b70d99 - sha256: 85300ac98ba5e82efbbf145bfd3b4c7edea1dc85066f5df0ca640f7c730191c5 + md5: 0c9debb6724803a5a049ea60edf9601b + sha256: 3a91a6f921174fb3b0202e05c5e50116acd2f598514e0159f5a54985ae4a6fa4 category: main optional: false - name: wcwidth @@ -24131,51 +24145,51 @@ package: category: main optional: false - name: wheel - version: 0.43.0 + version: 0.44.0 manager: conda platform: linux-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.44.0-pyhd8ed1ab_0.conda hash: - md5: 0b5293a157c2b5cd513dd1b03d8d3aae - sha256: cb318f066afd6fd64619f14c030569faf3f53e6f50abf743b4c865e7d95b96bc + md5: d44e3b085abcaef02983c6305b84b584 + sha256: d828764736babb4322b8102094de38074dedfc71f5ff405c9dfee89191c14ebc category: main optional: false - name: wheel - version: 0.43.0 + version: 0.44.0 manager: conda platform: osx-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.44.0-pyhd8ed1ab_0.conda hash: - md5: 0b5293a157c2b5cd513dd1b03d8d3aae - sha256: cb318f066afd6fd64619f14c030569faf3f53e6f50abf743b4c865e7d95b96bc + md5: d44e3b085abcaef02983c6305b84b584 + sha256: d828764736babb4322b8102094de38074dedfc71f5ff405c9dfee89191c14ebc category: main optional: false - name: wheel - version: 0.43.0 + version: 0.44.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.44.0-pyhd8ed1ab_0.conda hash: - md5: 0b5293a157c2b5cd513dd1b03d8d3aae - sha256: cb318f066afd6fd64619f14c030569faf3f53e6f50abf743b4c865e7d95b96bc + md5: d44e3b085abcaef02983c6305b84b584 + sha256: d828764736babb4322b8102094de38074dedfc71f5ff405c9dfee89191c14ebc category: main optional: false - name: wheel - version: 0.43.0 + version: 0.44.0 manager: conda platform: win-64 dependencies: python: '>=3.8' - url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda + url: https://conda.anaconda.org/conda-forge/noarch/wheel-0.44.0-pyhd8ed1ab_0.conda hash: - md5: 0b5293a157c2b5cd513dd1b03d8d3aae - sha256: cb318f066afd6fd64619f14c030569faf3f53e6f50abf743b4c865e7d95b96bc + md5: d44e3b085abcaef02983c6305b84b584 + sha256: d828764736babb4322b8102094de38074dedfc71f5ff405c9dfee89191c14ebc category: main optional: false - name: win32_setctime @@ -24215,59 +24229,59 @@ package: category: main optional: false - name: wslink - version: 2.1.1 + version: 2.1.2 manager: conda platform: linux-64 dependencies: aiohttp: <4 msgpack-python: '>=1,<2' python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.2-pyhd8ed1ab_0.conda hash: - md5: 6b1aef9c878c58baa7bb9f0d44457174 - sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 + md5: 4cbb17383064ccfb46797aea03d70fc7 + sha256: db8236946b789bcc303c3f28fb1a3749fb9d694300faef9091299a4354759241 category: main optional: false - name: wslink - version: 2.1.1 + version: 2.1.2 manager: conda platform: osx-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.2-pyhd8ed1ab_0.conda hash: - md5: 6b1aef9c878c58baa7bb9f0d44457174 - sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 + md5: 4cbb17383064ccfb46797aea03d70fc7 + sha256: db8236946b789bcc303c3f28fb1a3749fb9d694300faef9091299a4354759241 category: main optional: false - name: wslink - version: 2.1.1 + version: 2.1.2 manager: conda platform: osx-arm64 dependencies: + python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - python: '>=3.7' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.2-pyhd8ed1ab_0.conda hash: - md5: 6b1aef9c878c58baa7bb9f0d44457174 - sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 + md5: 4cbb17383064ccfb46797aea03d70fc7 + sha256: db8236946b789bcc303c3f28fb1a3749fb9d694300faef9091299a4354759241 category: main optional: false - name: wslink - version: 2.1.1 + version: 2.1.2 manager: conda platform: win-64 dependencies: python: '>=3.7' aiohttp: <4 msgpack-python: '>=1,<2' - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.1-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.1.2-pyhd8ed1ab_0.conda hash: - md5: 6b1aef9c878c58baa7bb9f0d44457174 - sha256: 446a1d5952f603c52c2083b224405e54a940c012dfef9d0642ffcfc1b29f0ab6 + md5: 4cbb17383064ccfb46797aea03d70fc7 + sha256: db8236946b789bcc303c3f28fb1a3749fb9d694300faef9091299a4354759241 category: main optional: false - name: wsproto @@ -24301,8 +24315,8 @@ package: manager: conda platform: osx-arm64 dependencies: - h11: '>=0.9.0,<1.0' python: '>=3.7' + h11: '>=0.9.0,<1.0' url: https://conda.anaconda.org/conda-forge/noarch/wsproto-1.2.0-pyhd8ed1ab_0.tar.bz2 hash: md5: 00ba804b54f451d102f6a7615f08470d @@ -24537,10 +24551,10 @@ package: ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-h63175ca_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-he0c23c2_1.conda hash: - md5: b1e07902b6bb7833db8cc4ec32f32dc7 - sha256: 21328b0442f2f86ad5bf14481ed60f56a8ebb765a68d158a57ec6f32eb55762b + md5: 0a0d85bb98ea8ffb9948afe5bcbd63f7 + sha256: d90517c4ea257096a021ccb42742607e9ee034492aba697db1095321a871a638 category: main optional: false - name: xkeyboard-config @@ -25113,55 +25127,55 @@ package: category: main optional: false - name: yarn - version: 4.3.1 + version: 4.4.0 manager: conda platform: linux-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.4.0-h31011fe_0.conda hash: - md5: 7d0a2d56af92fab67f350d469ebda9cc - sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 + md5: ac46baad5b16d37a9364c3e49d6421e4 + sha256: c726ee82687362605387d10191039df00dca5bed99f3e87f482f104c9d32fccd category: main optional: false - name: yarn - version: 4.3.1 + version: 4.4.0 manager: conda platform: osx-64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.4.0-h31011fe_0.conda hash: - md5: 7d0a2d56af92fab67f350d469ebda9cc - sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 + md5: ac46baad5b16d37a9364c3e49d6421e4 + sha256: c726ee82687362605387d10191039df00dca5bed99f3e87f482f104c9d32fccd category: main optional: false - name: yarn - version: 4.3.1 + version: 4.4.0 manager: conda platform: osx-arm64 dependencies: __unix: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h31011fe_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.4.0-h31011fe_0.conda hash: - md5: 7d0a2d56af92fab67f350d469ebda9cc - sha256: 66b5ebb5a5aff90467b758daf41b0884d9b31d71740787eff64d423d8e5f76e1 + md5: ac46baad5b16d37a9364c3e49d6421e4 + sha256: c726ee82687362605387d10191039df00dca5bed99f3e87f482f104c9d32fccd category: main optional: false - name: yarn - version: 4.3.1 + version: 4.4.0 manager: conda platform: win-64 dependencies: __win: '' nodejs: '>=18.12.0' - url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.3.1-h5737063_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/yarn-4.4.0-h5737063_0.conda hash: - md5: fd9fee941d3fa785d2567909057a2a04 - sha256: 8aaa1ce4fd43dce53c21fbb5edadb13dfee6fdfc034dcff8e674b143da09a81c + md5: 40496d9265ce0c4c64d50f65f1891b98 + sha256: 947e15a0c7306a2d6d850e687999060862672b0345b704bbd3861cd8fccf6fdf category: main optional: false - name: zeromq @@ -25269,57 +25283,124 @@ package: category: main optional: false - name: zlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: linux-64 dependencies: libgcc-ng: '>=12' - libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda + libzlib: 1.3.1 + url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-h4ab18f5_1.conda hash: - md5: 559d338a4234c2ad6e676f460a093e67 - sha256: 534824ea44939f3e59ca8ebb95e3ece6f50f9d2a0e69999fbc692311252ed6ac + md5: 9653f1bf3766164d0e65fa723cabbc54 + sha256: cee16ab07a11303de721915f0a269e8c7a54a5c834aa52f74b1cc3a59000ade8 category: main optional: false - name: zlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: osx-64 dependencies: __osx: '>=10.13' - libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h87427d6_6.conda + libzlib: 1.3.1 + url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-h87427d6_1.conda hash: - md5: 700b922d6d22e7deb5fb2964d0c8cf6a - sha256: 3091d48a579c08ba20885bc8856def925e9dee9d1a7d8713e3ce002eb29fcd19 + md5: 3ac9ef8975965f9698dbedd2a4cc5894 + sha256: 41bd5fef28b2755d637e3a8ea5c84010628392fbcf80c7e3d7370aaced7ee4fe category: main optional: false - name: zlib - version: 1.2.13 + version: 1.3.1 manager: conda platform: osx-arm64 dependencies: __osx: '>=11.0' - libzlib: 1.2.13 - url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-hfb2fe0b_6.conda + libzlib: 1.3.1 + url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-hfb2fe0b_1.conda hash: - md5: 88cf27df3eff5813734b538461f4c8cf - sha256: c09c9cb6de86d87b9267a6331c74cc8fb05bae5ee7749070a5e8883c3eff5424 + md5: f27e021db7862b6ddbc1d3578f10d883 + sha256: 87360c2dc662916aac37cf01e53324b4f4f78db6f399220818076752b093ede5 category: main optional: false - name: zlib - version: 1.3.1 + version: 1.2.13 manager: conda platform: win-64 dependencies: - libzlib: 1.3.1 + libzlib: 1.2.13 + ucrt: '>=10.0.20348.0' + vc: '>=14.2,<15' + vc14_runtime: '>=14.29.30139' + url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-h2466b09_6.conda + hash: + md5: 86591a585a18e35d23279b6b384eb4b9 + sha256: 7aebf311fdb9227deddaedc33ace85bc960f5116ffb31f3ff07db380dfca0b41 + category: main + optional: false +- name: zstandard + version: 0.23.0 + manager: conda + platform: linux-64 + dependencies: + __glibc: '>=2.17,<3.0.a0' + cffi: '>=1.11' + libgcc-ng: '>=12' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + zstd: '>=1.5.6,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py38h62bed22_0.conda + hash: + md5: 7cdf6cb1dcfbaf868ff42b15189f7e59 + sha256: c91d68f07b9909138f19b6bf5acbb1acdd9bc620e4bd4b997514e646584a43ae + category: main + optional: false +- name: zstandard + version: 0.23.0 + manager: conda + platform: osx-64 + dependencies: + __osx: '>=10.13' + cffi: '>=1.11' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + zstd: '>=1.5.6,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-64/zstandard-0.23.0-py38hdb7df32_0.conda + hash: + md5: be8ae480a2c487987fc4aeda477328dc + sha256: 9bd6178c20b468985784e63e5a5752ba09c23922e9113694bb0c308f035a85aa + category: main + optional: false +- name: zstandard + version: 0.23.0 + manager: conda + platform: osx-arm64 + dependencies: + __osx: '>=11.0' + cffi: '>=1.11' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* + zstd: '>=1.5.6,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/osx-arm64/zstandard-0.23.0-py38h43bb1b3_0.conda + hash: + md5: be90d81878902f7c0e7bb2846fbe126c + sha256: 14c3139f32c22b61ee4dbf9f4f1e44b445a54505b3e09dd0e41146f40865afe2 + category: main + optional: false +- name: zstandard + version: 0.23.0 + manager: conda + platform: win-64 + dependencies: + cffi: '>=1.11' + python: '>=3.8,<3.9.0a0' + python_abi: 3.8.* ucrt: '>=10.0.20348.0' vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' - url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.1-h2466b09_1.conda + zstd: '>=1.5.6,<1.6.0a0' + url: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.23.0-py38hf92978b_0.conda hash: - md5: f8e0a35bf6df768ad87ed7bbbc36ab04 - sha256: 76409556e6c7cb91991cd94d7fc853c9272c2872bd7e3573ff35eb33d6fca5be + md5: 98bd13d4c311b4c8402446c93b142f9b + sha256: 1a7dd43fd4d3e667521b2fb3477cd20ef6586c5696c003ef5c6bff01dca37a71 category: main optional: false - name: zstd From 6c3d0f6da8389571e4eaa4ac8873cab564539f02 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 13:38:55 +0200 Subject: [PATCH 041/103] Fix setting worker process dict --- cea/interfaces/dashboard/server/jobs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index b0a86a8613..cbf86e5e4b 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -117,10 +117,10 @@ async def set_job_error(jobs: CEAJobs, job_id: str, worker_processes: CEAWorkerP async def start_job(worker_processes: CEAWorkerProcesses, worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" print("tools/route_start: {job_id}".format(**locals())) - worker_processes[job_id] = subprocess.Popen([ + await worker_processes.set(job_id, subprocess.Popen([ "python", "-m", "cea.worker", f"{job_id}", "--url", f"{worker_url}" - ]) + ])) return job_id From 336ea2772866bdf46396f08a67f577d70558cef4 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 13:52:12 +0200 Subject: [PATCH 042/103] Fix not being able to pickle process object Only store pid of process instead of the whole process object, since we are able to retrieve it using psutils. --- cea/interfaces/dashboard/server/jobs.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cea/interfaces/dashboard/server/jobs.py b/cea/interfaces/dashboard/server/jobs.py index cbf86e5e4b..2f62a83aa0 100644 --- a/cea/interfaces/dashboard/server/jobs.py +++ b/cea/interfaces/dashboard/server/jobs.py @@ -117,10 +117,11 @@ async def set_job_error(jobs: CEAJobs, job_id: str, worker_processes: CEAWorkerP async def start_job(worker_processes: CEAWorkerProcesses, worker_url: CEAWorkerUrl, jobs: CEAJobs, job_id: str): """Start a ``cea-worker`` subprocess for the script. (FUTURE: add support for cloud-based workers""" print("tools/route_start: {job_id}".format(**locals())) - await worker_processes.set(job_id, subprocess.Popen([ + process = subprocess.Popen([ "python", "-m", "cea.worker", f"{job_id}", "--url", f"{worker_url}" - ])) + ]) + await worker_processes.set(job_id, process.pid) return job_id @@ -142,12 +143,12 @@ async def kill_job(jobid, worker_processes): if jobid not in await worker_processes.values(): return - popen = await worker_processes.get(jobid) + pid = await worker_processes.get(jobid) # using code from here: https://stackoverflow.com/a/4229404/2260 # to terminate child processes too - print("killing child processes of {jobid} ({pid})".format(jobid=jobid, pid=popen.pid)) + print("killing child processes of {jobid} ({pid})".format(jobid=jobid, pid=pid)) try: - process = psutil.Process(popen.pid) + process = psutil.Process(pid) except psutil.NoSuchProcess: return children = process.children(recursive=True) From f9bc4bb43d7975ea3bff4821b013057b6efa937f Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:00:59 +0200 Subject: [PATCH 043/103] Fix route typo --- cea/interfaces/dashboard/api/dashboards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index 515a979534..81a80a9b9c 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -104,7 +104,7 @@ async def get_plot_categories(config: CEAConfig): return get_categories(config.plugins) -@router.get('/plot-categories/{category_name}/plots/{plot_id>}/parameters') +@router.get('/plot-categories/{category_name}/plots/{plot_id}/parameters') async def get_plot_category_parameters(config: CEAConfig, category_name: str, plot_id: str, scenario: str = None): plot_class = cea.plots.categories.load_plot_by_id(category_name, plot_id, config.plugins) return get_parameters_from_plot_class(config, plot_class, scenario) From 9120b547dad373466f274359d5faacde21fa296a Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:07:31 +0200 Subject: [PATCH 044/103] Fix router typo --- cea/interfaces/dashboard/api/dashboards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index 81a80a9b9c..c6fc1c3857 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -163,7 +163,7 @@ async def get_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] -@router.put('/{dashboard_index}/plots/{plot_index}>') +@router.put('/{dashboard_index}/plots/{plot_index}') async def create_plot_at_index(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int, payload: Dict[str, Any]): """ From 192a5f1857a7fcbe5758d3f096181a68dba85ef8 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:10:27 +0200 Subject: [PATCH 045/103] Write configs in one layer --- Dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index a941230229..3734c7a458 100644 --- a/Dockerfile +++ b/Dockerfile @@ -55,10 +55,11 @@ ARG MAMBA_DOCKERFILE_ACTIVATE=1 # install cea after dependencies to avoid running conda too many times when rebuilding COPY --chown=$MAMBA_USER:$MAMBA_USER . /tmp/cea RUN pip install /tmp/cea -RUN cea-config write --general:project /project -RUN cea-config write --radiation:daysim-bin-directory /Daysim -# required for flask to receive reqests from the docker host -RUN cea-config write --server:host 0.0.0.0 + +# write config files +RUN cea-config write --general:project /project \ + && cea-config write --radiation:daysim-bin-directory /Daysim \ + && cea-config write --server:host 0.0.0.0 # required for flask to receive requests from the docker host ENTRYPOINT ["/usr/local/bin/_entrypoint.sh"] CMD cea dashboard From b06c228e35bd7a0cd5cf53a1d7766aa262a9fe4b Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:17:19 +0200 Subject: [PATCH 046/103] Fix route typo --- cea/interfaces/dashboard/api/dashboards.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/api/dashboards.py b/cea/interfaces/dashboard/api/dashboards.py index c6fc1c3857..17945f17c3 100644 --- a/cea/interfaces/dashboard/api/dashboards.py +++ b/cea/interfaces/dashboard/api/dashboards.py @@ -153,7 +153,7 @@ async def update_dashboard(config: CEAConfig, plot_cache: CEAPlotCache, dashboar return {'new_dashboard_index': dashboard_index} -@router.get('/{dashboard_index}/plots/{plot_index}>') +@router.get('/{dashboard_index}/plots/{plot_index}') async def get_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int): """ Get Dashboard Plot @@ -198,7 +198,7 @@ async def create_plot_at_index(config: CEAConfig, plot_cache: CEAPlotCache, return dashboard_to_dict(dashboards[dashboard_index])['plots'][plot_index] -@router.delete('/{dashboard_index}/plots/{plot_index}>') +@router.delete('/{dashboard_index}/plots/{plot_index}') async def delete_plot(config: CEAConfig, plot_cache: CEAPlotCache, dashboard_index: int, plot_index: int): """ Delete Plot from Dashboard From 094cfd433ff1276183271f9a8c5de22dcf41ec48 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:28:37 +0200 Subject: [PATCH 047/103] Add missing await --- cea/interfaces/dashboard/api/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index ebb68d1ba1..d8ee769b34 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -83,7 +83,7 @@ async def save_tool_config(config: CEAConfig, tool_name: str, payload: Dict[str, value = payload[parameter.name] print('%s: %s' % (parameter.name, value)) parameter.set(value) - config.save() + await config.save() return 'Success' From 4dc88a3c5bf7db63eae6be2b12fbebedef07e214 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 12 Aug 2024 00:10:12 +0200 Subject: [PATCH 048/103] Add missing input files for script --- cea/scripts.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cea/scripts.yml b/cea/scripts.yml index 4037ded2f3..789028367f 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -102,6 +102,8 @@ Demand forecasting: 'general:debug', schedule-maker] input-files: + - [get_building_internal] + - [get_building_comfort] - [get_building_architecture] - [get_zone_geometry] - [get_weather_file] From a89f503a46712c4a3cc4a2897e48a6a18bb57112 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 12 Aug 2024 00:37:38 +0200 Subject: [PATCH 049/103] Update conda-lock.yml --- conda-lock.yml | 128 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 36 deletions(-) diff --git a/conda-lock.yml b/conda-lock.yml index 7505b9af71..8667c6297a 100644 --- a/conda-lock.yml +++ b/conda-lock.yml @@ -13,10 +13,10 @@ version: 1 metadata: content_hash: - linux-64: b2c2957fddcd9b9ddc8923cef3d935591771d6a6ddd6f2ae4c48c5bd308a7873 - osx-arm64: d73a8b349385dbaf336923cfa7fdfe17b8e72b5221ca06fffc10b91bb8c3a4fa - osx-64: 5f95fabcc9038c883ccf7f2946038b60949ac09ae465dc573316628cedd0ca99 - win-64: 16ae8e92dda832ad5d683c8c17cee1fa34964ff5dfb470e25ec9ca58ed508447 + linux-64: 3f1de7a44dc72b20a2c62c66c87f6193bc497c342382a7d34682ceb483e8a4e0 + osx-arm64: 5b3b91cad60c6d8c07efa763a13b521c9eff4b71763601faf0063fde7b296eea + osx-64: 7a324922b520d42f1ad2656260b70a698ceec2ef0827db09dd44d9e0dbb9f32c + win-64: ab2315818eb51db6522ca8f1da8125b4df5ea7244d947761eaf86e17243b3159 channels: - url: conda-forge used_env_vars: [] @@ -197,7 +197,7 @@ package: category: main optional: false - name: aiohttp - version: 3.10.2 + version: 3.10.3 manager: conda platform: linux-64 dependencies: @@ -212,14 +212,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.10.2-py38h2019614_0.conda + url: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.10.3-py38h2019614_0.conda hash: - md5: aefa307b305ab253c865cc81fa8129b6 - sha256: c8d937888812c048601533a856492e7fb55db75efde3dfad5756e7fe4c80b4f7 + md5: 502fd35a4eea3206de0e89539f85f3bd + sha256: ed40e0289549f18bb0686d9ada64116ac2174a20a27ae8e49228e87ffc42f8ae category: main optional: false - name: aiohttp - version: 3.10.2 + version: 3.10.3 manager: conda platform: osx-64 dependencies: @@ -233,14 +233,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.10.2-py38hc718529_0.conda + url: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.10.3-py38hc718529_0.conda hash: - md5: 4b315bc686e7c8477504a293f0742b93 - sha256: b348f8768763d0686d2c782321ef6934d03130ef09cdb5db48abdda72ad707fe + md5: ebc8bb195e73321125f6da9c7d0ec039 + sha256: 6c83d3f4def469d76e738fbc3c840dd22b41b6e51e20648fc86a3c21ac3f5697 category: main optional: false - name: aiohttp - version: 3.10.2 + version: 3.10.3 manager: conda platform: osx-arm64 dependencies: @@ -254,14 +254,14 @@ package: python: '>=3.8,<3.9.0a0' python_abi: 3.8.* yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.10.2-py38h3237794_0.conda + url: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.10.3-py38h3237794_0.conda hash: - md5: 7a61e6aabd919af7c6e8b8fbeeeccd4d - sha256: 799d22e7642deed0825c87dc2267f49e2b8705bdc697c9367290d9acddae2adc + md5: 7e5a34fafcd669028dcfc7e91c14c565 + sha256: b7d7348f9f430ec6e41682f9d372a288b5506b5c56962440f9684bf73b050d90 category: main optional: false - name: aiohttp - version: 3.10.2 + version: 3.10.3 manager: conda platform: win-64 dependencies: @@ -277,10 +277,10 @@ package: vc: '>=14.2,<15' vc14_runtime: '>=14.29.30139' yarl: '>=1.0,<2.0' - url: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.10.2-py38h4cb3324_0.conda + url: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.10.3-py38h4cb3324_0.conda hash: - md5: 858504ad3c45ed8b4ff01fd5df063b69 - sha256: 28563fce8c4e8c628a730bb9180b479f15f0287fb58efda335981b6fe5c8c79f + md5: 87451e1e15d6811023efbb6558a0a2b7 + sha256: 25711bddc935b9b6e1b904150bb6ce638cf76b635d2f387ea8d2df7b5722a8f8 category: main optional: false - name: aiosignal @@ -19481,6 +19481,62 @@ package: sha256: 4790787fe1f4e8da616edca4acf6a4f8ed4e7c6967aa31b920208fc8f95efcca category: main optional: false +- name: python-louvain + version: '0.16' + manager: conda + platform: linux-64 + dependencies: + networkx: '' + numpy: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-louvain-0.16-pyhd8ed1ab_0.conda + hash: + md5: db29f9a0f9ee3495b4eda33c5dde7628 + sha256: 2802225f77c2c03e027e8b08eff46a6a333dc686b68d3ceb271916018f6ee508 + category: main + optional: false +- name: python-louvain + version: '0.16' + manager: conda + platform: osx-64 + dependencies: + numpy: '' + networkx: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-louvain-0.16-pyhd8ed1ab_0.conda + hash: + md5: db29f9a0f9ee3495b4eda33c5dde7628 + sha256: 2802225f77c2c03e027e8b08eff46a6a333dc686b68d3ceb271916018f6ee508 + category: main + optional: false +- name: python-louvain + version: '0.16' + manager: conda + platform: osx-arm64 + dependencies: + numpy: '' + networkx: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-louvain-0.16-pyhd8ed1ab_0.conda + hash: + md5: db29f9a0f9ee3495b4eda33c5dde7628 + sha256: 2802225f77c2c03e027e8b08eff46a6a333dc686b68d3ceb271916018f6ee508 + category: main + optional: false +- name: python-louvain + version: '0.16' + manager: conda + platform: win-64 + dependencies: + numpy: '' + networkx: '' + python: '>=3.6' + url: https://conda.anaconda.org/conda-forge/noarch/python-louvain-0.16-pyhd8ed1ab_0.conda + hash: + md5: db29f9a0f9ee3495b4eda33c5dde7628 + sha256: 2802225f77c2c03e027e8b08eff46a6a333dc686b68d3ceb271916018f6ee508 + category: main + optional: false - name: python-multipart version: 0.0.9 manager: conda @@ -23945,51 +24001,51 @@ package: category: main optional: false - name: webcolors - version: 24.6.0 + version: 24.8.0 manager: conda platform: linux-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.8.0-pyhd8ed1ab_0.conda hash: - md5: 419f2f6cf90fc7a6feee657752cd0f7b - sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f + md5: eb48b812eb4fbb9ff238a6651fdbbcae + sha256: ec71f97c332a7d328ae038990b8090cbfa772f82845b5d2233defd167b7cc5ac category: main optional: false - name: webcolors - version: 24.6.0 + version: 24.8.0 manager: conda platform: osx-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.8.0-pyhd8ed1ab_0.conda hash: - md5: 419f2f6cf90fc7a6feee657752cd0f7b - sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f + md5: eb48b812eb4fbb9ff238a6651fdbbcae + sha256: ec71f97c332a7d328ae038990b8090cbfa772f82845b5d2233defd167b7cc5ac category: main optional: false - name: webcolors - version: 24.6.0 + version: 24.8.0 manager: conda platform: osx-arm64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.8.0-pyhd8ed1ab_0.conda hash: - md5: 419f2f6cf90fc7a6feee657752cd0f7b - sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f + md5: eb48b812eb4fbb9ff238a6651fdbbcae + sha256: ec71f97c332a7d328ae038990b8090cbfa772f82845b5d2233defd167b7cc5ac category: main optional: false - name: webcolors - version: 24.6.0 + version: 24.8.0 manager: conda platform: win-64 dependencies: python: '>=3.5' - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.8.0-pyhd8ed1ab_0.conda hash: - md5: 419f2f6cf90fc7a6feee657752cd0f7b - sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f + md5: eb48b812eb4fbb9ff238a6651fdbbcae + sha256: ec71f97c332a7d328ae038990b8090cbfa772f82845b5d2233defd167b7cc5ac category: main optional: false - name: webencodings From f4eb0e535e23d4f5f10cd571263b53797e96c11d Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 12 Aug 2024 00:40:30 +0200 Subject: [PATCH 050/103] Fix linting --- cea/interfaces/dashboard/api/project.py | 2 +- cea/interfaces/dashboard/api/utils.py | 2 +- cea/interfaces/dashboard/settings.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 593a06bc86..bebacd7e13 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -223,7 +223,7 @@ async def check_scenario_exists(request: Request, config: CEAConfig, scenario: s if scenario not in choices: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail=f'Scenario does not exist.', + detail='Scenario does not exist.', ) diff --git a/cea/interfaces/dashboard/api/utils.py b/cea/interfaces/dashboard/api/utils.py index 6dad3ebadb..296e0472b7 100644 --- a/cea/interfaces/dashboard/api/utils.py +++ b/cea/interfaces/dashboard/api/utils.py @@ -26,7 +26,7 @@ def deconstruct_parameters(p: cea.config.Parameter, config=None): try: params["nullable"] = p.nullable - except AttributeError as e: + except AttributeError: pass return params diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py index 8fa77f45b1..0f414f4c91 100644 --- a/cea/interfaces/dashboard/settings.py +++ b/cea/interfaces/dashboard/settings.py @@ -1,5 +1,5 @@ from functools import lru_cache -from typing import Optional, List +from typing import Optional from pydantic_settings import BaseSettings, SettingsConfigDict From 68bc3e17f0f3cc336925381d214e0619cd5bbff3 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:06:23 +0200 Subject: [PATCH 051/103] Add weather endpoint --- cea/databases/__init__.py | 12 ++++++++---- cea/interfaces/dashboard/api/__init__.py | 3 +++ cea/interfaces/dashboard/api/weather.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 cea/interfaces/dashboard/api/weather.py diff --git a/cea/databases/__init__.py b/cea/databases/__init__.py index eb23f2dbf6..1c1b07576e 100644 --- a/cea/databases/__init__.py +++ b/cea/databases/__init__.py @@ -1,6 +1,3 @@ - - - import os from collections import OrderedDict @@ -10,7 +7,14 @@ def get_regions(): return [folder for folder in os.listdir(databases_folder_path) if folder != "weather" - and os.path.isdir(os.path.join(databases_folder_path, folder))] + and os.path.isdir(os.path.join(databases_folder_path, folder)) + and not folder.startswith('.') + and not folder.startswith('__')] + + +def get_weather_files(): + weather_folder_path = os.path.join(databases_folder_path, 'weather') + return [os.path.splitext(f)[0] for f in os.listdir(weather_folder_path) if f.endswith('.epw')] def get_categories(db_path): diff --git a/cea/interfaces/dashboard/api/__init__.py b/cea/interfaces/dashboard/api/__init__.py index 2ba3614b5e..3c6b4141f9 100644 --- a/cea/interfaces/dashboard/api/__init__.py +++ b/cea/interfaces/dashboard/api/__init__.py @@ -7,6 +7,7 @@ import cea.interfaces.dashboard.api.glossary as glossary import cea.interfaces.dashboard.api.project as project import cea.interfaces.dashboard.api.tools as tools +import cea.interfaces.dashboard.api.weather as weather router = APIRouter() @@ -17,3 +18,5 @@ router.include_router(glossary.router, prefix="/glossary") router.include_router(project.router, prefix="/project") router.include_router(tools.router, prefix="/tools") + +router.include_router(weather.router, prefix="/weather") diff --git a/cea/interfaces/dashboard/api/weather.py b/cea/interfaces/dashboard/api/weather.py new file mode 100644 index 0000000000..dab74f1adf --- /dev/null +++ b/cea/interfaces/dashboard/api/weather.py @@ -0,0 +1,10 @@ +from fastapi import APIRouter + +from cea.databases import get_weather_files + +router = APIRouter() + + +@router.get('') +async def get_weather(): + return {'weather': get_weather_files()} From d2152270604c3af5b1788278631a0119418f1ea0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 19 Aug 2024 01:23:35 +0200 Subject: [PATCH 052/103] Add endpoint to fetch version --- cea/interfaces/dashboard/server/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cea/interfaces/dashboard/server/__init__.py b/cea/interfaces/dashboard/server/__init__.py index 131a885011..9b5fba0dd4 100644 --- a/cea/interfaces/dashboard/server/__init__.py +++ b/cea/interfaces/dashboard/server/__init__.py @@ -1,5 +1,6 @@ from fastapi import APIRouter +import cea import cea.interfaces.dashboard.server.jobs as jobs import cea.interfaces.dashboard.server.streams as streams from cea.interfaces.dashboard.dependencies import get_worker_processes @@ -20,3 +21,8 @@ async def shutdown_worker_processes(): @router.get("/alive") async def get_health_check(): return {'success': True} + + +@router.get("/version") +async def get_version(): + return {'version': cea.__version__} From 69cbcf17a54c80a70d77c5bbecb9d66370c7444b Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 19 Aug 2024 03:42:09 +0200 Subject: [PATCH 053/103] Add database validation endpoint --- cea/interfaces/dashboard/api/databases.py | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cea/interfaces/dashboard/api/databases.py b/cea/interfaces/dashboard/api/databases.py index 3f7fc2a14b..329df3a2e4 100644 --- a/cea/interfaces/dashboard/api/databases.py +++ b/cea/interfaces/dashboard/api/databases.py @@ -1,9 +1,13 @@ import os +from typing import Optional, Literal import pandas as pd from fastapi import APIRouter, HTTPException, status +from pydantic import BaseModel +import cea.inputlocator from cea.databases import get_regions, get_database_tree, databases_folder_path +from cea.interfaces.dashboard.dependencies import CEAConfig from cea.utilities.schedule_reader import schedule_to_dataframe router = APIRouter() @@ -131,3 +135,32 @@ async def get_database_schema(): except KeyError as ex: raise KeyError(f"Could not convert_path_to_name for {db_name}/{db_schema_key}. {ex}") return out + + +class ValidateDatabase(BaseModel): + type: Literal['path', 'file'] + path: Optional[str] = None + file: Optional[str] = None + + +@router.post("/validate") +async def validate_database(config: CEAConfig, data: ValidateDatabase): + """Validate the given databases (only checks if the folder structure is correct)""" + if data.type == 'path': + # Override the locator to use path of database + class DummyInputLocator(cea.inputlocator.InputLocator): + def get_databases_folder(self): + return data.path + + try: + DummyInputLocator(config.scenario).verify_database_template() + except IOError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) + + return {} + return {} + From e07f58772ad694a99d9a6b7cfe873a6b7f360234 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:16:10 +0200 Subject: [PATCH 054/103] Add building geometries validation endpoint --- cea/interfaces/dashboard/api/databases.py | 3 ++ cea/interfaces/dashboard/api/geometry.py | 65 +++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 cea/interfaces/dashboard/api/geometry.py diff --git a/cea/interfaces/dashboard/api/databases.py b/cea/interfaces/dashboard/api/databases.py index 329df3a2e4..d3473253d1 100644 --- a/cea/interfaces/dashboard/api/databases.py +++ b/cea/interfaces/dashboard/api/databases.py @@ -147,6 +147,9 @@ class ValidateDatabase(BaseModel): async def validate_database(config: CEAConfig, data: ValidateDatabase): """Validate the given databases (only checks if the folder structure is correct)""" if data.type == 'path': + if data.path is None: + raise HTTPException(status_code=400, detail="Missing path") + # Override the locator to use path of database class DummyInputLocator(cea.inputlocator.InputLocator): def get_databases_folder(self): diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py new file mode 100644 index 0000000000..3c30158274 --- /dev/null +++ b/cea/interfaces/dashboard/api/geometry.py @@ -0,0 +1,65 @@ +import json +from typing import Literal, Optional + +import osmnx +from fastapi import APIRouter, HTTPException, status + +import geopandas as gpd +from pydantic import BaseModel + +from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings + +router = APIRouter() + + +@router.get("/buildings") +async def fetch_buildings(generate: bool = False, polygon: str = None): + if generate: + if polygon is None: + return HTTPException(status_code=400, detail="Missing polygon") + try: + site_polygon = gpd.read_file(polygon, crs="epsg:4326") + + if site_polygon.empty: + raise HTTPException(status_code=400, detail="Empty polygon") + + buildings = osmnx.features_from_polygon(polygon=site_polygon['geometry'].values[0], tags={"building": True}) + + # Drop all columns except geometry to reduce file size + buildings = gpd.GeoDataFrame(geometry=buildings['geometry'], crs="epsg:4326") + + return json.loads(buildings.to_json()) + + except Exception as e: + print(e) + return HTTPException(status_code=500, detail=str(e)) + + +class ValidateGeometry(BaseModel): + type: Literal['path', 'file'] + building: Literal['zone', 'surroundings'] + path: Optional[str] = None + file: Optional[str] = None + +@router.post("/buildings/validate") +async def validate_building_geometry(data: ValidateGeometry): + """Validate the given building geometry""" + if data.type == 'path': + if data.path is None: + raise HTTPException(status_code=400, detail="Missing path") + + try: + building_df = gpd.read_file(data.path) + print(building_df) + if data.building == 'zone': + verify_input_geometry_zone(building_df) + elif data.building == 'surroundings': + verify_input_geometry_surroundings(building_df) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) + + return {} From de2b95b0ef0ccbd2aed25396fa75887a8fccb803 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:13:21 +0200 Subject: [PATCH 055/103] Add typology validation endpoint --- cea/interfaces/dashboard/api/__init__.py | 3 ++- cea/interfaces/dashboard/api/geometry.py | 32 +++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/api/__init__.py b/cea/interfaces/dashboard/api/__init__.py index 3c6b4141f9..ac00347d95 100644 --- a/cea/interfaces/dashboard/api/__init__.py +++ b/cea/interfaces/dashboard/api/__init__.py @@ -8,6 +8,7 @@ import cea.interfaces.dashboard.api.project as project import cea.interfaces.dashboard.api.tools as tools import cea.interfaces.dashboard.api.weather as weather +import cea.interfaces.dashboard.api.geometry as geometry router = APIRouter() @@ -18,5 +19,5 @@ router.include_router(glossary.router, prefix="/glossary") router.include_router(project.router, prefix="/project") router.include_router(tools.router, prefix="/tools") - router.include_router(weather.router, prefix="/weather") +router.include_router(geometry.router, prefix="/geometry") diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index 3c30158274..9a29e1983f 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -7,7 +7,9 @@ import geopandas as gpd from pydantic import BaseModel -from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings +from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ + verify_input_typology +from cea.utilities.dbf import dbf_to_dataframe router = APIRouter() @@ -63,3 +65,31 @@ async def validate_building_geometry(data: ValidateGeometry): ) return {} + + +class ValidateTypology(BaseModel): + type: Literal['path', 'file'] + path: Optional[str] = None + file: Optional[str] = None + + +# TODO: Find a more suitable route +@router.post("/typology/validate") +async def validate_typology(data: ValidateTypology): + """Validate the given typology""" + if data.type == 'path': + if data.path is None: + raise HTTPException(status_code=400, detail="Missing path") + + try: + typology_df = dbf_to_dataframe(data.path) + verify_input_typology(typology_df) + print(typology_df) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=str(e), + ) + + return {} From 8edc302eacc52d7e711027ec8400bbec156b1d0f Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:10:10 +0200 Subject: [PATCH 056/103] Create updated create scenario endpoint --- cea/datamanagement/create_new_scenario.py | 58 +++++----- cea/datamanagement/surroundings_helper.py | 5 +- cea/interfaces/dashboard/api/project.py | 135 +++++++++++++++++++++- 3 files changed, 170 insertions(+), 28 deletions(-) diff --git a/cea/datamanagement/create_new_scenario.py b/cea/datamanagement/create_new_scenario.py index 4e962e5c2b..12e96018b3 100644 --- a/cea/datamanagement/create_new_scenario.py +++ b/cea/datamanagement/create_new_scenario.py @@ -1,11 +1,6 @@ """ A tool to create a new project / scenario with the CEA. """ - - - - - import os from shutil import copyfile @@ -29,6 +24,35 @@ __status__ = "Production" +def copy_terrain(terrain_path, locator, lat, lon): + terrain = raster_to_WSG_and_UTM(terrain_path, lat, lon) + driver = gdal.GetDriverByName('GTiff') + verify_input_terrain(terrain) + driver.CreateCopy(locator.get_terrain(), terrain) + + +def copy_typology(typology_path, locator): + # import file + occupancy_file = dbf_to_dataframe(typology_path) + occupancy_file_test = occupancy_file[COLUMNS_ZONE_TYPOLOGY] + # verify if input file is correct for CEA, if not an exception will be released + verify_input_typology(occupancy_file_test) + # create new file + copyfile(typology_path, locator.get_building_typology()) + +def generate_default_typology(zone_geometry: Gdf, locator: cea.inputlocator.InputLocator): + zone = zone_geometry.drop('geometry', axis=1) + zone['STANDARD'] = 'STANDARD1' + zone['YEAR'] = 2020 + zone['1ST_USE'] = 'MULTI_RES' + zone['1ST_USE_R'] = 1.0 + zone['2ND_USE'] = "NONE" + zone['2ND_USE_R'] = 0.0 + zone['3RD_USE'] = "NONE" + zone['3RD_USE_R'] = 0.0 + dataframe_to_dbf(zone[COLUMNS_ZONE_TYPOLOGY], locator.get_building_typology()) + + def create_new_scenario(locator, config): # Local variables zone_geometry_path = config.create_new_scenario.zone @@ -53,10 +77,7 @@ def create_new_scenario(locator, config): if terrain_path == '': print("there is no terrain file, run pour datamanagement tools later on for this please") else: - terrain = raster_to_WSG_and_UTM(terrain_path, lat, lon) - driver = gdal.GetDriverByName('GTiff') - verify_input_terrain(terrain) - driver.CreateCopy(locator.get_terrain(), terrain) + copy_terrain(terrain_path, locator, lat, lon) # now create the surroundings file if it does not exist if surroundings_geometry_path == '': @@ -79,24 +100,9 @@ def create_new_scenario(locator, config): ## create occupancy file and year file if typology_path == '': print("there is no typology file, we proceed to create it based on the geometry of your zone") - zone = Gdf.from_file(zone_geometry_path).drop('geometry', axis=1) - zone['STANDARD'] = 'STANDARD1' - zone['YEAR'] = 2020 - zone['1ST_USE'] = 'MULTI_RES' - zone['1ST_USE_R'] = 1.0 - zone['2ND_USE'] = "NONE" - zone['2ND_USE_R'] = 0.0 - zone['3RD_USE'] = "NONE" - zone['3RD_USE_R'] = 0.0 - dataframe_to_dbf(zone[COLUMNS_ZONE_TYPOLOGY], locator.get_building_typology()) + generate_default_typology(zone, locator) else: - # import file - occupancy_file = dbf_to_dataframe(typology_path) - occupancy_file_test = occupancy_file[COLUMNS_ZONE_TYPOLOGY] - # verify if input file is correct for CEA, if not an exception will be released - verify_input_typology(occupancy_file_test) - # create new file - copyfile(typology_path, locator.get_building_typology()) + copy_typology(typology_path, locator) # add other folders by calling the locator locator.get_input_network_folder("DH", "") diff --git a/cea/datamanagement/surroundings_helper.py b/cea/datamanagement/surroundings_helper.py index 0d2ee2f18e..cba0d24b44 100644 --- a/cea/datamanagement/surroundings_helper.py +++ b/cea/datamanagement/surroundings_helper.py @@ -27,6 +27,9 @@ __email__ = "cea@arch.ethz.ch" __status__ = "Production" +def generate_empty_surroundings(crs) -> gdf: + return gdf(columns=["Name", "height_ag", "floors_ag"], geometry=[], crs=crs) + def calc_surrounding_area(zone_gdf, buffer_m): """ @@ -189,7 +192,7 @@ def geometry_extractor_osm(locator, config): if not surroundings.shape[0] > 0: print('No buildings were found within range based on buffer parameter.') # Create an empty surroundings file - result = gdf(columns=["Name", "height_ag", "floors_ag"], geometry=[], crs=surroundings.crs) + result = generate_empty_surroundings(surroundings.crs) else: # clean attributes of height, name and number of floors result = clean_attributes(surroundings, buildings_height, buildings_floors, key="CEA") diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index bebacd7e13..f092b1e36b 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -3,7 +3,7 @@ import shutil import tempfile import traceback -from typing import Dict, Any +from typing import Dict, Any, Optional import geopandas from fastapi import APIRouter, HTTPException, status, Request, Path, Depends @@ -15,6 +15,10 @@ import cea.config import cea.api import cea.inputlocator +from cea.datamanagement.create_new_scenario import generate_default_typology, copy_typology, copy_terrain +from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ + verify_input_typology, verify_input_terrain +from cea.datamanagement.surroundings_helper import generate_empty_surroundings from cea.interfaces.dashboard.dependencies import CEAConfig from cea.interfaces.dashboard.utils import secure_path from cea.plots.colors import color_to_rgb @@ -24,6 +28,12 @@ # PATH_REGEX = r'(^[a-zA-Z]:\\[\\\S|*\S]?.*$)|(^(/[^/ ]*)+/?$)' +GENERATE_ZONE_CEA = 'generate-zone-cea' +GENERATE_SURROUNDINGS_CEA = 'generate-surroundings-cea' +GENERATE_TYPOLOGY_CEA = 'generate-typology-cea' +GENERATE_TERRAIN_CEA = 'generate-terrain-cea' +GENERATE_STREET_CEA = 'generate-street-cea' +EMTPY_GEOMETRY = 'none' class ScenarioPath(BaseModel): project: str @@ -34,6 +44,34 @@ class NewProject(BaseModel): project_name: str project_root: str +class CreateScenario(BaseModel): + project: str + scenario_name: str + database: str + user_zone: str + user_surroundings: str + generate_zone: Optional[dict] = None + generate_surroundings: Optional[int] = None + typology: Optional[str] = None + weather: str + terrain: str + street: str + + def should_generate_zone(self) -> bool: + return self.user_zone == GENERATE_ZONE_CEA + + def should_generate_surroundings(self) -> bool: + return self.user_surroundings == GENERATE_SURROUNDINGS_CEA + + def should_generate_typology(self) -> bool: + return self.typology == GENERATE_TYPOLOGY_CEA + + def should_generate_terrain(self) -> bool: + return self.terrain == GENERATE_TERRAIN_CEA + + def should_generate_street(self) -> bool: + return self.street == GENERATE_STREET_CEA + @router.get('/') async def get_project_info(config: CEAConfig, project: str = None): @@ -107,6 +145,101 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): ) +# TODO: Rename this endpoint once the old one is removed +# Temporary endpoint to prevent breaking existing frontend +@router.post('/scenario/v2') +async def create_new_scenario_v2(config: CEAConfig, scenario_form: CreateScenario): + with tempfile.TemporaryDirectory() as tmp: + # Create temporary project before copying to actual scenario path + config.project = tmp + config.scenario_name = "temp_scenario" + locator = cea.inputlocator.InputLocator(config.scenario) + + # Run database_initializer to copy databases to input + cea.api.data_initializer(config, databases_path=scenario_form.database) + + # Generate / Copy zone and surroundings + if scenario_form.should_generate_zone(): + site_geojson = scenario_form.generate_zone + site_df = geopandas.GeoDataFrame(crs=get_geographic_coordinate_system(), + geometry=[shape(site_geojson['features'][0]['geometry'])]) + site_path = locator.get_site_polygon() + locator.ensure_parent_folder_exists(site_path) + site_df.to_file(site_path) + # Generate using zone helper + cea.api.zone_helper(config) + + # Ensure that zone exists + zone_df = geopandas.read_file(locator.get_zone_geometry()) + else: + # Copy zone using path + zone_df = geopandas.read_file(scenario_form.user_zone).to_crs(get_geographic_coordinate_system()) + verify_input_geometry_zone(zone_df) + + zone_path = locator.get_zone_geometry() + locator.ensure_parent_folder_exists(zone_path) + zone_df.to_file(zone_path) + + if scenario_form.should_generate_surroundings(): + # Generate using surroundings helper + config.surroundings_helper.buffer = scenario_form.generate_surroundings + cea.api.surroundings_helper(config) + elif scenario_form.user_surroundings == EMTPY_GEOMETRY: + # Generate empty surroundings + surroundings_df = generate_empty_surroundings(zone_df.crs) + + surroundings_path = locator.get_surroundings_geometry() + locator.ensure_parent_folder_exists(surroundings_path) + surroundings_df.to_file(surroundings_path) + else: + # Copy surroundings using path + surroundings_df = geopandas.read_file(scenario_form.user_surroundings).to_crs(get_geographic_coordinate_system()) + verify_input_geometry_surroundings(surroundings_df) + + surroundings_path = locator.get_surroundings_geometry() + locator.ensure_parent_folder_exists(surroundings_path) + surroundings_df.to_file(surroundings_path) + + if scenario_form.should_generate_typology(): + # Generate using default typology + locator.ensure_parent_folder_exists(locator.get_building_typology()) + generate_default_typology(zone_df, locator) + elif scenario_form.typology is not None: + # Copy typology using path + locator.ensure_parent_folder_exists(locator.get_building_typology()) + copy_typology(scenario_form.typology, locator) + + if scenario_form.should_generate_terrain(): + # Run terrain helper + cea.api.terrain_helper(config) + else: + # Copy terrain using path + centroid = zone_df.dissolve().centroid.values[0] + lat, lon = centroid.y, centroid.x + locator.ensure_parent_folder_exists(locator.get_terrain()) + copy_terrain(scenario_form.terrain, locator, lat, lon) + + if scenario_form.should_generate_street(): + # Run street helper + cea.api.streets_helper(config) + elif scenario_form.street != EMTPY_GEOMETRY: + # Copy street using path + street_df = geopandas.read_file(scenario_form.street).to_crs(get_geographic_coordinate_system()) + locator.ensure_parent_folder_exists(locator.get_street_network()) + street_df.to_file(locator.get_street_network()) + + # Move temp scenario to correct path + new_scenario_path = secure_path(os.path.join(scenario_form.project, str(scenario_form.scenario_name).strip())) + print(f"Moving from {config.scenario} to {new_scenario_path}") + shutil.move(config.scenario, new_scenario_path) + + return { + 'message': 'Scenario created successfully', + 'project': scenario_form.project, + 'scenario_name': scenario_form.scenario_name + } + + @router.post('/scenario/') async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): """ From 0e9620b09d0b99d54ec0e303c5b5beed92fbb9fa Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:16:44 +0200 Subject: [PATCH 057/103] Use default config when creating new scenario --- cea/interfaces/dashboard/api/project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index f092b1e36b..e08a902b2d 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -148,9 +148,10 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): # TODO: Rename this endpoint once the old one is removed # Temporary endpoint to prevent breaking existing frontend @router.post('/scenario/v2') -async def create_new_scenario_v2(config: CEAConfig, scenario_form: CreateScenario): +async def create_new_scenario_v2(scenario_form: CreateScenario): with tempfile.TemporaryDirectory() as tmp: # Create temporary project before copying to actual scenario path + config = cea.config.Configuration(cea.config.DEFAULT_CONFIG) config.project = tmp config.scenario_name = "temp_scenario" locator = cea.inputlocator.InputLocator(config.scenario) From 520fd16c4af8108da0bea11dac4f29d4d1566f8b Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:17:04 +0200 Subject: [PATCH 058/103] Add archetypes mapper --- cea/interfaces/dashboard/api/project.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index e08a902b2d..809e3d748b 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -229,6 +229,9 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(locator.get_street_network()) street_df.to_file(locator.get_street_network()) + # Run archetypes mapper + cea.api.archetypes_mapper(config) + # Move temp scenario to correct path new_scenario_path = secure_path(os.path.join(scenario_form.project, str(scenario_form.scenario_name).strip())) print(f"Moving from {config.scenario} to {new_scenario_path}") From 950a7ac872c82824101069145af1205680cb9874 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:15:09 +0200 Subject: [PATCH 059/103] Add weather helper to create scenario --- cea/interfaces/dashboard/api/project.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 809e3d748b..482b81d02a 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -210,6 +210,10 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(locator.get_building_typology()) copy_typology(scenario_form.typology, locator) + # Run weather helper + config.weather_helper.weather = scenario_form.weather + cea.api.weather_helper(config) + if scenario_form.should_generate_terrain(): # Run terrain helper cea.api.terrain_helper(config) From 8181912d78aa636776e30382cffe41603c85b2c8 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:15:31 +0200 Subject: [PATCH 060/103] Update weather helper config --- cea/config.py | 4 ++++ cea/datamanagement/weather_helper/weather_helper.py | 2 +- cea/scripts.yml | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cea/config.py b/cea/config.py index 6be238164a..5be62c2009 100644 --- a/cea/config.py +++ b/cea/config.py @@ -542,6 +542,8 @@ def decode(self, value): class WeatherPathParameter(Parameter): + THIRD_PARTY_WEATHER_SOURCES = ['climate.onebuilding.org'] + def initialize(self, parser): self._locator = None # cache the InputLocator in case we need it again as they can be expensive to create self._extensions = ['epw'] @@ -563,6 +565,8 @@ def decode(self, value): # allow using shortcuts weather_path = self.locator.get_weather( [w for w in self.locator.get_weather_names() if w.lower().startswith(value.lower())][0]) + elif value in self.THIRD_PARTY_WEATHER_SOURCES: + weather_path = value else: raise cea.ConfigError(f"Invalid weather path: {value}") return weather_path diff --git a/cea/datamanagement/weather_helper/weather_helper.py b/cea/datamanagement/weather_helper/weather_helper.py index 1b9a35fd5d..00f3f4e658 100644 --- a/cea/datamanagement/weather_helper/weather_helper.py +++ b/cea/datamanagement/weather_helper/weather_helper.py @@ -85,7 +85,7 @@ def main(config): locator = cea.inputlocator.InputLocator(config.scenario) weather = config.weather_helper.weather - if config.weather_helper.weather == "": + if config.weather_helper.weather == 'climate.onebuilding.org': print("No weather provided, fetching from online sources.") fetch_weather_data(locator.get_weather_file(), locator.get_zone_geometry()) else: diff --git a/cea/scripts.yml b/cea/scripts.yml index 789028367f..2bfff4d5b6 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -18,6 +18,8 @@ Data management: interfaces: [cli, dashboard] module: cea.datamanagement.weather_helper parameters: ['general:scenario', weather-helper] + input-files: + - [ get_zone_geometry ] - name: surroundings-helper label: Surroundings helper From 59c4c7986e0d60de6f8a47d3dc0b4b3d09803481 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:59:29 +0200 Subject: [PATCH 061/103] Check if path exists before creating scenario --- cea/interfaces/dashboard/api/project.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 482b81d02a..e59b2ee25c 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -149,6 +149,14 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): # Temporary endpoint to prevent breaking existing frontend @router.post('/scenario/v2') async def create_new_scenario_v2(scenario_form: CreateScenario): + new_scenario_path = secure_path(os.path.join(scenario_form.project, str(scenario_form.scenario_name).strip())) + + if os.path.exists(new_scenario_path): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Scenario already exists - project: {scenario_form.project}, scenario_name: {scenario_form.scenario_name}', + ) + with tempfile.TemporaryDirectory() as tmp: # Create temporary project before copying to actual scenario path config = cea.config.Configuration(cea.config.DEFAULT_CONFIG) @@ -237,7 +245,6 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): cea.api.archetypes_mapper(config) # Move temp scenario to correct path - new_scenario_path = secure_path(os.path.join(scenario_form.project, str(scenario_form.scenario_name).strip())) print(f"Moving from {config.scenario} to {new_scenario_path}") shutil.move(config.scenario, new_scenario_path) From c2b8d24a0a73852d3a2f432e9b1e08b5efe62f18 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:11:13 +0200 Subject: [PATCH 062/103] Verify user provided typology --- cea/interfaces/dashboard/api/geometry.py | 2 +- cea/interfaces/dashboard/api/project.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index 9a29e1983f..3fd28346a4 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -82,7 +82,7 @@ async def validate_typology(data: ValidateTypology): raise HTTPException(status_code=400, detail="Missing path") try: - typology_df = dbf_to_dataframe(data.path) + typology_df = gpd.read_file(data.path) verify_input_typology(typology_df) print(typology_df) except Exception as e: diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index e59b2ee25c..ab00bf0887 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -17,7 +17,7 @@ import cea.inputlocator from cea.datamanagement.create_new_scenario import generate_default_typology, copy_typology, copy_terrain from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ - verify_input_typology, verify_input_terrain + verify_input_typology from cea.datamanagement.surroundings_helper import generate_empty_surroundings from cea.interfaces.dashboard.dependencies import CEAConfig from cea.interfaces.dashboard.utils import secure_path @@ -149,6 +149,7 @@ async def update_project(config: CEAConfig, scenario_path: ScenarioPath): # Temporary endpoint to prevent breaking existing frontend @router.post('/scenario/v2') async def create_new_scenario_v2(scenario_form: CreateScenario): + print(f'ScenarioForm: {scenario_form}') new_scenario_path = secure_path(os.path.join(scenario_form.project, str(scenario_form.scenario_name).strip())) if os.path.exists(new_scenario_path): @@ -215,6 +216,9 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): generate_default_typology(zone_df, locator) elif scenario_form.typology is not None: # Copy typology using path + typology_df = geopandas.read_file(scenario_form.typology) + verify_input_typology(typology_df) + locator.ensure_parent_folder_exists(locator.get_building_typology()) copy_typology(scenario_form.typology, locator) From 2456fbd95e9e81495cbd3c17740b62a948495559 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:35:47 +0200 Subject: [PATCH 063/103] Try extracting typology from zone --- cea/interfaces/dashboard/api/project.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index ab00bf0887..8a1d238723 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -17,11 +17,12 @@ import cea.inputlocator from cea.datamanagement.create_new_scenario import generate_default_typology, copy_typology, copy_terrain from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ - verify_input_typology + verify_input_typology, COLUMNS_ZONE_TYPOLOGY from cea.datamanagement.surroundings_helper import generate_empty_surroundings from cea.interfaces.dashboard.dependencies import CEAConfig from cea.interfaces.dashboard.utils import secure_path from cea.plots.colors import color_to_rgb +from cea.utilities.dbf import dataframe_to_dbf from cea.utilities.standardize_coordinates import get_geographic_coordinate_system router = APIRouter() @@ -210,17 +211,30 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(surroundings_path) surroundings_df.to_file(surroundings_path) + locator.ensure_parent_folder_exists(locator.get_building_typology()) if scenario_form.should_generate_typology(): # Generate using default typology - locator.ensure_parent_folder_exists(locator.get_building_typology()) generate_default_typology(zone_df, locator) elif scenario_form.typology is not None: # Copy typology using path typology_df = geopandas.read_file(scenario_form.typology) verify_input_typology(typology_df) - - locator.ensure_parent_folder_exists(locator.get_building_typology()) copy_typology(scenario_form.typology, locator) + else: + # Try extracting typology from zone + print(f'Trying to extract typology from zone') + try: + verify_input_typology(zone_df) + except Exception as e: + print(f'Could not extract typology from zone: {e}') + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Not enough information to generate typology file', + ) + + typology_df = zone_df[COLUMNS_ZONE_TYPOLOGY] + dataframe_to_dbf(typology_df, locator.get_building_typology()) + print(f'Typology file created at {locator.get_building_typology()}') # Run weather helper config.weather_helper.weather = scenario_form.weather From 46fb43a81d54a98c86dec32215c0e620b5d702f8 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:07:02 +0200 Subject: [PATCH 064/103] Ignore using secure databases_path and only allow the default databases_path --- cea/interfaces/dashboard/api/project.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 8a1d238723..5f89983f72 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -15,6 +15,7 @@ import cea.config import cea.api import cea.inputlocator +from cea.databases import get_regions, databases_folder_path from cea.datamanagement.create_new_scenario import generate_default_typology, copy_typology, copy_terrain from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ verify_input_typology, COLUMNS_ZONE_TYPOLOGY @@ -286,9 +287,16 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): detail='scenario_name parameter cannot be empty', ) - databases_path = secure_path(payload.get('databases_path')) + databases_path = payload.get('databases_path') input_data = payload.get('input_data') + # Ignore using secure databases_path and only allow the default databases_path + if databases_path not in (os.path.join(databases_folder_path, region) for region in get_regions()): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f'Invalid databases_path: {databases_path}', + ) + with tempfile.TemporaryDirectory() as tmp: config.project = tmp config.scenario_name = "temp_scenario" From f5ef0416a8209a41c18d48164a814267a2a1dfff Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:00:49 +0200 Subject: [PATCH 065/103] Fix generate typology logic --- cea/interfaces/dashboard/api/project.py | 40 +++++++++++++------------ 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 5f89983f72..1ac8ea5e94 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -212,25 +212,27 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(surroundings_path) surroundings_df.to_file(surroundings_path) - locator.ensure_parent_folder_exists(locator.get_building_typology()) - if scenario_form.should_generate_typology(): - # Generate using default typology - generate_default_typology(zone_df, locator) - elif scenario_form.typology is not None: - # Copy typology using path - typology_df = geopandas.read_file(scenario_form.typology) - verify_input_typology(typology_df) - copy_typology(scenario_form.typology, locator) - else: - # Try extracting typology from zone - print(f'Trying to extract typology from zone') - try: - verify_input_typology(zone_df) - except Exception as e: - print(f'Could not extract typology from zone: {e}') - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail='Not enough information to generate typology file', + # Only process typology if zone is not generated + if not scenario_form.should_generate_zone(): + locator.ensure_parent_folder_exists(locator.get_building_typology()) + if scenario_form.should_generate_typology(): + # Generate using default typology + generate_default_typology(zone_df, locator) + elif scenario_form.typology is not None: + # Copy typology using path + typology_df = geopandas.read_file(scenario_form.typology) + verify_input_typology(typology_df) + copy_typology(scenario_form.typology, locator) + else: + # Try extracting typology from zone + print(f'Trying to extract typology from zone') + try: + verify_input_typology(zone_df) + except Exception as e: + print(f'Could not extract typology from zone: {e}') + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Not enough information to generate typology file', ) typology_df = zone_df[COLUMNS_ZONE_TYPOLOGY] From 983335329acdaafc46fb48a066690ea1445c291b Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:38:53 +0200 Subject: [PATCH 066/103] Raise HTTPException instead of Exception There is currently no default exception handler for each route. Throwing an exception would cause the server to not return the error message correctly. --- cea/interfaces/dashboard/api/project.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 1ac8ea5e94..041dda19cf 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -312,7 +312,10 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): try: cea.api.data_initializer(config, databases_path=databases_path) except Exception as e: - raise Exception(f'data_initializer: {e}') from e + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'data_initializer: {e}', + ) from e if input_data == 'import': files = payload.get('files') @@ -329,7 +332,10 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): terrain=files.get('terrain'), typology=files.get('typology')) except Exception as e: - raise Exception(f'create_new_scenario: {e}') from e + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'create_new_scenario: {e}', + ) from e elif input_data == 'copy': source_scenario_name = payload.get('copy_scenario') @@ -363,7 +369,10 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): elif tool == 'weather': cea.api.weather_helper(config) except Exception as e: - raise Exception(f'{tool}_helper: {e}') from e + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'{tool}_helper: {e}', + ) from e # Move temp scenario to correct path new_scenario_path = secure_path(os.path.join(_project, str(scenario_name).strip())) From a6149cc76d8864dc38d1dfca773498d2775d0341 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 00:00:27 +0200 Subject: [PATCH 067/103] Fetch weather as default if weather is not set --- cea/interfaces/dashboard/api/project.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 041dda19cf..d5bc31e2f9 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -367,6 +367,10 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): elif tool == 'terrain': cea.api.terrain_helper(config) elif tool == 'weather': + # Fetch weather as default if weather is not set + # (old versions of GUI might return empty string as default) + if config.weather_helper.weather is "": + config.weather_helper.weather = "climate.onebuilding.org" cea.api.weather_helper(config) except Exception as e: raise HTTPException( From 6d2ebf065ee4fdd293c5750702ef3e518573262b Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 00:39:49 +0200 Subject: [PATCH 068/103] Resolve path to template folder --- cea/interfaces/dashboard/plots/routes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/plots/routes.py b/cea/interfaces/dashboard/plots/routes.py index f93c4ac0cf..90def8ffda 100644 --- a/cea/interfaces/dashboard/plots/routes.py +++ b/cea/interfaces/dashboard/plots/routes.py @@ -1,4 +1,5 @@ import re +from pathlib import Path from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse @@ -13,7 +14,8 @@ router = APIRouter() -templates = Jinja2Templates(directory="templates") +dir_path = Path(__file__).resolve().parent +templates = Jinja2Templates(directory=str(Path(dir_path, 'templates'))) def script_suggestions(locator_names): From 8f64f0eeef1ed22efdaa3fc61502d8954ec16c7a Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 01:19:44 +0200 Subject: [PATCH 069/103] Return error status code for frontend --- cea/interfaces/dashboard/plots/routes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/plots/routes.py b/cea/interfaces/dashboard/plots/routes.py index 90def8ffda..3238145f9b 100644 --- a/cea/interfaces/dashboard/plots/routes.py +++ b/cea/interfaces/dashboard/plots/routes.py @@ -45,7 +45,9 @@ def render_missing_data(request, missing_files): context={ "missing_input_files": [lm(*args) for lm, args in missing_files], "script_suggestions": script_suggestions(lm.__name__ for lm, _ in missing_files) - } + }, + # TODO: Change to 400 code after frontend is updated + status_code=404 ) From 53a85c459ad6176e341b8e887da936576a4352cd Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 02:10:41 +0200 Subject: [PATCH 070/103] Add query param to read geometry from path --- cea/interfaces/dashboard/api/geometry.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index 3fd28346a4..119ea383bb 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -9,13 +9,14 @@ from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ verify_input_typology +from cea.interfaces.dashboard.utils import secure_path from cea.utilities.dbf import dbf_to_dataframe router = APIRouter() @router.get("/buildings") -async def fetch_buildings(generate: bool = False, polygon: str = None): +async def fetch_buildings(generate: bool = False, polygon: str = None, path: str = None): if generate: if polygon is None: return HTTPException(status_code=400, detail="Missing polygon") @@ -36,6 +37,16 @@ async def fetch_buildings(generate: bool = False, polygon: str = None): print(e) return HTTPException(status_code=500, detail=str(e)) + elif path is not None: + try: + _path = secure_path(path) + buildings = gpd.read_file(_path).to_crs("epsg:4326") + + return json.loads(buildings.to_json()) + except Exception as e: + print(e) + return HTTPException(status_code=500, detail=str(e)) + class ValidateGeometry(BaseModel): type: Literal['path', 'file'] From dca13ef35e7dfe2b77dda4c747895e9f48eeb9c4 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 02:27:11 +0200 Subject: [PATCH 071/103] Fix error with trailing slash in path We have to compare real path of project root with real path of provided path. --- cea/interfaces/dashboard/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/utils.py b/cea/interfaces/dashboard/utils.py index 8896d94630..e04c502e19 100644 --- a/cea/interfaces/dashboard/utils.py +++ b/cea/interfaces/dashboard/utils.py @@ -11,7 +11,7 @@ def secure_path(path: str) -> str: """ Simple sanitation of path """ - project_root = get_settings().project_root + project_root = os.path.realpath(get_settings().project_root) real_path = os.path.realpath(path) if project_root != "": From 0d29f64b8d37d9270f27acef6744c55a0dd1f4e2 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:22:46 +0200 Subject: [PATCH 072/103] Pass project list if transversal is not permitted --- cea/interfaces/dashboard/api/project.py | 23 +++++++++++++++++++++-- cea/interfaces/dashboard/utils.py | 5 +++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index d5bc31e2f9..68d87433d7 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -21,6 +21,7 @@ verify_input_typology, COLUMNS_ZONE_TYPOLOGY from cea.datamanagement.surroundings_helper import generate_empty_surroundings from cea.interfaces.dashboard.dependencies import CEAConfig +from cea.interfaces.dashboard.settings import get_settings from cea.interfaces.dashboard.utils import secure_path from cea.plots.colors import color_to_rgb from cea.utilities.dbf import dataframe_to_dbf @@ -90,8 +91,26 @@ async def get_project_info(config: CEAConfig, project: str = None): config.project = project scenario_name = None - return {'project_name': os.path.basename(config.project), 'project': config.project, - 'scenario_name': scenario_name, 'scenarios_list': list_scenario_names_for_project(config)} + # FIXME: This exposes the project path to the frontend. Should be removed. + project_info = { + 'project_name': os.path.basename(config.project), + 'project': config.project, + 'scenario_name': scenario_name, + 'scenarios_list': list_scenario_names_for_project(config) + } + + # List projects if no path transversal is allowed + if not get_settings().allow_path_transversal(): + def valid_project(project_name): + return not project_name.startswith(".") + + projects = [ + project_name for project_name in os.listdir(get_settings().project_root) + if valid_project(project_name) + ] + project_info['projects'] = projects + + return project_info @router.post('/') diff --git a/cea/interfaces/dashboard/utils.py b/cea/interfaces/dashboard/utils.py index e04c502e19..2592bdd5e0 100644 --- a/cea/interfaces/dashboard/utils.py +++ b/cea/interfaces/dashboard/utils.py @@ -11,10 +11,11 @@ def secure_path(path: str) -> str: """ Simple sanitation of path """ - project_root = os.path.realpath(get_settings().project_root) real_path = os.path.realpath(path) - if project_root != "": + if not get_settings().allow_path_transversal(): + project_root = os.path.realpath(get_settings().project_root) + prefix = os.path.commonpath((project_root, real_path)) if project_root != prefix: raise InvalidPathError("Path is outside of project root") From cf60ca8d4a6e56a62fe52282228fadf8d9662f4d Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 11:35:21 +0200 Subject: [PATCH 073/103] Fix missing function --- cea/interfaces/dashboard/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cea/interfaces/dashboard/settings.py b/cea/interfaces/dashboard/settings.py index 0f414f4c91..9c65a4168b 100644 --- a/cea/interfaces/dashboard/settings.py +++ b/cea/interfaces/dashboard/settings.py @@ -14,7 +14,11 @@ class Settings(BaseSettings): worker_url: Optional[str] = None project_root: Optional[str] = None + def allow_path_transversal(self) -> bool: + return self.project_root == "" + +# FIXME: Settings does not load from cea config @lru_cache def get_settings(): return Settings() From 5947742e67dfd038b689d39e107c083adbdbfb50 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:06:00 +0200 Subject: [PATCH 074/103] Extract reference case as default project --- Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3734c7a458..0f961c5934 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,8 +56,12 @@ ARG MAMBA_DOCKERFILE_ACTIVATE=1 COPY --chown=$MAMBA_USER:$MAMBA_USER . /tmp/cea RUN pip install /tmp/cea +# extract reference case +RUN cea extract-reference-case --destination /project + # write config files -RUN cea-config write --general:project /project \ +RUN cea-config write --general:project /project/reference-case-open \ + && cea-config write --general:scenario-name baseline \ && cea-config write --radiation:daysim-bin-directory /Daysim \ && cea-config write --server:host 0.0.0.0 # required for flask to receive requests from the docker host From af75cfdc31f0c28040e74aecd0a48c62bbf0d646 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:11:30 +0200 Subject: [PATCH 075/103] Ignore mac folders --- cea/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cea/config.py b/cea/config.py index 5be62c2009..b3f30a179b 100644 --- a/cea/config.py +++ b/cea/config.py @@ -1132,9 +1132,11 @@ def is_valid_scenario(folder_name): """ folder_path = os.path.join(project_path, folder_name) + # TODO: Use .gitignore to ignore scenarios return all([os.path.isdir(folder_path), not folder_name.startswith('.'), - folder_name != "__pycache__"]) + folder_name != "__pycache__", + folder_name != "__MACOSX"]) return [folder_name for folder_name in os.listdir(project_path) if is_valid_scenario(folder_name)] From a23c9ce98b7e5ad653dc2322caaa087f9d831909 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:41:16 +0200 Subject: [PATCH 076/103] Remove reference case due to larger image size --- Dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0f961c5934..b975afe784 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,9 +56,6 @@ ARG MAMBA_DOCKERFILE_ACTIVATE=1 COPY --chown=$MAMBA_USER:$MAMBA_USER . /tmp/cea RUN pip install /tmp/cea -# extract reference case -RUN cea extract-reference-case --destination /project - # write config files RUN cea-config write --general:project /project/reference-case-open \ && cea-config write --general:scenario-name baseline \ From 59a3ae3898378fae76513f7bf79c3cf8cbdab4b1 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Wed, 4 Sep 2024 00:04:55 +0200 Subject: [PATCH 077/103] Fix equality sign --- cea/interfaces/dashboard/api/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 68d87433d7..172238711a 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -388,7 +388,7 @@ async def create_new_scenario(config: CEAConfig, payload: Dict[str, Any]): elif tool == 'weather': # Fetch weather as default if weather is not set # (old versions of GUI might return empty string as default) - if config.weather_helper.weather is "": + if config.weather_helper.weather == "": config.weather_helper.weather = "climate.onebuilding.org" cea.api.weather_helper(config) except Exception as e: From cb63b3125824a9e3acae950ca3f451c7c5cec3a6 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:48:20 +0200 Subject: [PATCH 078/103] Change building colours --- cea/interfaces/dashboard/api/inputs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/api/inputs.py b/cea/interfaces/dashboard/api/inputs.py index d2bcb3b837..b38f0f8468 100644 --- a/cea/interfaces/dashboard/api/inputs.py +++ b/cea/interfaces/dashboard/api/inputs.py @@ -30,10 +30,10 @@ router = APIRouter() COLORS = { - 'surroundings': get_color_array('white'), + 'surroundings': get_color_array('grey_light'), 'dh': get_color_array('red'), 'dc': get_color_array('blue'), - 'disconnected': get_color_array('grey') + 'disconnected': get_color_array('white') } # List of input databases (db_name, locator/schema_key) From cd47cd706a98753b9974dccf600aef5ab4819068 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:49:23 +0200 Subject: [PATCH 079/103] Extract solar radiation to its own category --- cea/scripts.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index 2bfff4d5b6..1b11c032e3 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -59,7 +59,7 @@ Data management: - [ get_zone_geometry ] - [ get_terrain ] -Demand forecasting: +Solar radiation: - name: radiation label: Building solar radiation description: Use Daysim to calculate solar radiation for a scenario @@ -93,6 +93,7 @@ Demand forecasting: - [ get_terrain ] - [ get_weather_file ] +Demand forecasting: - name: schedule-maker label: Building occupancy description: Use CEA models and input schedules to estimate the occupancy profile of buildings From 617119c621f128ee5d1a691cd9acc765f368c7ee Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:26:48 +0200 Subject: [PATCH 080/103] Remove unused import --- cea/interfaces/dashboard/api/geometry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index 119ea383bb..294404a9d9 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -10,7 +10,6 @@ from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ verify_input_typology from cea.interfaces.dashboard.utils import secure_path -from cea.utilities.dbf import dbf_to_dataframe router = APIRouter() From b64301cedeeaf84d4f52a0769b38c0e02ef8f0e0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:27:35 +0200 Subject: [PATCH 081/103] Add endpoint to check for script input files --- cea/interfaces/dashboard/api/tools.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/tools.py b/cea/interfaces/dashboard/api/tools.py index d8ee769b34..6798517fff 100644 --- a/cea/interfaces/dashboard/api/tools.py +++ b/cea/interfaces/dashboard/api/tools.py @@ -2,11 +2,12 @@ from itertools import groupby from typing import Dict, Any, List -from fastapi import APIRouter +from fastapi import APIRouter, HTTPException from pydantic import BaseModel import cea.config import cea.scripts +from cea.schemas import schemas from .utils import deconstruct_parameters from cea.interfaces.dashboard.dependencies import CEAConfig @@ -87,6 +88,30 @@ async def save_tool_config(config: CEAConfig, tool_name: str, payload: Dict[str, return 'Success' +@router.get('/{tool_name}/check') +async def check_tool_inputs(config: CEAConfig, tool_name: str): + script = cea.scripts.by_name(tool_name, plugins=config.plugins) + schema_data = schemas(config.plugins) + + script_suggestions = set() + + for method_name, path in script.missing_input_files(config): + _script_suggestions = schema_data[method_name]['created_by'] if 'created_by' in schema_data[method_name] else None + + if _script_suggestions is not None: + script_suggestions.update(_script_suggestions) + + if script_suggestions: + scripts = [] + for script_suggestion in script_suggestions: + _script = cea.scripts.by_name(script_suggestion, plugins=config.plugins) + scripts.append({"label": _script.label, "name": _script.name}) + + raise HTTPException(status_code=400, + detail={"message": "Missing input files", + "script_suggestions": list(scripts)}) + + def parameters_for_script(script_name, config): """Return a list consisting of :py:class:`cea.config.Parameter` objects for each parameter of a script""" parameters = [p for _, p in config.matching_parameters( From b9ae40351c7a998e141b2e5091d3bd3e7a36e6f7 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:45:03 +0200 Subject: [PATCH 082/103] Write missing config to env file --- cea/interfaces/dashboard/dashboard.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 5c06c6bfa0..0a76dbc5ac 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -1,4 +1,5 @@ import sys +import tempfile import uvicorn @@ -8,6 +9,7 @@ def main(config): # Try loading settings from env vars first settings = get_settings() + config_dict = dict() # Load from config if not found in env vars if settings.host is None: @@ -18,15 +20,24 @@ def main(config): if settings.worker_url is None: settings.worker_url = config.worker.url + config_dict["worker_url"] = config.worker.url if settings.project_root is None: settings.project_root = config.server.project_root + config_dict["project_root"] = config.server.project_root print(f"Using settings: {settings}") try: - uvicorn.run("cea.interfaces.dashboard.app:app", - host=settings.host, port=settings.port) + # Write missing settings to temp env file + with tempfile.NamedTemporaryFile(mode="w") as f: + for key, value in config_dict.items(): + f.write(f"CEA_{key.upper()}={value}\n") + f.flush() + + uvicorn.run("cea.interfaces.dashboard.app:app", + env_file=f.name, + host=settings.host, port=settings.port, reload=True) except KeyboardInterrupt: sys.exit(0) From 87119e1e11f53ca2ba2f94c6282c56c3bc71912e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:13:58 +0200 Subject: [PATCH 083/103] Remove anchor element due to removed url path --- .../dashboard/plots/templates/missing_input_files.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/plots/templates/missing_input_files.html b/cea/interfaces/dashboard/plots/templates/missing_input_files.html index 64d0500d68..bfc43bf56f 100644 --- a/cea/interfaces/dashboard/plots/templates/missing_input_files.html +++ b/cea/interfaces/dashboard/plots/templates/missing_input_files.html @@ -8,7 +8,8 @@

Try running these scripts first:

    {% for script in script_suggestions %} -
  • {{script.label}}
  • + +
  • {{script.label}}
  • {% endfor %}
{% endif %} From 72e048bce354f3e6d426c8cc2134418884e11d8e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:14:59 +0200 Subject: [PATCH 084/103] Extract each step into their own function Also added logic to make sure user-provided typology column names are in correct case --- cea/interfaces/dashboard/api/project.py | 105 ++++++++++++++++-------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 172238711a..9d44e6f05c 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -179,16 +179,7 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): detail=f'Scenario already exists - project: {scenario_form.project}, scenario_name: {scenario_form.scenario_name}', ) - with tempfile.TemporaryDirectory() as tmp: - # Create temporary project before copying to actual scenario path - config = cea.config.Configuration(cea.config.DEFAULT_CONFIG) - config.project = tmp - config.scenario_name = "temp_scenario" - locator = cea.inputlocator.InputLocator(config.scenario) - - # Run database_initializer to copy databases to input - cea.api.data_initializer(config, databases_path=scenario_form.database) - + def create_zone(scenario_form): # Generate / Copy zone and surroundings if scenario_form.should_generate_zone(): site_geojson = scenario_form.generate_zone @@ -211,6 +202,9 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(zone_path) zone_df.to_file(zone_path) + return zone_df + + def create_surroundings(scenario_form, zone_df): if scenario_form.should_generate_surroundings(): # Generate using surroundings helper config.surroundings_helper.buffer = scenario_form.generate_surroundings @@ -231,37 +225,49 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(surroundings_path) surroundings_df.to_file(surroundings_path) + def create_typology(scenario_form, zone_df): # Only process typology if zone is not generated - if not scenario_form.should_generate_zone(): - locator.ensure_parent_folder_exists(locator.get_building_typology()) - if scenario_form.should_generate_typology(): - # Generate using default typology - generate_default_typology(zone_df, locator) - elif scenario_form.typology is not None: - # Copy typology using path - typology_df = geopandas.read_file(scenario_form.typology) - verify_input_typology(typology_df) - copy_typology(scenario_form.typology, locator) - else: - # Try extracting typology from zone - print(f'Trying to extract typology from zone') - try: - verify_input_typology(zone_df) - except Exception as e: - print(f'Could not extract typology from zone: {e}') - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail='Not enough information to generate typology file', - ) + if scenario_form.should_generate_zone(): + return + + locator.ensure_parent_folder_exists(locator.get_building_typology()) + if scenario_form.should_generate_typology(): + # Generate using default typology + generate_default_typology(zone_df, locator) + elif scenario_form.typology is not None: + # Copy typology using path + typology_df = geopandas.read_file(scenario_form.typology) + + # Make sure typology column names are in correct case + typology_df.columns = [col.lower() for col in typology_df.columns] + rename_dict = {col.lower(): col for col in COLUMNS_ZONE_TYPOLOGY} + typology_df.rename(columns=rename_dict, inplace=True) + + verify_input_typology(typology_df) + copy_typology(scenario_form.typology, locator) + else: + # Try extracting typology from zone + print(f'Trying to extract typology from zone') + + # Make sure typology column names are in correct case + zone_df.columns = [col.lower() for col in zone_df.columns] + rename_dict = {col.lower(): col for col in COLUMNS_ZONE_TYPOLOGY} + zone_df.rename(columns=rename_dict, inplace=True) + + try: + verify_input_typology(zone_df) + except Exception as e: + print(f'Could not extract typology from zone: {e}') + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Not enough information to generate typology file. Check zone file for typology.', + ) typology_df = zone_df[COLUMNS_ZONE_TYPOLOGY] dataframe_to_dbf(typology_df, locator.get_building_typology()) print(f'Typology file created at {locator.get_building_typology()}') - # Run weather helper - config.weather_helper.weather = scenario_form.weather - cea.api.weather_helper(config) - + def create_terrain(scenario_form, zone_df): if scenario_form.should_generate_terrain(): # Run terrain helper cea.api.terrain_helper(config) @@ -272,6 +278,7 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(locator.get_terrain()) copy_terrain(scenario_form.terrain, locator, lat, lon) + def create_street(scenario_form): if scenario_form.should_generate_street(): # Run street helper cea.api.streets_helper(config) @@ -281,6 +288,34 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): locator.ensure_parent_folder_exists(locator.get_street_network()) street_df.to_file(locator.get_street_network()) + with tempfile.TemporaryDirectory() as tmp: + # Create temporary project before copying to actual scenario path + config = cea.config.Configuration(cea.config.DEFAULT_CONFIG) + config.project = tmp + config.scenario_name = "temp_scenario" + locator = cea.inputlocator.InputLocator(config.scenario) + + # Run database_initializer to copy databases to input + cea.api.data_initializer(config, databases_path=scenario_form.database) + + # Generate / Copy zone + zone_df = create_zone(scenario_form) + + # Generate / Copy surroundings + create_surroundings(scenario_form, zone_df) + + create_typology(scenario_form, zone_df) + + # Run weather helper + config.weather_helper.weather = scenario_form.weather + cea.api.weather_helper(config) + + # Generate / Copy terrain + create_terrain(scenario_form, zone_df) + + # Generate / Copy street + create_street(scenario_form) + # Run archetypes mapper cea.api.archetypes_mapper(config) From 4d9876b9c35c0fefab4063b584f1acc4030e6882 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:26:00 +0200 Subject: [PATCH 085/103] Support reading .csv and .xlsx --- cea/interfaces/dashboard/api/geometry.py | 10 ++++++++-- cea/interfaces/dashboard/api/project.py | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index 294404a9d9..b3122647fc 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -1,7 +1,9 @@ import json +import os from typing import Literal, Optional import osmnx +import pandas as pd from fastapi import APIRouter, HTTPException, status import geopandas as gpd @@ -91,10 +93,14 @@ async def validate_typology(data: ValidateTypology): if data.path is None: raise HTTPException(status_code=400, detail="Missing path") + _, extension = os.path.splitext(data.path) try: - typology_df = gpd.read_file(data.path) + if extension == ".xlsx": + typology_df = pd.read_excel(data.path) + else: + typology_df = gpd.read_file(data.path) + verify_input_typology(typology_df) - print(typology_df) except Exception as e: print(e) raise HTTPException( diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 9d44e6f05c..93c1cd6dcb 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -6,6 +6,7 @@ from typing import Dict, Any, Optional import geopandas +import pandas as pd from fastapi import APIRouter, HTTPException, status, Request, Path, Depends from pydantic import BaseModel from shapely.geometry import shape @@ -236,7 +237,11 @@ def create_typology(scenario_form, zone_df): generate_default_typology(zone_df, locator) elif scenario_form.typology is not None: # Copy typology using path - typology_df = geopandas.read_file(scenario_form.typology) + _, extension = os.path.splitext(scenario_form.typology) + if extension == ".xlsx": + typology_df = pd.read_excel(scenario_form.typology) + else: + typology_df = geopandas.read_file(scenario_form.typology) # Make sure typology column names are in correct case typology_df.columns = [col.lower() for col in typology_df.columns] From ba044e412fe68465097407a9fca8de52fed54869 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:37:05 +0200 Subject: [PATCH 086/103] Wrap all creating functions in try catch block --- cea/interfaces/dashboard/api/project.py | 69 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 93c1cd6dcb..226d4e88b7 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -180,7 +180,7 @@ async def create_new_scenario_v2(scenario_form: CreateScenario): detail=f'Scenario already exists - project: {scenario_form.project}, scenario_name: {scenario_form.scenario_name}', ) - def create_zone(scenario_form): + def create_zone(scenario_form, locator): # Generate / Copy zone and surroundings if scenario_form.should_generate_zone(): site_geojson = scenario_form.generate_zone @@ -205,7 +205,7 @@ def create_zone(scenario_form): return zone_df - def create_surroundings(scenario_form, zone_df): + def create_surroundings(scenario_form, zone_df, locator): if scenario_form.should_generate_surroundings(): # Generate using surroundings helper config.surroundings_helper.buffer = scenario_form.generate_surroundings @@ -226,7 +226,7 @@ def create_surroundings(scenario_form, zone_df): locator.ensure_parent_folder_exists(surroundings_path) surroundings_df.to_file(surroundings_path) - def create_typology(scenario_form, zone_df): + def create_typology(scenario_form, zone_df, locator): # Only process typology if zone is not generated if scenario_form.should_generate_zone(): return @@ -249,6 +249,15 @@ def create_typology(scenario_form, zone_df): typology_df.rename(columns=rename_dict, inplace=True) verify_input_typology(typology_df) + + # Check if typology index matches zone + if not typology_df["Name"].equals(zone_df["Name"]): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail='Typology buildings do not match zone buildings.' + 'Check buildings in typology file with zone file.', + ) + copy_typology(scenario_form.typology, locator) else: # Try extracting typology from zone @@ -265,14 +274,15 @@ def create_typology(scenario_form, zone_df): print(f'Could not extract typology from zone: {e}') raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail='Not enough information to generate typology file. Check zone file for typology.', + detail='Not enough information to generate typology file from zone file.' + 'Check zone file for the required typology.', ) typology_df = zone_df[COLUMNS_ZONE_TYPOLOGY] dataframe_to_dbf(typology_df, locator.get_building_typology()) print(f'Typology file created at {locator.get_building_typology()}') - def create_terrain(scenario_form, zone_df): + def create_terrain(scenario_form, zone_df, locator): if scenario_form.should_generate_terrain(): # Run terrain helper cea.api.terrain_helper(config) @@ -283,7 +293,7 @@ def create_terrain(scenario_form, zone_df): locator.ensure_parent_folder_exists(locator.get_terrain()) copy_terrain(scenario_form.terrain, locator, lat, lon) - def create_street(scenario_form): + def create_street(scenario_form, locator): if scenario_form.should_generate_street(): # Run street helper cea.api.streets_helper(config) @@ -293,6 +303,7 @@ def create_street(scenario_form): locator.ensure_parent_folder_exists(locator.get_street_network()) street_df.to_file(locator.get_street_network()) + with tempfile.TemporaryDirectory() as tmp: # Create temporary project before copying to actual scenario path config = cea.config.Configuration(cea.config.DEFAULT_CONFIG) @@ -300,33 +311,41 @@ def create_street(scenario_form): config.scenario_name = "temp_scenario" locator = cea.inputlocator.InputLocator(config.scenario) - # Run database_initializer to copy databases to input - cea.api.data_initializer(config, databases_path=scenario_form.database) + try: + # Run database_initializer to copy databases to input + cea.api.data_initializer(config, databases_path=scenario_form.database) - # Generate / Copy zone - zone_df = create_zone(scenario_form) + # Generate / Copy zone + zone_df = create_zone(scenario_form, locator) - # Generate / Copy surroundings - create_surroundings(scenario_form, zone_df) + # Generate / Copy surroundings + create_surroundings(scenario_form, zone_df, locator) - create_typology(scenario_form, zone_df) + create_typology(scenario_form, zone_df, locator) - # Run weather helper - config.weather_helper.weather = scenario_form.weather - cea.api.weather_helper(config) + # Run weather helper + config.weather_helper.weather = scenario_form.weather + cea.api.weather_helper(config) - # Generate / Copy terrain - create_terrain(scenario_form, zone_df) + # Generate / Copy terrain + create_terrain(scenario_form, zone_df, locator) - # Generate / Copy street - create_street(scenario_form) + # Generate / Copy street + create_street(scenario_form, locator) - # Run archetypes mapper - cea.api.archetypes_mapper(config) + # Run archetypes mapper + cea.api.archetypes_mapper(config) - # Move temp scenario to correct path - print(f"Moving from {config.scenario} to {new_scenario_path}") - shutil.move(config.scenario, new_scenario_path) + # Move temp scenario to correct path + print(f"Moving from {config.scenario} to {new_scenario_path}") + shutil.move(config.scenario, new_scenario_path) + except HTTPException as e: + raise e from e + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f'Uncaught exception: {e}', + ) from e return { 'message': 'Scenario created successfully', From 55e021fedd9027526c9381a97ca9bf5c39064290 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:50:48 +0200 Subject: [PATCH 087/103] Fix f-string without any placeholders --- cea/interfaces/dashboard/api/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 226d4e88b7..dccdf9aa13 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -261,7 +261,7 @@ def create_typology(scenario_form, zone_df, locator): copy_typology(scenario_form.typology, locator) else: # Try extracting typology from zone - print(f'Trying to extract typology from zone') + print('Trying to extract typology from zone') # Make sure typology column names are in correct case zone_df.columns = [col.lower() for col in zone_df.columns] From 0c9759c03937522d7fafded81d2c3c675f38946e Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:21:35 +0200 Subject: [PATCH 088/103] Fix unable to find setup tar when using prerelease tag Python creates the file as "cityenergyanalyst-4.0.0a0.tar.gz" instead of "cityenergyanalyst-4.0.0-alpha.tar.gz" --- .github/workflows/setup_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index 615f53deaf..b249950dd5 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -31,7 +31,7 @@ jobs: run: | python -m pip install build python -m build - mv dist/cityenergyanalyst-$CEA_VERSION.tar.gz setup/cityenergyanalyst.tar.gz + mv dist/cityenergyanalyst-*.tar.gz setup/cityenergyanalyst.tar.gz - name: Cache CEA env id: cache-env From 5e6a45697030c70377e3ab0ade8ab6a191ae207f Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:59:08 +0200 Subject: [PATCH 089/103] Make sure zone column names are in correct case --- cea/interfaces/dashboard/api/project.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index dccdf9aa13..4d061abf43 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -19,7 +19,7 @@ from cea.databases import get_regions, databases_folder_path from cea.datamanagement.create_new_scenario import generate_default_typology, copy_typology, copy_terrain from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ - verify_input_typology, COLUMNS_ZONE_TYPOLOGY + verify_input_typology, COLUMNS_ZONE_TYPOLOGY, COLUMNS_ZONE_GEOMETRY from cea.datamanagement.surroundings_helper import generate_empty_surroundings from cea.interfaces.dashboard.dependencies import CEAConfig from cea.interfaces.dashboard.settings import get_settings @@ -197,6 +197,12 @@ def create_zone(scenario_form, locator): else: # Copy zone using path zone_df = geopandas.read_file(scenario_form.user_zone).to_crs(get_geographic_coordinate_system()) + + # Make sure zone column names are in correct case + zone_df.columns = [col.lower() for col in zone_df.columns] + rename_dict = {col.lower(): col for col in COLUMNS_ZONE_GEOMETRY} + zone_df.rename(columns=rename_dict, inplace=True) + verify_input_geometry_zone(zone_df) zone_path = locator.get_zone_geometry() From 97e14e145112f2552a8ace4bf306774143a168ff Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:08:06 +0200 Subject: [PATCH 090/103] Update validation endpoints --- cea/interfaces/dashboard/api/geometry.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/api/geometry.py b/cea/interfaces/dashboard/api/geometry.py index b3122647fc..aefadb2e71 100644 --- a/cea/interfaces/dashboard/api/geometry.py +++ b/cea/interfaces/dashboard/api/geometry.py @@ -10,7 +10,7 @@ from pydantic import BaseModel from cea.datamanagement.databases_verification import verify_input_geometry_zone, verify_input_geometry_surroundings, \ - verify_input_typology + verify_input_typology, COLUMNS_ZONE_TYPOLOGY, COLUMNS_ZONE_GEOMETRY from cea.interfaces.dashboard.utils import secure_path router = APIRouter() @@ -66,6 +66,12 @@ async def validate_building_geometry(data: ValidateGeometry): building_df = gpd.read_file(data.path) print(building_df) if data.building == 'zone': + + # Make sure zone column names are in correct case + building_df.columns = [col.lower() for col in building_df.columns] + rename_dict = {col.lower(): col for col in COLUMNS_ZONE_GEOMETRY} + building_df.rename(columns=rename_dict, inplace=True) + verify_input_geometry_zone(building_df) elif data.building == 'surroundings': verify_input_geometry_surroundings(building_df) @@ -100,6 +106,12 @@ async def validate_typology(data: ValidateTypology): else: typology_df = gpd.read_file(data.path) + + # Make sure typology column names are in correct case + typology_df.columns = [col.lower() for col in typology_df.columns] + rename_dict = {col.lower(): col for col in COLUMNS_ZONE_TYPOLOGY} + typology_df.rename(columns=rename_dict, inplace=True) + verify_input_typology(typology_df) except Exception as e: print(e) From 35009fa0f9c8c6e2855f83492af92f7cc57c234b Mon Sep 17 00:00:00 2001 From: Zhongming Shi Date: Fri, 6 Sep 2024 23:40:14 +0200 Subject: [PATCH 091/103] update scripts british spelling, moving backwards - data management tools --- cea/scripts.yml | 144 ++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index 1b11c032e3..faa616eae7 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -1,65 +1,4 @@ -Data management: - - - name: archetypes-mapper - label: Archetypes mapper - description: Assign building properties and systems types from the Archetypes DataBase - interfaces: [cli, dashboard] - module: cea.datamanagement.archetypes_mapper - parameters: ['general:scenario', archetypes-mapper] - input-files: - - [get_zone_geometry] - - [get_building_typology] - - - name: weather-helper - label: Weather helper - description: | - Sets the weather file to use for simulation for a scenario. - Fetches data from third party sources if no file is provided by the user. - interfaces: [cli, dashboard] - module: cea.datamanagement.weather_helper - parameters: ['general:scenario', weather-helper] - input-files: - - [ get_zone_geometry ] - - - name: surroundings-helper - label: Surroundings helper - description: Query geometry of surrounding buildings from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.surroundings_helper - parameters: ['general:scenario', surroundings-helper] - input-files: - - [get_zone_geometry] - - - name: terrain-helper - label: Terrain helper - description: Query topography data from third party sources - interfaces: [cli, dashboard] - module: cea.datamanagement.terrain_helper - parameters: ['general:scenario', terrain-helper] - input-files: - - [get_zone_geometry] - - [get_surroundings_geometry] - - - name: streets-helper - label: Streets helper - description: Query streets geometry from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.streets_helper - parameters: ['general:scenario', streets-helper] - input-files: - - [get_surroundings_geometry] - - - name: trees-helper - label: Trees helper - description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. - interfaces: [ cli, dashboard ] - module: cea.datamanagement.trees_helper - parameters: [ 'general:scenario', trees-helper ] - input-files: - - [ get_zone_geometry ] - - [ get_terrain ] - -Solar radiation: +Solar Radiation: - name: radiation label: Building solar radiation description: Use Daysim to calculate solar radiation for a scenario @@ -93,7 +32,7 @@ Solar radiation: - [ get_terrain ] - [ get_weather_file ] -Demand forecasting: +Demand Forecasting: - name: schedule-maker label: Building occupancy description: Use CEA models and input schedules to estimate the occupancy profile of buildings @@ -137,7 +76,7 @@ Demand forecasting: - [get_radiation_building, building_name] - [get_schedule_model_file, building_name] -Life cycle analysis: +Life Cycle Analysis: - name: emissions label: Emissions @@ -162,7 +101,7 @@ Life cycle analysis: - [get_total_demand] - [get_building_supply] -Energy potentials: +Energy Potentials: - name: shallow-geothermal-potential label: Shallow geothermal potential description: Calculate the heat extracted from a geothermal probes (up to 50 m length) @@ -274,19 +213,19 @@ Networks: - [get_database_conversion_systems] - [get_weather_file] -Optimization: +Optimisation: - name: thermal-network-optimization - label: Thermal network optimization - description: Optimize network design variables (plant locations, layout,...) + label: Thermal network optimisation + description: Optimise network design variables (plant locations, layout,...) interfaces: [cli] module: cea.technologies.thermal_network.thermal_network_optimization parameters: ['general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', thermal-network-optimization] - name: decentralized - label: Supply system Part I (decentralized) - description: Run optimization for decentralized operation + label: Supply system Part I (decentralised) + description: Run optimisation for decentralised operation interfaces: [cli, dashboard] module: cea.optimization.preprocessing.decentralized_building_main parameters: ['general:scenario', 'decentralized', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free'] @@ -305,8 +244,8 @@ Optimization: # - [get_geothermal_potential] - name: optimization-new - label: Supply system part II (centralized) - description: This optimisation script is projected to replace 'Supply System Part II (centralized)', but is currently still in its final testing phase + label: Supply system part II (centralised) + description: This optimisation script is projected to replace 'Supply System Part II (centralised)', but is currently still in its final testing phase interfaces: [cli, dashboard] module: cea.optimization_new.domain parameters: ['general:debug', 'general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', @@ -412,6 +351,67 @@ Utilities: parameters: ["general:project", "general:scenario", "plots", "plots-comparisons", "plots-optimization", "plots-supply-system"] +Data management: + + - name: archetypes-mapper + label: Archetypes mapper + description: Assign building properties and systems types from the Archetypes DataBase + interfaces: [cli, dashboard] + module: cea.datamanagement.archetypes_mapper + parameters: ['general:scenario', archetypes-mapper] + input-files: + - [get_zone_geometry] + - [get_building_typology] + + - name: weather-helper + label: Weather helper + description: | + Sets the weather file to use for simulation for a scenario. + Fetches data from third party sources if no file is provided by the user. + interfaces: [cli, dashboard] + module: cea.datamanagement.weather_helper + parameters: ['general:scenario', weather-helper] + input-files: + - [ get_zone_geometry ] + + - name: surroundings-helper + label: Surroundings helper + description: Query geometry of surrounding buildings from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.surroundings_helper + parameters: ['general:scenario', surroundings-helper] + input-files: + - [get_zone_geometry] + + - name: terrain-helper + label: Terrain helper + description: Query topography data from third party sources + interfaces: [cli, dashboard] + module: cea.datamanagement.terrain_helper + parameters: ['general:scenario', terrain-helper] + input-files: + - [get_zone_geometry] + - [get_surroundings_geometry] + + - name: streets-helper + label: Streets helper + description: Query streets geometry from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.streets_helper + parameters: ['general:scenario', streets-helper] + input-files: + - [get_surroundings_geometry] + + - name: trees-helper + label: Trees helper + description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. + interfaces: [ cli, dashboard ] + module: cea.datamanagement.trees_helper + parameters: [ 'general:scenario', trees-helper ] + input-files: + - [ get_zone_geometry ] + - [ get_terrain ] + default: - name: multi-criteria-analysis From f2fe57ca2b56a75dde5538a93893bee114da0554 Mon Sep 17 00:00:00 2001 From: Zhongming Shi Date: Fri, 6 Sep 2024 23:42:54 +0200 Subject: [PATCH 092/103] Revert "update scripts" This reverts commit 35009fa0f9c8c6e2855f83492af92f7cc57c234b. --- cea/scripts.yml | 144 ++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index faa616eae7..1b11c032e3 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -1,4 +1,65 @@ -Solar Radiation: +Data management: + + - name: archetypes-mapper + label: Archetypes mapper + description: Assign building properties and systems types from the Archetypes DataBase + interfaces: [cli, dashboard] + module: cea.datamanagement.archetypes_mapper + parameters: ['general:scenario', archetypes-mapper] + input-files: + - [get_zone_geometry] + - [get_building_typology] + + - name: weather-helper + label: Weather helper + description: | + Sets the weather file to use for simulation for a scenario. + Fetches data from third party sources if no file is provided by the user. + interfaces: [cli, dashboard] + module: cea.datamanagement.weather_helper + parameters: ['general:scenario', weather-helper] + input-files: + - [ get_zone_geometry ] + + - name: surroundings-helper + label: Surroundings helper + description: Query geometry of surrounding buildings from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.surroundings_helper + parameters: ['general:scenario', surroundings-helper] + input-files: + - [get_zone_geometry] + + - name: terrain-helper + label: Terrain helper + description: Query topography data from third party sources + interfaces: [cli, dashboard] + module: cea.datamanagement.terrain_helper + parameters: ['general:scenario', terrain-helper] + input-files: + - [get_zone_geometry] + - [get_surroundings_geometry] + + - name: streets-helper + label: Streets helper + description: Query streets geometry from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.streets_helper + parameters: ['general:scenario', streets-helper] + input-files: + - [get_surroundings_geometry] + + - name: trees-helper + label: Trees helper + description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. + interfaces: [ cli, dashboard ] + module: cea.datamanagement.trees_helper + parameters: [ 'general:scenario', trees-helper ] + input-files: + - [ get_zone_geometry ] + - [ get_terrain ] + +Solar radiation: - name: radiation label: Building solar radiation description: Use Daysim to calculate solar radiation for a scenario @@ -32,7 +93,7 @@ Solar Radiation: - [ get_terrain ] - [ get_weather_file ] -Demand Forecasting: +Demand forecasting: - name: schedule-maker label: Building occupancy description: Use CEA models and input schedules to estimate the occupancy profile of buildings @@ -76,7 +137,7 @@ Demand Forecasting: - [get_radiation_building, building_name] - [get_schedule_model_file, building_name] -Life Cycle Analysis: +Life cycle analysis: - name: emissions label: Emissions @@ -101,7 +162,7 @@ Life Cycle Analysis: - [get_total_demand] - [get_building_supply] -Energy Potentials: +Energy potentials: - name: shallow-geothermal-potential label: Shallow geothermal potential description: Calculate the heat extracted from a geothermal probes (up to 50 m length) @@ -213,19 +274,19 @@ Networks: - [get_database_conversion_systems] - [get_weather_file] -Optimisation: +Optimization: - name: thermal-network-optimization - label: Thermal network optimisation - description: Optimise network design variables (plant locations, layout,...) + label: Thermal network optimization + description: Optimize network design variables (plant locations, layout,...) interfaces: [cli] module: cea.technologies.thermal_network.thermal_network_optimization parameters: ['general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', thermal-network-optimization] - name: decentralized - label: Supply system Part I (decentralised) - description: Run optimisation for decentralised operation + label: Supply system Part I (decentralized) + description: Run optimization for decentralized operation interfaces: [cli, dashboard] module: cea.optimization.preprocessing.decentralized_building_main parameters: ['general:scenario', 'decentralized', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free'] @@ -244,8 +305,8 @@ Optimisation: # - [get_geothermal_potential] - name: optimization-new - label: Supply system part II (centralised) - description: This optimisation script is projected to replace 'Supply System Part II (centralised)', but is currently still in its final testing phase + label: Supply system part II (centralized) + description: This optimisation script is projected to replace 'Supply System Part II (centralized)', but is currently still in its final testing phase interfaces: [cli, dashboard] module: cea.optimization_new.domain parameters: ['general:debug', 'general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', @@ -351,67 +412,6 @@ Utilities: parameters: ["general:project", "general:scenario", "plots", "plots-comparisons", "plots-optimization", "plots-supply-system"] -Data management: - - - name: archetypes-mapper - label: Archetypes mapper - description: Assign building properties and systems types from the Archetypes DataBase - interfaces: [cli, dashboard] - module: cea.datamanagement.archetypes_mapper - parameters: ['general:scenario', archetypes-mapper] - input-files: - - [get_zone_geometry] - - [get_building_typology] - - - name: weather-helper - label: Weather helper - description: | - Sets the weather file to use for simulation for a scenario. - Fetches data from third party sources if no file is provided by the user. - interfaces: [cli, dashboard] - module: cea.datamanagement.weather_helper - parameters: ['general:scenario', weather-helper] - input-files: - - [ get_zone_geometry ] - - - name: surroundings-helper - label: Surroundings helper - description: Query geometry of surrounding buildings from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.surroundings_helper - parameters: ['general:scenario', surroundings-helper] - input-files: - - [get_zone_geometry] - - - name: terrain-helper - label: Terrain helper - description: Query topography data from third party sources - interfaces: [cli, dashboard] - module: cea.datamanagement.terrain_helper - parameters: ['general:scenario', terrain-helper] - input-files: - - [get_zone_geometry] - - [get_surroundings_geometry] - - - name: streets-helper - label: Streets helper - description: Query streets geometry from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.streets_helper - parameters: ['general:scenario', streets-helper] - input-files: - - [get_surroundings_geometry] - - - name: trees-helper - label: Trees helper - description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. - interfaces: [ cli, dashboard ] - module: cea.datamanagement.trees_helper - parameters: [ 'general:scenario', trees-helper ] - input-files: - - [ get_zone_geometry ] - - [ get_terrain ] - default: - name: multi-criteria-analysis From 22fb56a6e1925066d63b7f3bdacaa71f9c1afe0a Mon Sep 17 00:00:00 2001 From: Zhongming Shi Date: Fri, 6 Sep 2024 23:44:54 +0200 Subject: [PATCH 093/103] Reapply "update scripts" This reverts commit f2fe57ca2b56a75dde5538a93893bee114da0554. --- cea/scripts.yml | 144 ++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index 1b11c032e3..faa616eae7 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -1,65 +1,4 @@ -Data management: - - - name: archetypes-mapper - label: Archetypes mapper - description: Assign building properties and systems types from the Archetypes DataBase - interfaces: [cli, dashboard] - module: cea.datamanagement.archetypes_mapper - parameters: ['general:scenario', archetypes-mapper] - input-files: - - [get_zone_geometry] - - [get_building_typology] - - - name: weather-helper - label: Weather helper - description: | - Sets the weather file to use for simulation for a scenario. - Fetches data from third party sources if no file is provided by the user. - interfaces: [cli, dashboard] - module: cea.datamanagement.weather_helper - parameters: ['general:scenario', weather-helper] - input-files: - - [ get_zone_geometry ] - - - name: surroundings-helper - label: Surroundings helper - description: Query geometry of surrounding buildings from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.surroundings_helper - parameters: ['general:scenario', surroundings-helper] - input-files: - - [get_zone_geometry] - - - name: terrain-helper - label: Terrain helper - description: Query topography data from third party sources - interfaces: [cli, dashboard] - module: cea.datamanagement.terrain_helper - parameters: ['general:scenario', terrain-helper] - input-files: - - [get_zone_geometry] - - [get_surroundings_geometry] - - - name: streets-helper - label: Streets helper - description: Query streets geometry from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.streets_helper - parameters: ['general:scenario', streets-helper] - input-files: - - [get_surroundings_geometry] - - - name: trees-helper - label: Trees helper - description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. - interfaces: [ cli, dashboard ] - module: cea.datamanagement.trees_helper - parameters: [ 'general:scenario', trees-helper ] - input-files: - - [ get_zone_geometry ] - - [ get_terrain ] - -Solar radiation: +Solar Radiation: - name: radiation label: Building solar radiation description: Use Daysim to calculate solar radiation for a scenario @@ -93,7 +32,7 @@ Solar radiation: - [ get_terrain ] - [ get_weather_file ] -Demand forecasting: +Demand Forecasting: - name: schedule-maker label: Building occupancy description: Use CEA models and input schedules to estimate the occupancy profile of buildings @@ -137,7 +76,7 @@ Demand forecasting: - [get_radiation_building, building_name] - [get_schedule_model_file, building_name] -Life cycle analysis: +Life Cycle Analysis: - name: emissions label: Emissions @@ -162,7 +101,7 @@ Life cycle analysis: - [get_total_demand] - [get_building_supply] -Energy potentials: +Energy Potentials: - name: shallow-geothermal-potential label: Shallow geothermal potential description: Calculate the heat extracted from a geothermal probes (up to 50 m length) @@ -274,19 +213,19 @@ Networks: - [get_database_conversion_systems] - [get_weather_file] -Optimization: +Optimisation: - name: thermal-network-optimization - label: Thermal network optimization - description: Optimize network design variables (plant locations, layout,...) + label: Thermal network optimisation + description: Optimise network design variables (plant locations, layout,...) interfaces: [cli] module: cea.technologies.thermal_network.thermal_network_optimization parameters: ['general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', thermal-network-optimization] - name: decentralized - label: Supply system Part I (decentralized) - description: Run optimization for decentralized operation + label: Supply system Part I (decentralised) + description: Run optimisation for decentralised operation interfaces: [cli, dashboard] module: cea.optimization.preprocessing.decentralized_building_main parameters: ['general:scenario', 'decentralized', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free'] @@ -305,8 +244,8 @@ Optimization: # - [get_geothermal_potential] - name: optimization-new - label: Supply system part II (centralized) - description: This optimisation script is projected to replace 'Supply System Part II (centralized)', but is currently still in its final testing phase + label: Supply system part II (centralised) + description: This optimisation script is projected to replace 'Supply System Part II (centralised)', but is currently still in its final testing phase interfaces: [cli, dashboard] module: cea.optimization_new.domain parameters: ['general:debug', 'general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', @@ -412,6 +351,67 @@ Utilities: parameters: ["general:project", "general:scenario", "plots", "plots-comparisons", "plots-optimization", "plots-supply-system"] +Data management: + + - name: archetypes-mapper + label: Archetypes mapper + description: Assign building properties and systems types from the Archetypes DataBase + interfaces: [cli, dashboard] + module: cea.datamanagement.archetypes_mapper + parameters: ['general:scenario', archetypes-mapper] + input-files: + - [get_zone_geometry] + - [get_building_typology] + + - name: weather-helper + label: Weather helper + description: | + Sets the weather file to use for simulation for a scenario. + Fetches data from third party sources if no file is provided by the user. + interfaces: [cli, dashboard] + module: cea.datamanagement.weather_helper + parameters: ['general:scenario', weather-helper] + input-files: + - [ get_zone_geometry ] + + - name: surroundings-helper + label: Surroundings helper + description: Query geometry of surrounding buildings from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.surroundings_helper + parameters: ['general:scenario', surroundings-helper] + input-files: + - [get_zone_geometry] + + - name: terrain-helper + label: Terrain helper + description: Query topography data from third party sources + interfaces: [cli, dashboard] + module: cea.datamanagement.terrain_helper + parameters: ['general:scenario', terrain-helper] + input-files: + - [get_zone_geometry] + - [get_surroundings_geometry] + + - name: streets-helper + label: Streets helper + description: Query streets geometry from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.streets_helper + parameters: ['general:scenario', streets-helper] + input-files: + - [get_surroundings_geometry] + + - name: trees-helper + label: Trees helper + description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. + interfaces: [ cli, dashboard ] + module: cea.datamanagement.trees_helper + parameters: [ 'general:scenario', trees-helper ] + input-files: + - [ get_zone_geometry ] + - [ get_terrain ] + default: - name: multi-criteria-analysis From 0901e2f8cd5fa8a53cded2533a0753c31f11d992 Mon Sep 17 00:00:00 2001 From: Zhongming Shi Date: Fri, 6 Sep 2024 23:46:04 +0200 Subject: [PATCH 094/103] Revert "Reapply "update scripts"" This reverts commit 22fb56a6e1925066d63b7f3bdacaa71f9c1afe0a. --- cea/scripts.yml | 144 ++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/cea/scripts.yml b/cea/scripts.yml index faa616eae7..1b11c032e3 100644 --- a/cea/scripts.yml +++ b/cea/scripts.yml @@ -1,4 +1,65 @@ -Solar Radiation: +Data management: + + - name: archetypes-mapper + label: Archetypes mapper + description: Assign building properties and systems types from the Archetypes DataBase + interfaces: [cli, dashboard] + module: cea.datamanagement.archetypes_mapper + parameters: ['general:scenario', archetypes-mapper] + input-files: + - [get_zone_geometry] + - [get_building_typology] + + - name: weather-helper + label: Weather helper + description: | + Sets the weather file to use for simulation for a scenario. + Fetches data from third party sources if no file is provided by the user. + interfaces: [cli, dashboard] + module: cea.datamanagement.weather_helper + parameters: ['general:scenario', weather-helper] + input-files: + - [ get_zone_geometry ] + + - name: surroundings-helper + label: Surroundings helper + description: Query geometry of surrounding buildings from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.surroundings_helper + parameters: ['general:scenario', surroundings-helper] + input-files: + - [get_zone_geometry] + + - name: terrain-helper + label: Terrain helper + description: Query topography data from third party sources + interfaces: [cli, dashboard] + module: cea.datamanagement.terrain_helper + parameters: ['general:scenario', terrain-helper] + input-files: + - [get_zone_geometry] + - [get_surroundings_geometry] + + - name: streets-helper + label: Streets helper + description: Query streets geometry from Open Street Maps + interfaces: [cli, dashboard] + module: cea.datamanagement.streets_helper + parameters: ['general:scenario', streets-helper] + input-files: + - [get_surroundings_geometry] + + - name: trees-helper + label: Trees helper + description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. + interfaces: [ cli, dashboard ] + module: cea.datamanagement.trees_helper + parameters: [ 'general:scenario', trees-helper ] + input-files: + - [ get_zone_geometry ] + - [ get_terrain ] + +Solar radiation: - name: radiation label: Building solar radiation description: Use Daysim to calculate solar radiation for a scenario @@ -32,7 +93,7 @@ Solar Radiation: - [ get_terrain ] - [ get_weather_file ] -Demand Forecasting: +Demand forecasting: - name: schedule-maker label: Building occupancy description: Use CEA models and input schedules to estimate the occupancy profile of buildings @@ -76,7 +137,7 @@ Demand Forecasting: - [get_radiation_building, building_name] - [get_schedule_model_file, building_name] -Life Cycle Analysis: +Life cycle analysis: - name: emissions label: Emissions @@ -101,7 +162,7 @@ Life Cycle Analysis: - [get_total_demand] - [get_building_supply] -Energy Potentials: +Energy potentials: - name: shallow-geothermal-potential label: Shallow geothermal potential description: Calculate the heat extracted from a geothermal probes (up to 50 m length) @@ -213,19 +274,19 @@ Networks: - [get_database_conversion_systems] - [get_weather_file] -Optimisation: +Optimization: - name: thermal-network-optimization - label: Thermal network optimisation - description: Optimise network design variables (plant locations, layout,...) + label: Thermal network optimization + description: Optimize network design variables (plant locations, layout,...) interfaces: [cli] module: cea.technologies.thermal_network.thermal_network_optimization parameters: ['general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', thermal-network-optimization] - name: decentralized - label: Supply system Part I (decentralised) - description: Run optimisation for decentralised operation + label: Supply system Part I (decentralized) + description: Run optimization for decentralized operation interfaces: [cli, dashboard] module: cea.optimization.preprocessing.decentralized_building_main parameters: ['general:scenario', 'decentralized', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free'] @@ -244,8 +305,8 @@ Optimisation: # - [get_geothermal_potential] - name: optimization-new - label: Supply system part II (centralised) - description: This optimisation script is projected to replace 'Supply System Part II (centralised)', but is currently still in its final testing phase + label: Supply system part II (centralized) + description: This optimisation script is projected to replace 'Supply System Part II (centralized)', but is currently still in its final testing phase interfaces: [cli, dashboard] module: cea.optimization_new.domain parameters: ['general:debug', 'general:scenario', 'general:multiprocessing', 'general:number-of-cpus-to-keep-free', @@ -351,67 +412,6 @@ Utilities: parameters: ["general:project", "general:scenario", "plots", "plots-comparisons", "plots-optimization", "plots-supply-system"] -Data management: - - - name: archetypes-mapper - label: Archetypes mapper - description: Assign building properties and systems types from the Archetypes DataBase - interfaces: [cli, dashboard] - module: cea.datamanagement.archetypes_mapper - parameters: ['general:scenario', archetypes-mapper] - input-files: - - [get_zone_geometry] - - [get_building_typology] - - - name: weather-helper - label: Weather helper - description: | - Sets the weather file to use for simulation for a scenario. - Fetches data from third party sources if no file is provided by the user. - interfaces: [cli, dashboard] - module: cea.datamanagement.weather_helper - parameters: ['general:scenario', weather-helper] - input-files: - - [ get_zone_geometry ] - - - name: surroundings-helper - label: Surroundings helper - description: Query geometry of surrounding buildings from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.surroundings_helper - parameters: ['general:scenario', surroundings-helper] - input-files: - - [get_zone_geometry] - - - name: terrain-helper - label: Terrain helper - description: Query topography data from third party sources - interfaces: [cli, dashboard] - module: cea.datamanagement.terrain_helper - parameters: ['general:scenario', terrain-helper] - input-files: - - [get_zone_geometry] - - [get_surroundings_geometry] - - - name: streets-helper - label: Streets helper - description: Query streets geometry from Open Street Maps - interfaces: [cli, dashboard] - module: cea.datamanagement.streets_helper - parameters: ['general:scenario', streets-helper] - input-files: - - [get_surroundings_geometry] - - - name: trees-helper - label: Trees helper - description: Import tree geometries to scenario. Check CEA Learning Camp Lesson cea-a-02 for details. - interfaces: [ cli, dashboard ] - module: cea.datamanagement.trees_helper - parameters: [ 'general:scenario', trees-helper ] - input-files: - - [ get_zone_geometry ] - - [ get_terrain ] - default: - name: multi-criteria-analysis From 6365fed49e6e85c276799bf9bdede180fdcbd2ef Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:10:51 +0200 Subject: [PATCH 095/103] Update error message for typology validation --- cea/interfaces/dashboard/api/project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cea/interfaces/dashboard/api/project.py b/cea/interfaces/dashboard/api/project.py index 4d061abf43..0b40dc0160 100644 --- a/cea/interfaces/dashboard/api/project.py +++ b/cea/interfaces/dashboard/api/project.py @@ -260,8 +260,8 @@ def create_typology(scenario_form, zone_df, locator): if not typology_df["Name"].equals(zone_df["Name"]): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail='Typology buildings do not match zone buildings.' - 'Check buildings in typology file with zone file.', + detail='Building geometries (zone) and Building information (typology) do not match.' + 'Ensure the `Name` Columns of the two files are identical.', ) copy_typology(scenario_form.typology, locator) From efe9d0ad282f7be1f42aba85d15dedac99cf23d0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sat, 14 Sep 2024 00:37:00 +0200 Subject: [PATCH 096/103] Update node version to match dev machine --- .github/workflows/setup_build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index b249950dd5..da99ff7a51 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -70,7 +70,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Enable Corepack run: corepack enable @@ -147,7 +147,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 - name: Enable Corepack run: corepack enable From 98a12c696c46e774e9f79c6e970b7933c9d2797c Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 15 Sep 2024 07:20:04 +0200 Subject: [PATCH 097/103] Temp fix for yarn validation fails during build --- .github/workflows/setup_build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index da99ff7a51..2bf2f66e4f 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -79,6 +79,8 @@ jobs: shell: bash -el {0} env: GITHUB_TOKEN: ${{ secrets.GUI_GH_TOKEN }} + # Temp fix for yarn validation fails during build + YARN_ENABLE_HARDENED_MODE: 0 run: | cd $GITHUB_WORKSPACE/gui yarn From 6624c7d95d073819f1bd70f8c9061bafc8e76258 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 15 Sep 2024 08:34:54 +0200 Subject: [PATCH 098/103] Update setup_build.yml --- .github/workflows/setup_build.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index 2bf2f66e4f..abf6cbf273 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -79,11 +79,9 @@ jobs: shell: bash -el {0} env: GITHUB_TOKEN: ${{ secrets.GUI_GH_TOKEN }} - # Temp fix for yarn validation fails during build - YARN_ENABLE_HARDENED_MODE: 0 run: | cd $GITHUB_WORKSPACE/gui - yarn + yarn install --immutable yarn version $CEA_VERSION yarn electron:release mv "out/CityEnergyAnalyst-GUI Setup ${CEA_VERSION}.exe" $GITHUB_WORKSPACE/setup/gui_setup.exe From 94b2b36c97ea68741c779c5b1e52ba38777dca52 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 15 Sep 2024 08:56:53 +0200 Subject: [PATCH 099/103] Update setup_build.yml --- .github/workflows/setup_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index abf6cbf273..b9d1d547ea 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -81,7 +81,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GUI_GH_TOKEN }} run: | cd $GITHUB_WORKSPACE/gui - yarn install --immutable + yarn install yarn version $CEA_VERSION yarn electron:release mv "out/CityEnergyAnalyst-GUI Setup ${CEA_VERSION}.exe" $GITHUB_WORKSPACE/setup/gui_setup.exe From b6928bf1e509849be02402e7f577090b13793757 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:47:20 +0200 Subject: [PATCH 100/103] Make sure that yarn is the correct version --- .github/workflows/setup_build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index b9d1d547ea..de5994f4c1 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -81,6 +81,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GUI_GH_TOKEN }} run: | cd $GITHUB_WORKSPACE/gui + yarn set version 4.4.1 yarn install yarn version $CEA_VERSION yarn electron:release From cb25f73c7524a2958fa3ccc1edb1bcd8280ffdf0 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:09:27 +0200 Subject: [PATCH 101/103] Ensure that corepack is enabled in the same shell --- .github/workflows/setup_build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup_build.yml b/.github/workflows/setup_build.yml index de5994f4c1..67aea445d4 100644 --- a/.github/workflows/setup_build.yml +++ b/.github/workflows/setup_build.yml @@ -73,15 +73,15 @@ jobs: node-version: 22 - name: Enable Corepack + shell: bash run: corepack enable - name: Package CEA GUI - shell: bash -el {0} + shell: bash env: GITHUB_TOKEN: ${{ secrets.GUI_GH_TOKEN }} run: | cd $GITHUB_WORKSPACE/gui - yarn set version 4.4.1 yarn install yarn version $CEA_VERSION yarn electron:release From db9ff85222d5266bfaa45dac5f3297b858aa525f Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:05:42 +0200 Subject: [PATCH 102/103] Remove reload option --- cea/interfaces/dashboard/dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 0a76dbc5ac..399f341815 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -37,7 +37,7 @@ def main(config): uvicorn.run("cea.interfaces.dashboard.app:app", env_file=f.name, - host=settings.host, port=settings.port, reload=True) + host=settings.host, port=settings.port) except KeyboardInterrupt: sys.exit(0) From 5eab5598a9aeb3902f0f7d052c4590083e155c22 Mon Sep 17 00:00:00 2001 From: Reynold Mok <34395415+reyery@users.noreply.github.com> Date: Tue, 17 Sep 2024 02:49:52 +0200 Subject: [PATCH 103/103] Use temp directory instead of file Possibly solves Windows permission error due to the file not being closed. --- cea/interfaces/dashboard/dashboard.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cea/interfaces/dashboard/dashboard.py b/cea/interfaces/dashboard/dashboard.py index 399f341815..de5b13fbef 100644 --- a/cea/interfaces/dashboard/dashboard.py +++ b/cea/interfaces/dashboard/dashboard.py @@ -1,3 +1,4 @@ +import os import sys import tempfile @@ -30,13 +31,15 @@ def main(config): try: # Write missing settings to temp env file - with tempfile.NamedTemporaryFile(mode="w") as f: - for key, value in config_dict.items(): - f.write(f"CEA_{key.upper()}={value}\n") - f.flush() + with tempfile.TemporaryDirectory() as temp_dir: + env_file = os.path.join(temp_dir, "cea.env") + with open(env_file, "w") as f: + for key, value in config_dict.items(): + f.write(f"CEA_{key.upper()}={value}\n") + f.flush() uvicorn.run("cea.interfaces.dashboard.app:app", - env_file=f.name, + env_file=env_file, host=settings.host, port=settings.port) except KeyboardInterrupt: sys.exit(0)