From 8abda5462b417abcdfffcf61cc774d23388fe54d Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 19 Mar 2026 14:56:52 +0100 Subject: [PATCH 01/29] Delete requirements.txt --- code/resources/requirements.txt | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 code/resources/requirements.txt diff --git a/code/resources/requirements.txt b/code/resources/requirements.txt deleted file mode 100644 index 0407f8e6..00000000 --- a/code/resources/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -Statistics and Machine Learning Toolbox -Image Processing Toolbox -Parallel Computing Toolbox -Signal Processing Toolbox \ No newline at end of file From 8276437d938c69870ead42fb8ca8aee43d6922eb Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 19 Mar 2026 15:08:16 +0100 Subject: [PATCH 02/29] Create generate-requirements-txt.yml --- .../workflows/generate-requirements-txt.yml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/generate-requirements-txt.yml diff --git a/.github/workflows/generate-requirements-txt.yml b/.github/workflows/generate-requirements-txt.yml new file mode 100644 index 00000000..c917f503 --- /dev/null +++ b/.github/workflows/generate-requirements-txt.yml @@ -0,0 +1,52 @@ +name: Generate requirements.txt from manifest + +on: + push: + paths: + - 'requirements.nansen.json' + branches: + - main + - dev + workflow_dispatch: + +jobs: + generate-requirements: + name: Regenerate requirements.txt + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + with: + ssh-key: ${{ secrets.DEPLOY_KEY }} + + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v2 + + - name: Add toolbox code to path and generate requirements.txt + uses: matlab-actions/run-command@v2 + with: + command: | + addpath(genpath('code')); + addpath(genpath('tools')); + generateRequirementsTxt( ... + fullfile(pwd, 'requirements.nansen.json'), ... + fullfile(pwd, 'requirements.txt')); + + - name: Check for changes + id: check-changes + run: | + if git diff --quiet requirements.txt; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Commit and push updated requirements.txt + if: steps.check-changes.outputs.changed == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add requirements.txt + git commit -m "Auto-generate requirements.txt from manifest [skip ci]" + git push From 44f33deaecf4b9e9e04c368e88cc8c5d7fc98a4c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 19 Mar 2026 15:10:20 +0100 Subject: [PATCH 03/29] Add nansentools.generateRequirementsTxt and update workflow Update CI workflow to call nansentools.generateRequirementsTxt and add the new namespaced MATLAB function tools/+nansentools/generateRequirementsTxt.m. --- .../workflows/generate-requirements-txt.yml | 2 +- tools/+nansentools/generateRequirementsTxt.m | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tools/+nansentools/generateRequirementsTxt.m diff --git a/.github/workflows/generate-requirements-txt.yml b/.github/workflows/generate-requirements-txt.yml index c917f503..47739b8c 100644 --- a/.github/workflows/generate-requirements-txt.yml +++ b/.github/workflows/generate-requirements-txt.yml @@ -29,7 +29,7 @@ jobs: command: | addpath(genpath('code')); addpath(genpath('tools')); - generateRequirementsTxt( ... + nansentools.generateRequirementsTxt( ... fullfile(pwd, 'requirements.nansen.json'), ... fullfile(pwd, 'requirements.txt')); diff --git a/tools/+nansentools/generateRequirementsTxt.m b/tools/+nansentools/generateRequirementsTxt.m new file mode 100644 index 00000000..bf103c14 --- /dev/null +++ b/tools/+nansentools/generateRequirementsTxt.m @@ -0,0 +1,49 @@ +function generateRequirementsTxt(manifestFilePath, outputFilePath) +%generateRequirementsTxt Generate requirements.txt from a manifest file. +% +% generateRequirementsTxt(manifestFilePath, outputFilePath) reads a +% requirements.nansen.json manifest and writes a requirements.txt +% containing only community-toolbox entries with their Source URIs. +% +% MathWorks products are excluded. Entries without a Source field are +% skipped with a warning. +% +% Input: +% manifestFilePath (1,1) string - Path to requirements.nansen.json +% outputFilePath (1,1) string - Path to write requirements.txt + + arguments + manifestFilePath (1,1) string {mustBeFile} + outputFilePath (1,1) string + end + + dependencies = nansen.internal.dependencies.readManifest(manifestFilePath); + + sourceLines = string.empty; + for i = 1:numel(dependencies) + entry = dependencies(i); + + if entry.DependencyType ~= "community-toolbox" + continue + end + + if entry.Source == "" + warning("NANSEN:Dependencies:MissingSource", ... + "Community toolbox '%s' has no Source field — skipping.", ... + entry.Name); + continue + end + + sourceLines(end+1) = entry.Source; %#ok + end + + % Write output file + fileContent = strjoin(sourceLines, newline) + newline; + fileId = fopen(outputFilePath, 'w'); + cleanupObj = onCleanup(@() fclose(fileId)); + if fileId == -1 + error("NANSEN:Dependencies:FileWriteError", ... + "Could not open '%s' for writing.", outputFilePath); + end + fprintf(fileId, '%s', fileContent); +end From 4f532e8ffa7e1b2e191ae207e8d1de1ba82c0535 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 19 Mar 2026 20:13:28 +0100 Subject: [PATCH 04/29] Provide default manifest and output file paths Set default values for manifestFilePath and outputFilePath in generateRequirementsTxt to use nansentools.projectdir (defaults to 'code/requirements.nansen.json' and 'requirements.txt'). --- tools/+nansentools/generateRequirementsTxt.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/+nansentools/generateRequirementsTxt.m b/tools/+nansentools/generateRequirementsTxt.m index bf103c14..5470b856 100644 --- a/tools/+nansentools/generateRequirementsTxt.m +++ b/tools/+nansentools/generateRequirementsTxt.m @@ -13,8 +13,8 @@ function generateRequirementsTxt(manifestFilePath, outputFilePath) % outputFilePath (1,1) string - Path to write requirements.txt arguments - manifestFilePath (1,1) string {mustBeFile} - outputFilePath (1,1) string + manifestFilePath (1,1) string {mustBeFile} = fullfile(nansentools.projectdir, 'code', 'requirements.nansen.json') + outputFilePath (1,1) string = fullfile(nansentools.projectdir, 'requirements.txt') end dependencies = nansen.internal.dependencies.readManifest(manifestFilePath); From ca41ac8a4e30160628d8211c7aa7971f1cd6f57c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 19 Mar 2026 21:39:53 +0100 Subject: [PATCH 05/29] Update ModuleManager.m --- code/+nansen/+config/+module/@ModuleManager/ModuleManager.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/+nansen/+config/+module/@ModuleManager/ModuleManager.m b/code/+nansen/+config/+module/@ModuleManager/ModuleManager.m index 569c87a4..74e11ade 100644 --- a/code/+nansen/+config/+module/@ModuleManager/ModuleManager.m +++ b/code/+nansen/+config/+module/@ModuleManager/ModuleManager.m @@ -108,6 +108,12 @@ function getModuleList(obj) modules{i}.PackageName = modulePackageName; modules{i}.isCoreModule = strcmp(modules{i}.ModuleCategory, 'general'); modules{i}.FolderPath = fileparts( moduleSpecFiles{i}); + requirementManifestPath = fullfile(modules{i}.FolderPath, 'dependencies.nansen.json'); + if isfile(requirementManifestPath) + modules{i}.RequirementManifestPath = requirementManifestPath; + else + modules{i}.RequirementManifestPath = ""; + end end obj.ModuleList = cat(1, modules{:}); From 7f51d5074188c3a80144475915e2bf7bc0882532 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 12:45:05 +0100 Subject: [PATCH 06/29] Add dependency manifest schema to schemas/ Co-Authored-By: Claude Sonnet 4.6 --- schemas/dependencies.nansen.json | 115 +++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 schemas/dependencies.nansen.json diff --git a/schemas/dependencies.nansen.json b/schemas/dependencies.nansen.json new file mode 100644 index 00000000..474d83c2 --- /dev/null +++ b/schemas/dependencies.nansen.json @@ -0,0 +1,115 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev-claude-standardize-requirements/schemas/dependencies.nansen.json", + "title": "NANSEN Dependency Manifest", + "description": "Schema for dependencies.nansen.json files that declare dependencies for NANSEN core and modules.", + "type": "object", + "required": ["_schema_version", "_type", "scope", "scopeId", "dependencies"], + "properties": { + "$schema": { + "type": "string", + "description": "URI pointing to the JSON Schema that validates this manifest. Used by editors for inline validation." + }, + "_schema_version": { + "type": "string", + "description": "Version of this schema format.", + "const": "1.0" + }, + "_type": { + "type": "string", + "description": "Type of this manifest.", + "const": "NANSEN Dependency Manifest" + }, + "scope": { + "type": "string", + "enum": ["core", "module"], + "description": "Whether this manifest belongs to core NANSEN or a module." + }, + "scopeId": { + "type": "string", + "description": "Unique identifier for the scope. 'core' for core NANSEN, or a dot-separated module package name (e.g. 'nansen.module.ophys.twophoton')." + }, + "dependencies": { + "type": "array", + "description": "List of dependency entries.", + "items": { + "$ref": "#/$defs/dependency" + } + } + }, + "additionalProperties": false, + "$defs": { + "dependency": { + "type": "object", + "required": ["name", "dependencyType", "requirementLevel"], + "properties": { + "name": { + "type": "string", + "description": "Display name of the dependency." + }, + "dependencyType": { + "type": "string", + "enum": ["mathworks-product", "community-toolbox"], + "description": "Whether this is a MathWorks product or a community toolbox." + }, + "requirementLevel": { + "type": "string", + "enum": ["required", "optional"], + "description": "'required' means NANSEN or the module will not work without it. 'optional' means only specific workflows need it." + }, + "scope": { + "type": "string", + "enum": ["core", "module", "workflow"], + "description": "Overrides the manifest-level scope for this entry. Use 'workflow' for dependencies that belong to a specific workflow within a module. If omitted, inherits from the manifest." + }, + "scopeId": { + "type": "string", + "description": "Overrides the manifest-level scopeId for this entry. Use a workflow-specific identifier like 'nansen.module.ophys.twophoton.workflow.suite2p'. If omitted, inherits from the manifest." + }, + "source": { + "type": "string", + "description": "Install URI for community toolboxes. Supports 'fex://' for FileExchange and 'https://github.com/...' for GitHub. Used to generate requirements.txt." + }, + "docsSource": { + "type": "string", + "description": "URL pointing to installation or usage documentation." + }, + "description": { + "type": "string", + "description": "Human-readable summary of what the dependency provides." + }, + "reason": { + "type": "string", + "description": "Why this dependency is needed. Shown to users for optional dependencies." + }, + "workflowNotes": { + "type": "string", + "description": "Extra context shown when scope is 'workflow'. Explains which workflow requires this dependency." + }, + "setupHook": { + "type": "string", + "description": "Callable to invoke once after installation (e.g. a MATLAB function name or Python entry point). Run during nansen_install or equivalent." + }, + "startupHook": { + "type": "string", + "description": "Callable to invoke on NANSEN startup after the dependency is installed and registered." + }, + "installCheck": { + "type": "string", + "description": "Symbol name used to verify the dependency is installed (e.g. a function, class, or module name). Checked via language-appropriate introspection." + }, + "versionConstraint": { + "type": "string", + "description": "Version requirement string. Reserved for future use." + } + }, + "if": { + "properties": { "dependencyType": { "const": "community-toolbox" } } + }, + "then": { + "required": ["source"] + }, + "additionalProperties": false + } + } +} From f4b04b1b440c6862c04e446144517464320074d5 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 15:52:08 +0100 Subject: [PATCH 07/29] Add dependency reader and resolver Co-Authored-By: Claude Sonnet 4.6 --- .../+dependencies/checkInstallationStatus.m | 42 ++++ .../+internal/+dependencies/readManifest.m | 126 +++++++++++ .../+dependencies/resolveRequirements.m | 206 ++++++++++++++++++ 3 files changed, 374 insertions(+) create mode 100644 code/+nansen/+internal/+dependencies/checkInstallationStatus.m create mode 100644 code/+nansen/+internal/+dependencies/readManifest.m create mode 100644 code/+nansen/+internal/+dependencies/resolveRequirements.m diff --git a/code/+nansen/+internal/+dependencies/checkInstallationStatus.m b/code/+nansen/+internal/+dependencies/checkInstallationStatus.m new file mode 100644 index 00000000..6d8f317d --- /dev/null +++ b/code/+nansen/+internal/+dependencies/checkInstallationStatus.m @@ -0,0 +1,42 @@ +function statusResults = checkInstallationStatus(resolvedRequirements) +%checkInstallationStatus Check install state of resolved requirements. +% +% statusResults = nansen.internal.dependencies.checkInstallationStatus(resolvedRequirements) +% takes the output of resolveRequirements and populates the IsInstalled +% field for each entry. +% +% Input: +% resolvedRequirements - struct array from readManifest or +% resolveRequirements. +% +% Output: +% statusResults - same struct array with IsInstalled populated: +% - MathWorks products: checked via ver() +% - Community toolboxes: checked via InstallCheck field +% (a function/class name tested with exist()) + + arguments + resolvedRequirements (1,:) struct + end + + statusResults = resolvedRequirements; + + if isempty(statusResults) + return + end + + % Cache installed MathWorks products (call ver() once) + versionInfo = ver(); + installedProductNames = string({versionInfo.Name}); + + for i = 1:numel(statusResults) + entry = statusResults(i); + if entry.DependencyType == "mathworks-product" + statusResults(i).IsInstalled = any(entry.Name == installedProductNames); + elseif isfield(entry, 'InstallCheck') && strlength(entry.InstallCheck) > 0 + statusResults(i).IsInstalled = ~isempty( which(entry.InstallCheck) ); + else + statusResults(i).IsInstalled = false; + end + end +end diff --git a/code/+nansen/+internal/+dependencies/readManifest.m b/code/+nansen/+internal/+dependencies/readManifest.m new file mode 100644 index 00000000..40d90e4f --- /dev/null +++ b/code/+nansen/+internal/+dependencies/readManifest.m @@ -0,0 +1,126 @@ +function dependencies = readManifest(manifestFilePath) +%readManifest Parse a dependencies.nansen.json manifest file. +% +% dependencies = nansen.internal.dependencies.readManifest(manifestFilePath) +% reads the manifest at the given path and returns a struct array of +% dependency entries, validated against the schema. +% +% Input: +% manifestFilePath (1,1) string - Absolute path to a +% dependencies.nansen.json file. +% +% Output: +% dependencies - struct array where each element has all schema +% fields. Missing optional fields are filled with defaults. +% +% Errors: +% Throws if the file does not exist, is not valid JSON, or if +% required fields (name, dependencyType, requirementLevel) are +% missing from any entry. + + arguments + manifestFilePath (1,1) string {mustBeFile} = fullfile(nansen.toolboxdir, 'dependencies.nansen.json') + end + + jsonText = fileread(manifestFilePath); + manifestData = jsondecode(jsonText); + + validateManifestStructure(manifestData); + + manifestScope = string(manifestData.scope); + manifestScopeId = string(manifestData.scopeId); + + rawDependencies = manifestData.dependencies; + if isstruct(rawDependencies) + numDependencies = numel(rawDependencies); + else + numDependencies = length(rawDependencies); + end + + dependencies = repmat(getDefaultEntry(), numDependencies, 1); + + for i = 1:numDependencies + if iscell(rawDependencies) + entry = rawDependencies{i}; + else + entry = rawDependencies(i); + end + dependencies(i) = populateEntry(entry, manifestScope, manifestScopeId); + end +end + +function validateManifestStructure(manifestData) +%validateManifestStructure Verify top-level manifest fields exist. + manifestFields = string(fieldnames(manifestData)); + % jsondecode mangles leading underscores, so _schema_version becomes + % x_schema_version in the resulting struct. + requiredPayloadFields = ["scope", "scopeId", "dependencies"]; + hasPayloadFields = all(ismember(requiredPayloadFields, manifestFields)); + hasVersionField = ismember("x_schema_version", manifestFields); + if ~hasPayloadFields || ~hasVersionField + error("NANSEN:Dependencies:InvalidManifest", ... + "Manifest is missing required top-level fields."); + end +end + +function entry = populateEntry(rawEntry, manifestScope, manifestScopeId) +%populateEntry Convert a raw JSON entry to a normalized dependency struct. + entry = getDefaultEntry(); + + % Required fields + requiredFields = ["name", "dependencyType", "requirementLevel"]; + entryFields = string(fieldnames(rawEntry)); + missingFields = setdiff(requiredFields, entryFields); + if ~isempty(missingFields) + entryName = "(unknown)"; + if ismember("name", entryFields) + entryName = rawEntry.name; + end + error("NANSEN:Dependencies:InvalidEntry", ... + "Dependency entry '%s' is missing required fields: %s", ... + entryName, strjoin(missingFields, ", ")); + end + + % Map all camelCase JSON fields to PascalCase struct fields + defaultFieldNames = string(fieldnames(entry)); + for j = 1:numel(entryFields) + pascalName = camelToPascal(entryFields(j)); + if ismember(pascalName, defaultFieldNames) && isfield(rawEntry, entryFields(j)) + entry.(pascalName) = string(rawEntry.(entryFields(j))); + end + end + + % Scope: inherit from manifest if not overridden at entry level + if ~ismember("scope", entryFields) + entry.Scope = manifestScope; + end + if ~ismember("scopeId", entryFields) + entry.ScopeId = manifestScopeId; + end +end + +function pascalName = camelToPascal(camelName) +%camelToPascal Convert camelCase to PascalCase by uppercasing the first letter. + camelName = char(camelName); + pascalName = string([upper(camelName(1)), camelName(2:end)]); +end + +function entry = getDefaultEntry() +%getDefaultEntry Return a dependency struct with all fields set to defaults. + entry = struct( ... + 'Name', "", ... + 'DependencyType', "", ... + 'Scope', "", ... + 'ScopeId', "", ... + 'RequirementLevel', "", ... + 'Source', "", ... + 'DocsSource', "", ... + 'Description', "", ... + 'Reason', "", ... + 'WorkflowNotes', "", ... + 'SetupHook', "", ... + 'StartupHook', "", ... + 'InstallCheck', "", ... + 'VersionConstraint', "" ... + ); +end diff --git a/code/+nansen/+internal/+dependencies/resolveRequirements.m b/code/+nansen/+internal/+dependencies/resolveRequirements.m new file mode 100644 index 00000000..68a519d1 --- /dev/null +++ b/code/+nansen/+internal/+dependencies/resolveRequirements.m @@ -0,0 +1,206 @@ +function resolvedRequirements = resolveRequirements(options) +%resolveRequirements Aggregate, deduplicate and check dependencies. +% +% resolvedRequirements = nansen.internal.dependencies.resolveRequirements() +% returns the full resolved requirement set for core NANSEN. +% +% resolvedRequirements = nansen.internal.dependencies.resolveRequirements(Name, Value) +% accepts filtering options. +% +% Name-Value Arguments: +% IncludeCore (logical) - Include core dependencies. Default: true. +% SelectedModules (string array) - Module package names to include. +% SelectedWorkflows (string array) - Workflow ScopeIds to include. +% DependencyTypes (string array) - Filter by DependencyType. +% Empty means all types. +% RequirementLevels (string array) - Filter by RequirementLevel. +% Empty means all levels. +% MissingOnly (logical) - Return only missing dependencies. +% Default: false. +% +% Output: +% resolvedRequirements - struct array with all schema fields plus: +% .IsInstalled (logical) - whether the dependency is present + + arguments + options.IncludeCore (1,1) logical = true + options.SelectedModules (1,:) string = string.empty + options.SelectedWorkflows (1,:) string = string.empty + options.DependencyTypes (1,:) string = string.empty + options.RequirementLevels (1,:) string = string.empty + options.MissingOnly (1,1) logical = false + end + + manifestPaths = collectManifestPaths(options.IncludeCore, options.SelectedModules); + allDependencies = readAllDependencies(manifestPaths); + + % Filter by scope inclusion + allDependencies = filterByScope(allDependencies, ... + options.IncludeCore, options.SelectedModules, options.SelectedWorkflows); + + % Deduplicate + resolvedRequirements = deduplicateDependencies(allDependencies); + + % Check installation status + resolvedRequirements = nansen.internal.dependencies.checkInstallationStatus( ... + resolvedRequirements); + + % Apply filters + resolvedRequirements = applyFilters(resolvedRequirements, ... + options.DependencyTypes, options.RequirementLevels, options.MissingOnly); +end + +function manifestPaths = collectManifestPaths(includeCore, selectedModules) +%collectManifestPaths Get manifest file paths from core and selected modules. + manifestPaths = string.empty(1, 0); + + if includeCore + coreManifestPath = fullfile(nansen.toolboxdir, 'dependencies.nansen.json'); + if isfile(coreManifestPath) + manifestPaths(end+1) = string(coreManifestPath); + end + end + + % Module manifests — ModuleManager tracks RequirementManifestPath + if ~isempty(selectedModules) + moduleManager = nansen.config.module.ModuleManager(); + moduleTable = moduleManager.listModules(); + if ismember("RequirementManifestPath", moduleTable.Properties.VariableNames) + modulePackages = string(moduleTable.PackageName); + selectedMask = ismember(modulePackages, selectedModules); + moduleManifestPaths = string(moduleTable.RequirementManifestPath(selectedMask)); + moduleManifestPaths = moduleManifestPaths(strlength(moduleManifestPaths) > 0); + manifestPaths = [manifestPaths, moduleManifestPaths(:)']; + end + end + + manifestPaths = unique(manifestPaths, "stable"); +end + +function allDependencies = readAllDependencies(manifestPaths) +%readAllDependencies Read and concatenate dependencies from all manifests. + allDependencies = struct([]); + for i = 1:numel(manifestPaths) + if ~isfile(manifestPaths(i)); continue; end + dependencies = nansen.internal.dependencies.readManifest(manifestPaths(i)); + for j = 1:numel(dependencies) + if isempty(allDependencies) + allDependencies = dependencies(j); + else + allDependencies(end+1) = dependencies(j); %#ok + end + end + end +end + +function dependencies = filterByScope(dependencies, includeCore, selectedModules, selectedWorkflows) +%filterByScope Keep only dependencies matching the requested scopes. + if isempty(dependencies) + return + end + keepMask = false(1, numel(dependencies)); + for i = 1:numel(dependencies) + switch dependencies(i).Scope + case "core" + keepMask(i) = includeCore; + case "module" + keepMask(i) = ~isempty(selectedModules) && ... + any(dependencies(i).ScopeId == selectedModules); + case "workflow" + keepMask(i) = ~isempty(selectedWorkflows) && ... + any(dependencies(i).ScopeId == selectedWorkflows); + end + end + dependencies = dependencies(keepMask); +end + +function resolved = deduplicateDependencies(dependencies) +%deduplicateDependencies Merge duplicate entries across scopes. +% Entries with the same Name + DependencyType are merged. When merging: +% - "required" wins over "optional" +% - Reason and WorkflowNotes are concatenated (unique values only) + if isempty(dependencies) + resolved = dependencies; + return + end + + numDependencies = numel(dependencies); + keys = strings(1, numDependencies); + for i = 1:numDependencies + keys(i) = dependencies(i).Name + "|" + dependencies(i).DependencyType; + end + + [~, ~, groupIndices] = unique(keys, 'stable'); + numUnique = max(groupIndices); + resolved = repmat(dependencies(1), 1, numUnique); + + for i = 1:numUnique + groupEntries = dependencies(groupIndices' == i); + merged = groupEntries(1); + for j = 2:numel(groupEntries) + other = groupEntries(j); + if other.RequirementLevel == "required" + merged.RequirementLevel = "required"; + end + merged.Reason = mergeStringField(merged.Reason, other.Reason); + merged.WorkflowNotes = mergeStringField(merged.WorkflowNotes, other.WorkflowNotes); + merged = preferNonEmpty(merged, other, "Source"); + merged = preferNonEmpty(merged, other, "DocsSource"); + merged = preferNonEmpty(merged, other, "Description"); + merged = preferNonEmpty(merged, other, "SetupHook"); + merged = preferNonEmpty(merged, other, "StartupHook"); + merged = preferNonEmpty(merged, other, "InstallCheck"); + end + resolved(i) = merged; + end +end + +function result = mergeStringField(existing, incoming) +%mergeStringField Concatenate two string values, keeping only unique parts. + if existing == "" && incoming == "" + result = ""; + elseif existing == "" + result = incoming; + elseif incoming == "" || existing == incoming + result = existing; + else + result = existing + "; " + incoming; + end +end + +function merged = preferNonEmpty(merged, other, fieldName) +%preferNonEmpty Use the other entry's value if the merged entry's is empty. + if merged.(fieldName) == "" && other.(fieldName) ~= "" + merged.(fieldName) = other.(fieldName); + end +end + +function dependencies = applyFilters(dependencies, dependencyTypes, requirementLevels, missingOnly) +%applyFilters Filter resolved dependencies by type, level, and install state. + if isempty(dependencies) + return + end + keepMask = true(1, numel(dependencies)); + if ~isempty(dependencyTypes) + for i = 1:numel(dependencies) + if ~any(dependencies(i).DependencyType == dependencyTypes) + keepMask(i) = false; + end + end + end + if ~isempty(requirementLevels) + for i = 1:numel(dependencies) + if ~any(dependencies(i).RequirementLevel == requirementLevels) + keepMask(i) = false; + end + end + end + if missingOnly + for i = 1:numel(dependencies) + if dependencies(i).IsInstalled + keepMask(i) = false; + end + end + end + dependencies = dependencies(keepMask); +end From e3c5262d3a84b7c6586e29f0aec9352a20b2c4fb Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 15:58:21 +0100 Subject: [PATCH 08/29] Rename function getRequiredMatlabToolboxes -> getRequiredMathworksProducts Co-Authored-By: Claude Sonnet 4.6 --- code/+nansen/+app/+setup/SetupWizard.mlapp | Bin 140558 -> 141527 bytes .../+setup/getRequiredMathworksProducts.m | 41 ++++++++++++++++++ .../+setup/getRequiredMatlabToolboxes.m | 6 --- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 code/+nansen/+internal/+setup/getRequiredMathworksProducts.m delete mode 100644 code/+nansen/+internal/+setup/getRequiredMatlabToolboxes.m diff --git a/code/+nansen/+app/+setup/SetupWizard.mlapp b/code/+nansen/+app/+setup/SetupWizard.mlapp index 2e17fdc9d25afeceaf631fac7ca87ab243a5b8cd..5f6b0678064a4addd1dcd83daa37d656e12bb4bc 100644 GIT binary patch delta 97960 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 b000000PQ4~FC+pRm+2$|9|rU#0ssI2Y$Hjp delta 96996 zcmV(-K-|CA(Fl&p2(UE+2}@-C;}SFg0Gg9N11teclWPMR0a=rU10jFQgxu1+h_m#3 zXEfa3AvB$2(>R@<@4UNy@!)ia6lIi7qa;h|`A(YckY9fOY4d2BP1Z}AmV_Zli$|OD zokdx$9zA?mOcrz*6~k;rQ}%9_<;$pKU-S9HO_onrc{ZU%!SFAWhvWVIz~*l$`IdhS8meKmYWwdXGQKpMU!C{nKX`*B9?6NmLY5 zIwM!KT(5qQ{}ts^@)KcANTQozv|1Izi`D8$RL~!OAndbC-sY^Oc^T7!l#8e&lPu3^ zvC7gZDKo+#*pnsu%KBO$$f^eDUreAgm+bxw)$ z5$##WL;kLUdzxegeHJrn&!4QzGD`_@!%ecZ%(G;8xs2vD_=_x=()`z$=21Rb+&%vs zEmsM}GHt+LN4N1jDj6@ljZ&Hr5~`gI8_kDU(CGHdY@Sthc4_`=`nhy<+Y8PMSMYCh zdK+i!!h@p`{yKlU`D>o7SI*kq{g)sWj!VGIo_51gfnSwT9-u*E7hYx&OkOAXo$&ey zT&A<^lD&Ev-Pq&r0>^?Dc&pCawLib3fyx_e7vP@C8*BfSCaZh&U4m~}`|mVif`)F} zcg}Wf{~yrc%}KFc;~!r1pZ%aWVy zGcB-*AIB}bz)Oz~TGQV}0jJ#aQ9ze{?=Bfd64#{j)Q`m#*_Hj1PDw4h{n!cI z+Yr@ce_p?j_>JJtqB44! zO>p6M(4c>*_d0l7Cb|&nQu{MnO!63ofW*;q+8%C6I<%q0Uh4t^C)F1Z+G(hDsKem-B&BVOjqk_CbyWmw2Y>#?VhRI zICBNKXYRJ0xxR_pJaa|;p1Iou{`V-4VHNO5u9km7|9H#B%i5n$<1))F61F9tuliPV zx1xZp_%w1pTAJJIEC_xNq0bS3+UL~Qo96u$P1u?zIzgG#U>eagW?O<9tcEvr4u@}MzL|xaw?0h8?URDo%^mRi?Rnzjn{cc zG<$zrg$0-n+wdw%8BgVn&DU8EK`+yy%-0ijv1r+Q(fIAvwX09@szNfS&E|q(DOBx` zk^~o>*I7wJ@P^RF_lV^A=T*Y&mi%gxQ<@fwtZZW=W5piMYpd{#T;tvVPSdG$TRqKK zyUCx(#cD;P95_(*WL;;|>=9UH>tsr9D2aba$>t{=4u^&dOIgU%@^!SNMf-k#!2bL2*j@5TH2E~ovvoSH%MZ^6;@<~n6T~>1Ef9Z? zT`d@%o}3<%>etEsk&0RabTx>99Fu)_V?g*%VP#m-bX`k9@$?mY=)gD{u>SiKf6Re2lN8OR|RWNn<`i_y^41Q!yn6@ z@Qy5~tc^()1hct|4~lG{UiA{+4fP^!NUPZ{*msvd=wiI4*KR!u*!Gyu7f^qzBjl)u zr4+e3ig&T}yzIhQ@-Kj48W&6{x&sVJT$Ci6kz&1CWqHZgYmU>VhRT$$fJOXoSZCxr z+YnM-O76W(<1&sCyMU#V>lJHHU0|%s?^dh^`WyYPb)2)_ofE#g_j__?_6B4YB?TRj zUNu4MXL4zfpI$w06~KD>Di41vJv@NToawA6YaT$`^Syd!VNs-jQokw;rSHOLfbLodrDDG$%NMn@bf%cvSmJ=Fz&vq8^ET)WjbX~ znK1@3s`jNgHb};vO^>nNV*IhB00@woZRhXA~X672r*Z z+ZO9pKU%H!v@z4ZFtr7NK)#A8inCBoY)eGJC!Ucgz3Ve}o-DC~p|SpGE6$!?J$wL! zHx`SbcRW2DNsR`+0G_H4VG*^Zz;t43N)(8ibCW@&QQB*G#)$-jRRK@IhSMi z4O` z0~vI(uaD#%e>@)V2S%8(*1m{oGX0gt^F@i}AG=Fjt)dCYGN!$TFsAEeWzE67T`y_U z*Lo5FMpXrBc%-7S*dmpB^g2$!pu=gQTGB=xHOvsV_1J>WBz9WP`n}!hkj;$P55TAx z;~+8394P%@ygz?H+71}02IKJu8`4I_`i(TiCIdxh@XcyATYyW}zMiW!625LwKjmE*b@nDe5|AdC5izaCf<>wz_q9$SB6&GolWSSZV{rYG#0ucdU1 zgreZm+qIUgndKuqk@dQZmQWfcLwGynp(*d`f84GWLDg3~EZ1rL0-A>2=eQ6a z7Bqj}1N88+e)b`>0KhZ^dI3=X4+YcS5T@wYo(?>%b#ot>qQ0BZaiN%L?;Wt0Re=w^ zK&x|6h&v$9$%H0Jzli@u``Dj7gEO__{kjo*(1U-T{MP##g8IV*;}IWGVuG3KR;@=_ ziUE9Jj70#2RPVtPnayTBTZ~Ed^*`6lrY}I-LoGc@%8X6Ug`u2F^fEp~O8njh<4z{l zKA{f_Ote^zz>xeSTa!tY5)4;lL@@*(TaSWWc*Z&RJ@$5>vCBZG=!dXK^@&nb6V&CY zl%Idh3V~_H3ri2w59ZMPA;$*0V7heBT}Bhi(7`a4gnni-uNdk+<}@qGBD$pzGda!J zY>#aXXo^@owS@I$7lWc{`4m{ zW4OWv$monR;0f>&x>9&^diFdL_Jr`$fR%r*LJw=$77T6SVkS7#0fyK}n{As0Y*^5e z?-|mmz}eTUFloY;2hE5y5LW&uj+IRgVIKC}_N6c--7pGYgyx-TS%v)_*5q<{5Wmv| zbJpY)HCD@E|E44p&a-?WP6RgYHy@f5o|+Zb6Vz&psWU0-gN3G@f$bB>R@JOkRuzAK z5$vFg5Uq-fPx{&Iy0~Oo=MHVo5?@nBU%R;%t5x6WE3r!U2JQ~~d@X!)5oKb*VBed- zisBdw^5G@4Fq{vbDrKm&XsP__FAXZ5t7+iqQ(LAwkM;Jj2Ok>rbDU%mQ|;#|%q_>( zD2|u#n7q4`qHDC*P+(j+x1k?@XF7i`%`ccNxuwFv-GtyEAX$7<{G2RwL1sZ40?pw9 za@l5fF{#+EW1IlDqJWSN)_7VyuwJZKcu210)cc^i=0 zidE~{byPN7#8b)?DyGU*yH198)d}|QlJCxZyw2wHq?%1=>BLD~-c?2kMA8$8I*=0z zeAhi&Y4z5?jAQw3_&klAhLp*68l4>*JXhdD=l*;ICJVgJMAaessD&ASdh} z{LdD`9&ay1tG$>&iNExV0UeatCz|dN=-Qm@a?AbiI_}KisA5*qSv44%{@ag{uvnRiiu^e!a(w&y^dIDhc#*03}BVWJx-9c zo4A}TXbx*kp*nTLx*P@-FbIBfl%a&vw{NwFTzs>p7OWaJqCkI;0jx4OK>|{}%)j=gF4FkSQMv)C`xXk+(G*mylHoyHEH-JnW~ef5*~l2 zVDEyZ0KO-=*GV>6{)wTXQ#u{GrYZG_b(E%oAjspdtft>%2cWE^Micf8JzY@7V{HBbUE%_Le&9)%BK0>E zcZinREhUD~ii@XJ(R0B}4Atd~Ra<|(QToc&6WfLGhk~f>B=+_Pnn6FuP@i3Om<*il z7@HNse-9L~L&2m+Zz$dToaUU|wo>E@GOq^E+EIo%FP2IWnz$CWX%w0y&}WXi!KbDx zYKkS|n3)bzU9%A(%+@ApW$B_IVq-baK+>SpV$Bz){rSeFIqV|TkyptF2vvV|X6iY% zd>n?gwuPEHc2E(fjwNm0a^-tkTA*nd$m@~+mQD4Q54F^UvF6M!(ZhxK`pX9&!U6;9 ztO*LA%cpN%UkOX1fMhnqm|5*i=L8f79N2`A2Z zB||)hv#K+e8vh zgvs}9d82;bGXrV^`Va#Y5Ff;f$84?TN}vHvsowVvA*`jJ#N2!Hw;q4CxUM3I0kLR9 z49<&ituB9P_0A>8?o*j#-EP?y=W}Qus0!WLz}o~d0U!njG)Y*ma1|v{6$KB0E#!tW zq*TVpfXmU}b5tt<>suAWGR9P30l3E5s?s4eP5zhRl~0i2J@0(aJ(3Xja;hC$x8*%e zL}=2vZ$on^w?n^-9MONm@OiKFeE_Tr;~^2V34j4v^&;UIjtoM^HnE3&nn)YexeXm2 z1+Ux}WKFesZOu$mnwNg>6oZ1@j)Ve{`K%O^h}mn^97l)sg#U)eJ%8v&c-55#gL`e= z6|aS*gw{B!%xI3IOo*AeEnGcOd^-q%4J9KB~e(3#`t4Mv0BQ;5+{ z(=y6GJ!MiSZCD_kz&S0LISm2+*BKZPZ&L8Wyn24ZY?rHO$?vWoej(#X-(M6K*=^yBDe=h=@+=5X0 zn|Mez`*RBM{5N+H=@ZXlp-()NfuZi9xQ9;CLJ@&T*2^@)SS}C6JPqLSU_=e2+p-m7 zvlTvCi%5UCEvq>Qb+&^VA)RojN33Jb5w|Pf60tU`e-#q1ZQIshXLcKau&nEHT)>H-ZJfR56aarQcUY8$e+$78WEW4xRbX9EQMLzC zO#|WOf%_61K2tSq9oU5M$5^D>SOG46#<8d7x3hwnOlq0|ecT9nk!MQ?AMR_FcI9y` z&0r_)c8PdfynDPN9*+pd7i+cDVD8q%!tpG2{$}eWnZ=C41b(ifye#@l_!E3e{T{pq zHHu@AoGHdkQe^9VLNPKB5aAySnyiMabZ#D7<{fEgSGeQqc~o>tH_})33)CkbOU48|MT5keu`hW7y63`*A^G`03dY@%33%2BqUFXNM) z7&3od(Ek4L$loCm!>(87E{@?) zu7-Vh_h~Y|Rfl9W&RZyN$P4^iY;wbcn+SixUl=_0Pdi@ZNY$fK=nBtBh*L_H$}4gMDYfMVr$9Gcr2W5`VqTJdeVI%|KE z3i*o|4%wCqN4^;w2AmyWwzlAh>L`RGT;fVb0vYNPlPX*ZnxZlW^}F&s=;u$AV;!h; zUD+Km03u7fbxsmEOvx|Csi$z|z0=ouHJ>iT28+WjOQDVr%exgFid+-{eZjS|@0Mv?U@PFd<)F&JnF~Hfy*=Vs zTD`7FyEc!u9z4S%KO$Lx#Oc+AT=X$o;x@+qZHl@4boBj)RND8w3(U+|C!>FZ(}NXv zM+qa|^sYK~*b5>vcTjS=N+6LX%qYYFsx#K~OV4xmq(b%PmgYGG13#C5RWpC_oNcdR z<-P@`^uRU%S^q}qO6GV&dxR@AUmLJB8!7VR9xQIOxFwzX;aZk#ueTT$ZOPI)YOVhr z@dwOh_=LBQPTYWVH{4tt9ZFic1fNVv)On`FKdsRHm( z^BLB7R2!ULH<6VY^`0`fmbLG+Ghf2t)+}l*iu)3X>aAA&SJgoos9hDlgeO8!lH$6L zsJF>Q+Om3Sb#<#cnBLT`oqNU1)j*nXDTTv%QGWM}Rh#W_w{GNeX(@jl_M_SYtG6k& zhcdPYbTGfy-w>aWU?_b(&!+%p@fS)5M$HP!)PD zQR_Rl6HngkhzwQ@WLYpBM+}2Q^?A(Nj43?J41(=)NJTGQy{Q>i3rCdJCC`<^(~NK= zZ&H4BQy=OI2$6rQdR+KbNU%*0e_*zZqTicRy1Gf$v}a`@bR1f_mI5|CL{~)`}-yv1p z#7LBLlQFw(*$b*Yev&J>V!s37%?nzcZa@=UN^)H*%Bi@dW&+Igwicze13gBdzG?_8L+DeGow0f5f#Lj zkjquJg^US-t2dJw0>H>+okyEA+Zb974@lTQ3Ji{Wi>c21J&R&It}&0x#rlTi>oj$Q zuArlcI>dK7MJ;q)hH*EI->YV#W{Xm`#B~&J*Q0-Uy&eb?nYFNDILffgd8ND!U8Gq5LdNB=2;#!}{JPDzhe^5V8 zzD0iq!d(-`|7Ianvk(So^Z#WYLY*Ead9+)@Vwp$8D0RP#g?8SB?l}t`IJV1L=s@&M z@)mmVZlAf(n&qk=$L;Z8Iwey<9vld-%2#vjt#mQlrweRAyj8+LWKZvx?K6LPQ92T@ zIHki!mmv0RgNXP8o689-_A1SBkSMps%(34(SE_L$B0Fs_L2>5ng zEa(*SkL~$VFmop$x~Z5&;n~4wlK2h_)x*t2u%ccx4Xu*d<=YM`W`;3_^>F-e8rFZ~ z?S{4EsMfS=9MSJMr107G!d=}hZ!-6QnHrZau5QXy$aly)nnG&)!NDFG{uyqxW}p4x z!TwnMb$E6P_ggzqyl|t~AD*4sj(-?}`nx7e)4ct==6opFJW9;p`1T<)x5}xG#vik^yU3 z-k_yj+G%WN@SqnwT*3?U#1j>W84Z5@!iyv>1XOiJTi^HNgL+rY@T$rFT6tn#`{lo(NJY>yH~NqmpAKV#VZD zs@M{(d^ZX3`pF~m{IlSX>S~j4BNTsQaAih5K`1*qnD`^MSVfa^Xh{QXr$`+|j87?V zn?YWv^V&S**Szw}lz8GAY&PVB5~-hFU0lDsc*3|2cH=Mul)33;Q3M-Qhz#0wpov4W z4P=rm_Q1EiS#d8CGi(6%ECRP_T*JC&;dC5ILLJeWyi2>;=Osi|iTCz)VHkhW+X$oN zylqmkIL{Z!QNM`J)8$6U!DN(pMn7T_J{rir#I$ZY{^=~=a z_Znq*{S8Oi9^LTPs1o<6Mib!hV~#!X@v2~UM8 z%!10K;5eSq86H>3(tcf+d2ti_&w8-nCSxEn$^wyD^omu^-i*Vl7lcpD`id`|W?3fL`L8AfB)m zMqgjInjo;IHu_d5q9$bh11ui!;c=7=UKoQ8{A3VVq7)A6)+U(E{tjErE`<1g~a#>N6OchyB0B95xuDs2ooJ(X#KGGKASHfZ7@ll*lOz$Kpj&Jkx8@lzq0Y zrIkVF(i(){DKc+54)}k9d^~S4k3G^>k#EV+PETi;qpf=rTXggJ9R+D;cTT)$HBp<- z6<*Hp#Bo6>cQuIfV$(IA-NMCcK+vM4n`+Y;k}5{G5d;S&R2(LnWr2LbE&B{u+?|$h z{++#s9UgJuL&=H^*0Qtj_w76=G49UGH~&MOhtu@lUWYoZbsm3CeaOQd)dAi5h)2tV zBRn!fc1Fa|$xF0t%5g7dRdL}+8^%u$$;35iji7$Zv%Nq@?4@N(L!s;J)ys>wZ!y#= ztOwb*(C}V3Mh80t*Ta%^TE;wIta3>>%)5yro4aSMaf?-iMw&Z<+uwgD@bBdKlpLKLx5OZH%^rV8@TEiQx6+ed> z%S=`eP8qa@(eZt?E^mV&R{T1`J29Lw^dUIwgaBYEGuM=;fqu{O>F;^8@@nCAQ5ky4 zy?OHtBy1zV6`y9K<4{4BPmcD<0sD7+dP+tI2M$S~5Q-D{OAiCVr#$5#dY0yEkdCl^ z!CCwDd?9~suEPaI&lxc6J%(*&?y8F7CCX3u4)u-ph}ej$HUeuWmMk>hBRow7RG8N( zSTLa!&nZ@wJ=l}X6A_tbiPTwPYy`uec^PiSe&S*;WDJW+>dW>_s6wfHs2rkc0CGf9 z0um7>*#O*uVWQV5>Wwj-T9G)GZJUSUWxJ-Yigz&hDho&2{8WBr5li1`790^nv znnprG3{`b5ET>%xpjSp$__eurG$x0m19HIT;J$+>dZVf+jmp`hXgsa5E`_P+W^CR9K_X8RMJL2{{{+v5ReVNafg0!Ovbn@4f6}8gmk1baC%5aqeC~>XplD3 z2*cXTH%py?d6>cza@4KPrb~eH)=cXQN77wD!SQ6d)q~;Q^1-S zNH1)O9Y&?m!LgfzbWodx)C-$@1W@Df?45ra?>wt^S}l}y07pwJw*simTygVPsBC9LmxE%M zy$3D6!&a~0ufA5Hx8Xd)!HX=X7Tb*u&xrEVL4OrRphqFFt4W?ENiYalEv~Z1AzRMJ zXXN%5mR4Q}OOu&G*ZM{sz9Qz_eGzlJ(d<-cQE1v;; zmC1$T^3FVgZzKIZo|X&1I)Z~>y=Yy6_x5x@0Qg(BkxdDd(q`5HBN;h9V9VL*k(Y8Z zG{9aM#0z5)4slx@X3)vCQh_-IBNK>YqWyBMViH9M=S&6DD7>qZErqUDKHz_usmhs- znbQOAnAvx!X=X6TcMkrkIOUl@Q-vJ!hK#KS`U-a7Bp-^_&Jr(zu8tEgqL#c6gbz4W zyl@?yD}E{p&XEPkb?t2P>1n~BOIf3{l&QN_0}qE=At!)Sd-GqL*~**VCi>H_+TAxG z%#TEy>Zi<_KW6gzc%O_9ydr;Eq{DM*GWDyrs!R=0>oW2Vn_%hA+Khm8t263LL!YVZ z^f$k=I-j!ox(Xc~s;kV=p}UD3 z9k!8G_2MlBjtvx$H+JDp;zkGWAZ?6+(~kz#EEp6vC%$QP(uIX2%yuq;ll!{_PPPzp zC#}WYNk^B!NlUSKV(C1`Bh-1EyAm~#rP3pYTBgRv?9Nh|iPL{cvIZAGobo^jnRh*` z+wfs_YxBxGLz!TbL3gij|^$hs;dHYE9>m&-p1Kcca`g?t;TiK z%`!V`r=J~dvsHUkP4Zu}4Jtagaun+u5w$L_!iF0KW5|C8gDVQIJG{g%5E_C@Oa(-k z?!`vB*dyx#w|yDJe~8m#etqa_MJMs>4g`(Lm+n<3RCpU^3*l?M0tJzDU50|lnq#^` z&~4+hns5YGr68=~E!qz(P2q8o&LdukuTjPd5H!_%@@jMsfi>Dfa*SGwj!{ctAj)-i zULS2^tsONvtTkfXP)t9gXNMHolFAb?OmwVP$sPCl;B7`=d|}CgAIgl`+=wH%)`5eh zm_wNfbtYtHlkzSme;7k7z&;rtv;V!yL{sO!SJ1X{3!&|f({3niw=+_MC|e`qq08y6 zly@r~r~8LQ`E@$>@0AE#-rW-Yz3J?(TN3D3=PeThuJfje0pGm!VF0w<{BVGUwm*#G zE_3O~y(U?dlo3n(1R$d>W7_S!M;MXvyi1t_<+6mz(UtYLS68e;{{{3TCR%fE{Aq5AKrQjxvS} zZ{Ruyf-a)m1-|`GsBb2Xwwg+#EqHp=nyE)E*;JJ4Y*-&}V^|+M3~PR%a|Z*xCwO&W zb&YMY1C}=Ik7Dcu-0xOT)k<#{8j+<+RGogoJ>{O&a1A-u*vTY=6F2L zLQg@1e+#RoxVq#)(cU-cL(thT=tI=(6ZAp0^#_LFL%u*CT!+QoPk&t_m)Bxf{1y^W zzDNx-P$R?`0%EIW{_x(*{1$;Bt>Z!tyDjrAqeu?7S>_Lw^ea48Y$7x0ByoX@I{mz2 z>n{)>O5_#fMV(Mb#*qo3!2m@Wk+_#^7V%_(3kmMUY0PT(yvEEglb$gc1ZiBXl9ReI zM}IhG(*u%Wos#j9UphL_nBtMMsx0H@tU&VWR<+B*I4<(q*e!>q%9?#y(j~vh@_Lhz zw_N=e5+Co66k%IT0$k@pVVAER2a|(!-D3bN9O@X3&yM&Qo}9HGLp@(OG{w>JuykdLYk#ds%Z4W?y_%&0rb(tVm{K5?++oY^?tQOx zSJu4*R(tH5JUXR^Pyo#|5u`6)?s;<`sNna>93k;|s?o|AtCrP}a7GDP@Ec^7s8DT} zVWI->mT95_+uHp0oyc;Zbq`ZkKyIbwj_C!W%hi?Ts9DJiIk(>Af6nmCt2VOC|{4 z5wfPv<^pkpRdQS~W<@$~CYv@{{(lL~WoAPscSG`o&LBC(hC9{cbWI0j#U1tQf+}fW zP_7Vht($aff}pEw1?!l?VT~l)3`rn0BC3fE!p>Q$3qv{)w3cyh=&mBpjiq(cW*=}s zz`21s$Ttt!1iQ)1%dMrG+Zm$1H1x{gn5uAH)ISZ*r@$Ti6}aFPg;s6B(tn0gr?$)$ z1JL?zL}wzsFt|<#Mu}50J^=g66;l>Q)!iE7hh9D|5$#9Rr#@1FxP@^h7!gA=UT3A9 z&COZLEkAt3ccN&L>uw-z0y0Z?Ob&eMiron01cWb-q`;SsOGa3p;E+T!2*E_xWvrm^ z`y_%_YRM)!OA#YelS<4`rhiQrt}Zz@{kMDh9Tv_y_3TOq!2WRGh1>n$#8555?5&r? z)p+LXi9decS*pu&=S0w&Sv4RnG2rNc9PUGc?NI}}YACAYo0*`%ziDZYB?=)HVaw!|#pmbCs<DRt1$0&?0M$4oVI9hUo0nx|>O8G_(P|9j*bHnH>V3h{Pe)~rqh2P6;p1D)L8}E%J&KQ30O<@(h z)|cba89Bu4@6Kd-Cg``w|DG^x@SEST`w_m5!)r_6u1BlIfq$|V;o7V@_qt~?1gx9q z502SN?!R>{gsA(n&ZFW#E+o2-%%oT|Wscv&6dVfwb)K@RR*9|1Zr{*(HHi}X3hx~R zg0tq*a?RuP&Zs4;dUb@b~y%Q9kY8Mr>-#pJhJST>#oyP{0$W}fPbG=IJo>t4 zR2R=k%HCybw)mZseeE4mCZSQT4TU=N+VIQqn~ErL%KK4}8}7sgl4<;)4Xk>Ru|be$ z_^KYr&4O}9fGh0qozBQLDmT5&Uchhm@56_me|oriRN~JZf3EQ7O*Xy5Kc?Aa4Nm2s z{|``01G9EFo}vn!;F*w{K>+|bLX#faBY(~lEeyfk-Ccvb6P)1glHde)cXtSGAvgqg zcXwT!MHhExVV~ds-unTbp01jyc{SBtb;eEUER?%J!EfE2Y{m zb9XBzR|ld0?xZC7cvvZ=TrJJrEiEXW9EB)lU2Q26ng2yycXaq|3k;D6$! z{Qqk%GEo25pcRxc{@XC2p`g6;4t|=MVVYT)nZYcQN=y$!LH|<|qrpD@vVREP3I%sB zcc=cy62ga9sp!VUjPmWYEX%|%MN_>w5}wVDb%DYpYnH}@4U*Z zygawjysGW-)F zGZKJd#u<73iRo!0{+a$Yo|Uz=`Q^c_RO}!aC>Is}g8#)uQ|fR4$*$?sHtjjxW}kpG037{mUfgtM^qJz4y4fK; z2Mwg?*olYBQjV<+ly#aan>kP7+9+qDK8&QB_st94w(G`sc$iUwPk#z6U(viE$oYX% zLcfn+#ctg$hMRZLx9+zBiCiicYRpt4h8r2w-juHRUy4{9qsX?Nmqy@vi6J}_ z4vJds*}a>(UewXNpMPh3py~(UG&qibSq#PWT4TG_n*s$s7~H&92IZ52g%KgMP@g!X z*$>-CdQ1Zzgo_qzcD06$+pL*ZX*yM`0th%s-6Hu?Pat@3#QKOR;c-c}cV17qi|G+i z2h(w6kc=e4)Vlhnt;y_G3Hutlz_J3}f$7K9r^%WKzto5D5d>VgbW6028mn4dqHY6MLqipdH3{use|l0TuIEnErqi(~b1+Ld@ZW$U@wDV@!y< z(Yb3=9e?et!1>LN$ES0C6*{Uaqu z`V~tUZ_LiHm)>W=r}Oc^?Zzmw2y;(er!N z#yW+Uucej&O<&uUypG(K>po_M8-Lfx!~Y!jLmts_QeqI7<7_9J+$4PdemX7gcF~G? zouR2@%@#rBBEyeM>WPfSNK=KF9^Y=O)_)RUxadeQT8t8RRxrx$O74#L>b8=|&bsAs z1^p-V5xbc!&geACcUTx+ylysM`i0>u7_GH>aptaO(EEL5MtNfAjXDwaIFl5C!alPc zgCMyNCA-hKOlXjV+k3Ss%HW9>MmDZM?Hb9?rLbA7d$OS~MPx??0&iXcK zrkp6*MNdPz#LT@e`rP;7d+gg2LVt9JU;>n@-%}Zn^hd1niDMYjW2o6DH*uN?gmA8>m~0>xN;?Olm(Jcb9c^W z3G_TJSc|T$)Om$ZNM`AEC7dzqVb=lYi!WWvU^PYmuCz;sT zcR29(#a{S+aWZ&+={H?&yA-jf*tMJsg!PJo=PChOqz!uR5*Z`LUw;eO%>mqk72szP za18`-1VK-mR!n0wj(=zRFT+5x(Lox|DjnwKd1>2Epr{!ARzZK~k@i2onP4{z;1-NP zd2W0$-9z`$>QEQP%@s`doS;e9S15*#Sq%8RC@2tBKh@y74inM`?>FIXt(cRu>vN#^ zmzSi-J*Tm?Vs$yp>3_B@>>v$a0Un?Tw16s<%5O4z2<@WE5BWjaq_9BauIvZmdRX5;0#QWIsDcU+)2+=~H&94!_t5!!9ae3X(&raEcLyeIps(wh@>@2Z-ZbyS|B_@T?U zVjdg4rQV;sSS`jAI3(UCUkWmZe59o{(hD-?dr_Y|JgY1Bn}3;p{8@LT&^qY1cs>clIjCc*J*lDhLb`3x-&j zQ4^dsEU;piG=+Ma57e~mX!o}Xx%P0h;QAbuAfa4^ynEbFarNty2N(O{J#qs8RMU?u z59||ZUQiISes*7gfj}G7Yz=baFykRn8-#b|l!zm!jDL&bp>L{p?k`z(uZ3g1+pE&! z1zvxU_CR4|yN!&f1mTf>DqOU+%XI4R7sRPK@1o4=B#@7@ zw7@>Ct8_ktLb#M%ug6YxRM%0|zNo6pVGLTT;kfzYCU){qq;aaICXFp&(ipUuGgsz# zvQ(Yj>g-Nh8a(|^^%BsP6+&zogQ800+am47`2ntO zk9;*F#V@sj&a_+INr2mW%*DzRT}_jTm~fVRUhX09)pyG&YBE#BjrNLYC*j6?!M3fK zL#aY%_97u$)G|NKKx+N-qdl4at~KkVuXon6X^W)69v^pMFy|zBBw1j-g+Yh$0#nuj z8h`UO-~;=jT1JyYn~Ava8EH*Yxw_p<#%N<~iigSC$nZ1jjVQ^47c^3kwqvl=dAAkB z06?A#pN9Yig6=O0ab|KQEiY_=w%h1Ha?XX)HQ^GxtgU{yx=>fS=W%MFtY`b5Ub+vq z4unb?ADOm}J8>A*92Q?B9HAzlCM{EXpno$?J$X&NrhwVS2W}EKvRQ(5L527viuU@r zUlw+PaHoy5Of?Su_k~aRGpI1+7*(?5!T|x2MmbNM(idmv%T2t&O;+`Q-0lE3K*+z| z3zl-5r;;wKx+aQt$XLL%_Is!l45Z?opgzcF49rTKz9ZxCqwFl-I&p(RnczKR+hgVD zp|pQIcS74|5SlBTnF+^ArYc)(_+L_F8|d|KV18QKZ~obS8qz8d%ZE&{bwq72#ncs%lM_2D1)NE| z`sB=495B|bUL4d4tH%3Xi7>(oDzwSOK4|QpxA6OFo10#CgT?8O}kUzJJyLo-4 z2$*(>X2SBIRNv-*y!r?2J|~tMxPDYz&7FNpZtJdm7z=#{y!p#)_mu=aw)_?=-ii>N zD=(srM?^sgX&UPpXYk9~qr&P@fmwe^OJTc>VPUeq#IlmwUm+QH$*UxFLUR>?`k$ZJ z8>95=3l?q1`mCaf0HEetNHNTJq<7L$oEuq^G_~jafL(rqpOV8r5|UXEGb~WPgHyZo zFd}*q`T9inI8S}ZZj2C~rky`If!#0y*HGwWf5dI%M?=77RF{R_%afYJ*B*b#2^k9+ zcbT+r0nAuFbw8Nh=c%4wh|dze5B;KDVq{;!DJN3KQb-q^?Eoo~v-HVL`YfYK1aZzG zS%Ts@7k)T5+pzvZ8ThB=K98od!qU|I*r6OTBBi2tnvV;5=hsS$yvHc0{$Kk6U;N3N z*?nUPt*FdpmJB`Z2j5rw?O}gRx^$w)SV>W+4?nu>fgNbxj)2%(+UR)LYJB$ZP)>OefH>60<<#-UL8q)}94Ts`gxp$O9Qir*4~%=+b^D4@Y9X*^OrDvM7M zI!m>w4Chc@+tFQBzU#vX8@h78^ROF=-WqWJg6U%(4zfF~?`+~KU31`=p-r8S7+d`l}CPv~M55iZ|L+~?k0jV2YU3`BS zi9562gepgS#2SB6>v&tT^y`Wb+G$_X4H*5ybUnS+Txc{LD7xAbPp^ZYU+VZ)2BI2+ z0ujDdmOS<62Uk5Slp?UtTIjVJ&|cQxeU`U0ZHf8pbephYEfc9Hks@MaXU~LZ7(0BN z!1M;<^_p07r=~XTV!S$^sNzr35HE^7R)T?~sm~hgb+vyPNt)pSL5(_*%=2d*BD_Zc z{A8!8i?&K{l7h?`L3X`vEtc#TGqt*{B;Ct6C4n+G*npW$gwRiUFIHoPP_;2@7!QJt zx}3LaYbX#=e@w+Wv$eGQzpa(or#FXb6=&AErXO{4}Dk1|{{2Lb~ zl2&RUl>t7YDPD1fjSjkf4UQ3Li^Md9X)H@d zk6(ZFQJHmP3nWC`Iom20NSiz4O^f&K9%2i;hW<1mg0v!!x>c6RX7x6Hua_Gpf4tk* zij51Pocr{-v%rUROryQAS}lRDT>P+4PpPKY^By;s`D;S2bwa?b#P+uCX4QqK=+usS z{;tvQw?=`Go7H|Vf}3qP|Bx?RV+UFDbiIF0yd*e8cOqqOmBPUwbl?IAQ_F=1!1Z8v z+lS=L{~av4u!ke6iM#Q`(yFP#K{!h5?T`iBH=H>d#{^02_mT@XJ+ExZ4fpP3%hzy{ zKfKWD6jGjE8LzV0c+;(!fRGC6qjk)eI^{pzu{|j@+ngbj@EzL zx-6!S52xlgC+T}45c*{6&!G1<+a8X6UKFg8OhJp}2D5mT;Bj#5dL3_B>oJWSpo=(o z%R354nq3PAY#fujkpl7Kd@3kpX`4@wH^v?igng;6Y%{Ik9O|pOgcd{Umdc!>6$WEx3>9<(m4lE1KfR2pR3JDP0dbs_SwJ>7$@; zK4`rXU9-0=WbQCi=!tjs4Nl;6`~dgJRLB1-OOUag001YC+E-8Ec=WtZ#{RLhzrHra zn*`}Pxhmx5o5t(9$G{=bJ;Z-vEb*_l2EE@zrYO|};|=MEcOfhg-@J9VE*)@KK9|xx z=k_*x*9<)Pk-l6a!0xBCc*3xvHR}drN^*O2Zs7xuVJq0X>#ko;a$2D&}mO$bSi(#VsLvVxWJk-7&OV#|>H# z>UPqDK-C1P<-|{M*zt}=Djjj{iOIGnVbzk?;%NLRm2E`c6Z_VlWCc7MXlJ2{4y@ph zo$#aB+bLwJdtzm2>O*>_8VvAm=zeTw<3nrD%%4;Cxu7$6#=dp){af73P3&2@lf{-( zlk)p_^%nSfp|`Ij5wCxSh5}9C9MPI=@ApJ4FhlXf6zOjsn?*(na<*K|vTcRD*g0hZ z`o6hnN!3>khC;ETi9$pQv`UH=atgiiPBBsU&Nl?}7Cj0Nj0u-Ip35lg4WbDM#b;aC z>Lq1hO(kQIos71Xuc?E^#0rZ?AlJ%~warJ<)|-)Wfr~*r%RPUHxM z$<_ZTTjZYEZMltBoX%LTOx^Hbfle}MI(FjbE3e0EARKe^?yJd8`GXed>}`eGNA$ir zroRe{KauqXRXFi4bD-hZgiAXi>sCxBmNCQG7x^v7NXOb9`7JCoJB^)0Q7R*I$3Yqn zRgwhanYxoddDnlh9*3ewL%NI1s6m|E!vI2sx_iMFc-ZiGG1+qAH4Vf~#6P1KC9eEv z-7@Dz3ZL|Yw$yof3HemY$U@9A=}2-Fe6h>sB)1!GJ~*?JCA2G%ui&&qeUH)K*8KCG zXtbvL7xx}qiIK7?;3wQ$(foWnt!Ti7QTZ^MXM?jHJ&Ctg+TSO2!m z!!heCbmOvk@2vXBMzYrb@Wk8G!b)t#6}8-;U0PLG{i?Ymb5Ng`PR%Gv^|{q{0$U=X=sT7!Z7=yJa^@>COH?DOCal?j@ zg1O~$THFRhi#o&RVee37VJjS_eg;s7rYXtRw9GFyKB=I}^snJ81w*^9Xm!Jh=ymut zU7N>!`(gkun!gw3F4?f$N3w~G-#@C}7WU?-V}s*fwnn)?Q+huz;A0T*ka=|CE>3>C zt)G8)JO1<(;bp;e-4Wu2aeFlbTq)l61qeoe5|eHe3EfxD7!^Sq7y;~51|DpMX{<$5A9Ij5$S0prLN~Df7DziGcA2`Cvxj1%mo)tDYBW>?hvnKfriKNsGd@D5oGnzOj>iNwc<*fXooS<57vF2^=`PH^pTMnUv-p3# z^KJ3&x{UnYCLnGD?2XMINKuasrJXE++SLCyYwXPBXPmcx(q!S|l=b33HB)T&bq7+ssa;HyrUg>8pNle>H{6LHHxf1ZOF z?j!TNxSaPKp0|tT`!%66;ea_TsQ!OM6us7j$&n3bYYNt@;w{)(Kf7-yH#D<`+T_0< z6T`JJgKI^~^0s8z8)q$3Uks?Pm&RbtxZEIqZH42su$*gJLScEV)bS@JcC#1VD0CnSw}ys;Akx+b^kJPZ^FVZ)p>! z&b;(ZG%-vxjI>%hQ9F$Ek5uW<6^Gt9Y$IP#OV*s1?b??+f_`=8qx~ZY5>LiQZ3+@dla0wVc0o%{o0# zG{;EwT~Cq`{i6aX*n(LIBVm__$+EyEHn5U!fITTcgJ6XcHOgszsSu?KRtO;7;v@5HGIKUJJCEU1YU+mT zRq4?t5jc|$qyqtXYX#reuSfND^qG1m#B*W$1SL(zwr}zoRjdhde1k@?c<8;(*Pu0?sYIs7=vkFttD^=5Bu!XT=Do ztgutR=t^Av5q*Et-Y|**N8)&bLxGtNlp}!>#&NNKpu0edFW4=_aFh{dTW+o?*fAxO zFRGf5Wbq>Bi>jyW74SvLJzbhV0pb;0Xzoa+La!k#NC!zp1EfnO+8imPBH! zb*FFUy^$lCCv||oWunfe-|Tbd$1cx>%-rSWOcJwD=jMO4Ea#v;2F^a0hs;s=&*F+1 zNfqH@n)A0EHwD;m%8`bRTW`5!9VCeWKq_1AZ&!(Z{OG?J>Dj^!`X7M^EZ1XJ+x&+; z$DY_jB%IZjOl2>^>Xdaet98mB?<}GBll2&MMk%;BU{$y(C)LOyrgRa`?_uk$qD%Kz zSld5nGGKorR$k0{@SU4lJuS@weo=a9cafK~&t|mH`--@F3_9`Rljx-R8ShzPWSn)F z&bW$2u?*!O8NmYD=Vrd56U(-&vgFqhAntyH6SYcFI}*A34HT~l4x(j3^J(7<*DTWw za8&oW;!EepRg}VxvStqex4A6Y`)Kq9E7mo3Z1#WEB-IJ^4L;Hxn`^%t8M$4&ijgkw zXF1iUnArj4YGD|ROFPcFy6?C&t37+g62(EE&0h~%H&muJ|8KQuS^v^$NtO@;JC`|R zRE&~}7M{Ok99@eIhCU&(s%EiFn#Lg*7kR0~KmkA$&H?>_te)*;C?RU_>4vC%=@;;lFGi1{Md@=N* z8$qDSrc+ULXHsVmYC?H7;APQ%eu|;}P?W_y~r`S2~H?lO?OgCIsKU31W787&(tGaNhb4 z2u+uTnv>VGv*H4wF}QnKpVDk$ciR!m4~vGSv{?I;7d{;%USuzc&LA# zFIRy>8&0&Jua~*IHJH*v#jR$Alqy>?Yv*cV&k_TE$@X=f*FyahFH@TlgeI zE{l?tma2V?vfhZfIy#_^r5k`JZuunY1VKblTI(66*U3d9VAJifB)daEDWZt}$<1KR zyf$n=`ippCCKN1;3{gSvGlH}Kw92T=+{<&X80f0_RM+&j6LclGpvWz@)Bk@DQ1Lz= zNdx1hn7&x4YoM46&0!q?^ua5q6 zQD1gPR=jZen^IjgzA`_qJxpnl;9f!Ut%WD`08&5^C)8G0PLWXO8myC!EgiIx`raEv{E;}ExS?+Z>iZlH12RDN8-*QQl%FA zQHP_W$JxZX$JyV5Oh#{7fQl27^@F^ubIMCV8BlC0g}bc){nUbv>@~pTGsQk~ndt8P z4wOC!u|w{Q?<~q;j7#QEk{X~nL@gn8==eD*SA7vCTgqi3uF7*aZ7_evox^HUyvE{j z^=!I-;-nI7q@Qg10L{6sfWIKe$Ky>PYN}kFrn}gKHM>H1&>cuLt1Yg^P6}m84@0~v z@JBa~VgU|XR)#V)!I;ouJ@krXr3q5in?y@C5QHC#fhrh4zeNCuywAcnjegEt+x7X<46tzg~%TiukU;#`_s}r)Tk0gbRBL2Lql< z)#obEJKB~hP zqM%?DLD2N3hJ|OlBgs@RSNhCVd>Iy7agA5R>Y-r16Ul!o<41wPQ9Y`ox>5gk>{(J9>`+^?$XvL(&o->2-<2w=W5462bJ5sQdCT+TQ-0#u1DU0-nxC z=3e|%%4vVIne8=l`>>mP0+=}LuY`UbN%cwm!ZEoIss;!xKa_G*7kE|sc6TAx!Ynm9 z=LjB@9R93`u5VedwC>9v*UPtBWV=-d(L%kBM+dq4U=|O5Q!wCXsX$b_uQRpg>>Y^5 zaW2%46iANH9uAk_ocJZL7>_i;{IG)$VJx0G(dU1vWtKWS>YTI3=mO>g)cIQH~TK52jEwQIVCB+J{I_K#C(E zh(K|TJ-~HeTQ>x;8&bjR0Mc&8LAWK}7_F112Mc8oI*bI;Gsf-*ha)yocJY@`Db$mm z6DfaA$`0mE7h9(s5GMcUL%<7tXEvC;DehzLes)CaI=Vg7C>&MB$Ir9~5Gqh`sVb>U z=Au4!vQG)}N!WyiWix(&2)BV*#2L;vz<~~Pq{vBOF1vdO!1-r#Gf!X>6(gstN_$_i zh(47Hu$o(f0`c?{jgqRnlWgmCW$)49cawkjpSOrTVF*bFsY(8oCO>OFIGyK8;hncz z+kWumU#a7vbvhN+y$`Iv5rgTTv-5tm=?9g@aG|}PR6dm-j)^6g_XUe!9kaht4g5>~ z6Jx9j^@+m^UJ+Vu0)DM#<9pm}fCJ(8cfdL8*yEkMa2-m=^J@(TR$+VA&eK0OqrHD@ z1lJX)ROmT%#Vz~fk~;=JKlp@!Uy)KQ%7cqA`(Ogv&bdgiIX>sG1F-$f2w6d?m8z41>)su z=sy;rZZPa#aL6IGs7BKJOWJMgjV&4I4cbf9(=(M)h4E>MY@VFzx1k&CQ^@;R~m z(OT?u4%c}#p?4^GZmR`>^<0>L{EHy@Y|4;+(t>&3UzlmyRL*@`q=rKFRBqQvSw@_@#CyXr`GtQ@r(Xm+ z?+?B2Vx3iB{v)Z?7~g*@0lM49Gxv#Hi!RgH{hE6>F`vtjBt!)@^?#2(4N`Bj@{6=d zz7pt81*Ex?7m68?X@n`G1P=TmPd9Sj|uCP|thejzZf3BCw5TH5t7{1f588h_=ud3msDGdXeRFx@_1Z_Ywt{*aY6Y`%??hT}@}xx=uvFu!bTXF#TwUV& zHwDz)<#3*3dGJbA3K@Xl+4Ba*zxfYNS50cSeAbI(FLmY(2ds?;ze31TD{FCuRRSEM z?e76d;eKEC8s`Ch@ZQf~y`!*p_DIRi(42dlfERxh1M7umCoXMY56~$;VIoc4GKqpP z6U4Kcf^uG;DftGI6lcVR?*!J{b@4x0Y_`(#J}w1*(N%7qE!Gba|BQoYuHVIpvC!3fm;XJ<{dk=pQU_C6A^+tSl)>9OqoFa(+Lpjg|oN) zFCKq{@e(Qkumc!j)9YWHh9|l+`zd^b4DYI+miq@8yqHk;X2SWyw2`dJE0BARznhR& zM*W-hRi@7$5MLQ*M*$A-8x1dfOJEKErTZ0p7DzdDe68{7gSzg4x}JU%qio&kTWicP zm>x1uEc7((b*GVQDVoh!=Wt(BblajRX%c@^Pc`Di(dWJsm}5+_H#Tztw%GHD^e#B^ z#*cbQm9%<2^w|Xv9XE-+d}$1M7+AqtKjo6Y)0;fh5gMlb_y@K$teY*m1u+-D1;5SX z30p+Du9Pg^i~Q8x4fP|~+mUG(E0LNupC$V$Abz4`lCG&S)MdYCEYn?`e(PWB=!Sn+ zZ$9^|k{ z{w}e_-o>{4t-DR}7JmiluI?)7*R?XaDS6_qF2|>hBUprEI`>@4`K(`C=g%g`+|)n7 zF16poW5!<%QKcO^p8bj`FsaGUz-WHm;AiElPuBB!3jDmU;Y|_FB`JUXt(cOU7vE;T zT02pABX+@!qu(QcVU{b)6w-!vK#vqS<@>8uXe{@%oFck;j)MkFG2cR@kqLu317|%t zwie7z_VMNCNeWnFqC2G}!Nz;E0=D&ESH!v3;@nKakkhOm^09WJBj{ZdRBnM#Hu`etAtX!7gDq!On0(&c#-7lPFuT!}+ zseJ-JCNMqonBFSnOSbM35K87dS>JFxKZJbR1H=LtlC0fFdv@gdPKF>&A(@N+@3asRio>(7r^;srlFdm6$PFesMV_dToe_EjgaO9-Z_l?%YitCmWX?r1;k%3d&%IA-IhMyFnxR=$#k<5JGjqSC& zS9l$0soHh}-@VDjtVCD^z#W7Cx%bKX>w-Cmv*~|6Ydsq)_dCY$S;%gN3yL&x*}!is zF7!L?q%WPsql2xIholGTUzHHKadkKM=1A|YucE~fi`=0M^ymtpX{jZn!5V~yr<-S( zJNZ9veCy1+cb;2G19!}Jy9U6hxnG`cfZBzV6(}%W;(`}fTwPt$Y(1=`dWyRjurwIV zb`^gx9EB6^;?Y?Wmt!fZlAX%l*|iI!zgVySv9lq;XuLaE%(hmWIOO@~S_LW-yvTT> zlX~i8=dXMbE_!7~W_00@|JkyupmFp=ftRH_kk2=LN3Z}k5L&O}S~DU`JoP1j?6u9? z$ifp}Zdjf6nGkwg2wVDVn^%V0!JS`1fRlei_-;uJNyS#3f}KZs=Bu~vzc5bfKGT|G zA8;5<-|Wpf!{BZz@!W#|IG-1Tl1suf&}Ge*Tlg~6+t;@t?905CddbsJJ8v>t1BGmg zjf5%BA9j*tWI1}`0&8UVgJz%ojdHZ7o`leLl?t4pv6eal>q~x>zXYHn95%=`xA1?n z+{^WH45UzO{*va6gUOi8kV2&bMVIJPI}*c%W8rf?T^u7jKWch5-a8d`@!N(mteHPq zS-i#HB`t#&XSv1?Qxbv9~zm$l2U8_ zklQqc6X|XrhH3fSwa|?dC)m)xutk5T^TL6dWl#lMGAgpYznXGS2d*mVU=oBE+2m>g zu?kl>*!fL1&dt9R9G^%g;k^aKt4YOU#nhKFBq0dO-eV^KdMTlV{3IfYu7+o=QbTcl z!Lx~Uktfn7Z`ZGUJTP?zcDet)8O#1|W&fNbBh7qk-t`zO z-P*5F{2!}WqzzGFM82PUIq!dBKVF)50`cjE_4#G+3X>p}+v4BH&c`Aa&)@d$4(RU> z=nq1;IC9rd2j;f^wHp$B&vfMOYD2luNPZMR46scnzZDsY;GS}}`H+_p7_N)>Q#mDK zB$`~}?=hVczvzn);`cZ2KuI+}URSrLnzPRi?l$Qrt((Q{C)b=PqL+W52D}bOhc?SK zf9$+Up*UP@`nN!|U5|ma3!lZ2gV(^Q+aBP}&n>Z|X;4v7vvM)jQL2FP3jNt`?NDO% z&RjGZ>p8}7hE9HX!6_omvxJ4*n!g4y0SJAlW5{{1>_v=6Z|Txph_yzZ1%Ovz@eiMb zIrv1OhpR!*H|rkDY=wUo&6_05c=pFv-Os6yMiz`ZZec*uo%kP1Mit#Y--PuZo&L7b zwCaNiu^<6u(Zj$!*)TZ8Hbrrh%%Fp->bN$HY%&9ig@x|2JULO98C8Z#hM6+Jb=TZR zUFW$1hC?^lKWT5l_Yt#Vecw{JA1A!X~8rXlod<>@%ayvuG-B$-XU;RjZBf=s9Ijs=-Nlym~I|YE6vq`B9C!4I~tvCxvi$$v28f2qkt{Jwv^S`)VPvf>pcVMx%pT^sxS zvRwGz;y!Ny2)c05^F>6}Ha9*$1%U2mvbmRH^m9FPn#Z_YlS+=;z8a=n@Z-lG_z6(- zzkbcz9e8~NJ`M68J?c7ts(t1hjNRqLlPQI3?)@K4GCN;j$|{hFIZGGbBu&mF%S*Fu z1e^1HZ>WDk?KRin=9(JZg}5v25=Sp14TC@C*dr@lP`_4cd)9YMbgiZS+&!A?wK>=o z@12R|q{}=Q($woJlDoIwa`TV6KzrD2d@LXk>UX3acHxxhoRb?_6T6=3^;dy8tXa44 zp(fs1E;KPITCSQ5j=N~n!QX&50AGnX1Q0kG*$gHyqq;mC~cO5Baek{0YVFQ)-6 z7o+0wUw*zs2agx7#`C*Dte(4gy2>55F{KCDmlQY%{9qraB*k|NDQ7e;U?2Cl@1VHo z%A+mt^Bx<-f>n5};;gZp5&d)jWqrFKQ7zzf6_=#!GL21=mQ zYP9xzmet@bktuHFW?FsP^vLcDwGk#IiZ6;kEyw-|jr;6_a>k6VU!l3PiS%y1HA}3h z<;EA8j9ACLH{Zw3TnQtB&$E8TVLQ;Kakw%(_wyt>a_Huoo?w5% zV6Sh;d1tiJkn!KEdAtE(L=xc<4M2q{Q)?azyB6IoqH3D*mQDO!!;>z<@hiGU_$9g` zXDg+&*>MYOTxj~n?>v_lQoRl+yV}EEc(*bfua;xV$vJEixg7`K+=wP& zv~n}V)q=94IJbjph18F!LZyf2d2)aGGDck%Xs{fJ>9Lp4^7W9eL@66mTMf9jCg zza}E3{Rxn}E|p|cr}0lPaqG&6BKDng5ZTTHr)>i~hh_c(ufPJ8S2 zWjq)*V2)$a6bW8F$xHbf%YER(T=2-Yt==%Q8D%Wd!i(o0P?+p3JvS;$jAPnKK|tQ2RZTP(f{1aDv+h5gn^v2X7({ywRhmxPdm*9Tw>*g`+!}dxTddS0L)!plwBNiU;QD* zF5~jEb8E7sEbAN-d-8jnV>0D0a0f-Te=CH~@q3%1uUYp|@Geo-DMo*0BE8V}@}<0) zB381xF4%XUj;l0D5*_l(R(7;rD{1nC206#DZRJF00?=`^Gw-tc!OI6ilfu$R-#D}b zonCVAd*h<7_hEY-Qy%T$9_g;G*TLPv&TN!<3xO^Tq9!AAtq>QuJrjKap#u0#<`EMn zR=FAAq$VI&CtM|Ap0i|lKEajGH>00?6aN{^NcBAb;H>5GDNn%lTpQvR!ILI$_uCP30$_pF_X^^_!zhXpgq({37ej z)+&P@AgBEk<$r$!v7%@Gzs9u6f2Gd(c%G@eCC3I4iZ^dlp9i0 zc+C)n9-NtL?*H%qBjP)tnhLgPLApwjBE2IZRYZS;KnT5wf;0iC3WyXTGzpNg2<(&;G`oP zriz@Sj|-fglA=nJ|GX2#Zcd>}fM2?MV;qS$lEvp`?rRrs@(*$X@;mbnwLc7P*rqeG ze=n*w*Imb6|9Lk<>c{r3)oGYV%kq3d;`)D74W}fPeW{7}S5^qs&baUJq?$V*D}GV8 zf(ah883_2M?UVOgqrt20?K7R!Bh7Yh%Wo)XEY?Z@8$`RGYWlFEfbPTWgjF*`#Sh88 zLO~&gLsh|Cj96_?8i?e3P*vaeKu z9TXNS4w8iA3K!fRq`zqf2IMYRa^HWvWeG^?=7F|6HrH9OitGwbuY5b)>{8U_6I`hx z;`EjztG}84nq>B?av1m8(5!Sp^XHegA056DZlr6on^Nd$=j`YWg*+S^e=$DJ7dOtk z+2qi*mj1|hlhNRZru{zUPou!56K7vk(cS}%Z*Km9$DDuPmsQSu zI1tDJ@3)_8DKLVnC`eLOwwZAzNJ9qc(I*r30+%nrvSSjEsf_!wc6xJ;f21?MTbk_F z=vO5ZyIU$gBo{4{rJIn%G(?+IM}se?zp*2{kXkk9stdt>*2ki?agAFY+2GY1DSD_` zq^ocrCTB{5jGXMB&!?)tdpLg})Hr@1dU-V9$qr-#6477OT`yAV=T zwzhNVun@BZffK?K`;AXri`}$~U7fAza@x%YJc|}y0rp1~2DKfgy48QD9@MA!Ycrxp8(iC7v~B5mjGnI+pNx8`kcR|eU`{G|moSwx485*KA{I9d%! zZV-4Xu1RC$cA*A3qjP6btgkk|?nLNbr(QH3I@DtI zD(zPqVj(WVkZd>F2IPMk(gc3Ql`VHS8~a2)?I$*geq+hC-B{POz3y!o{F}(V*qGM$aJ?W zBXa9Qw2Stec93X{`MVB#?t!W=)jr>MHQrtaqDGta-Vc9ZJ`#UgEf!l*T6!VI##thp z;4Vxz?0tJ>jsYWb4;GX}TqoYkr09d6-yROaxTn6;g40i%7;&*AT?oA&KZtY=s7t`Ad*`~vgF<HB&>IT%N?YMNE4Q>$fTiV`}u!+;0V_smlpR-6o53^DEVF5 zzwx`eo$1mMBilr^#5&^g^s-6)n8iP+RUPXUJp0d@afR~Zxa+g4J#DN-HMTUoR^8^a zUq^3W!&;wDRCnd%Qt1bgzett2#A2C#pKnoDqr9v5o|f>oQTvsz83#VgSk6T=Iq!v~ zJLwAkSzv$T6+hParM96Nq^147?uh^CbDOq?rfzkNbB7zRMX$bNO(|Xb2XiB!onEmA z=s{d3RkFxENyI4!r3pV$_3ba1TXXVB+LLEw1b}D{?uk}G&$p9*Rrq4|Uil2K>91=% zeO&axkaYt-`_TQV=v;^hm3ms#83g!gQ-UCAy%>MWLreNak%M=IRg0GqdzVVXYE2nVT%38P%fu^x>!;(k?yOJi?Qnmc zYFmBJ=bofVq{4Qp-^(FRr+U}WtvuH}vw>4B3HJK(vU3CU)>UKJT4Va=b^n}xsPj?v zD~_C(?iR(J`~1?|;D89q$z!aHY_c6N_5}h^{ry*%Nr}L+_!Iu&FoF+(?autPQ3Eea z-#5c;)|*7j?!8=AP3xcedJ=#5L_X`w2dI+)8x^=ZvYJ-KK2!Vl@&jC=#lOd2Ee6Hf zt`d%OxePOGEJ!E*8xzzNaWGO!>SFv(<8LI9s;HeN8p#cuTk)_+K4t#!@h*RULQB*~ z&2COMMfZu(kDca>{;0Q(5g(G6C5guR)!S(z#UCDZo4Ig*6kpzX>UpK5uGH0Ch z5T>3wEpzJ%2Z9OKi+F|$s{~G0jy2U**Ek}7vv&B4a9K21TG=W;lChalR_n`KJAW+K z+aSa@R%>_1<~0HwBey_oG!cK?Xp@x^_}=feZhgVKP7jgip8;;NWCTmFleAD9h? zBqCb7LfSxsDOv3`NaygpwR-tVE_t)APi))VZU2Pqh)t(C+8$O=hs=LKhUrB$3{0mO z?%Ngu=7O1L=&ZYzmEE>_oL{xPY(D&JyXEe0hY9q`kpe|J0qo!-+pGQ zl!-?wC(be>)#-n1*z@i7CT$`$O^jdtigDvJmPG)^IEO2v@Hb`m8 zROpoUDrFr0WvS;hne~5z(+>}yj~$%b7i80N#dg43|-xP+MeQzL| z6)^BCQ|F$3b7sAAs`ze(EWh9DoiWOklJB2eo`CGDdeUFJ53)T7UWR{QLVit|&F-_@6P1~A z%uW+|%P$fm2gnq$%%vvb^lLwY@%0xHrIl>Mwb@H z`>&@SkKUUPF+=j%Q`L!2bmI7rrX%Kmvv_O$sYAjPoG*X(=3+k=&d_`jkjzXQuxolF zA=Zw`a{RIDok;rZh?^WjZB2Q90tS0qt=G00m7BDF=um$g`*%Wvm5BEmXg@<=rzmO? zToEPl)DxspNb;4Wto~Wmrr>4?Tgd(I!R&k&uO87pPv}2$XkUgu9o&^b-XjeVNew!< z`$ivT9>GHrsq%*oY*F!k=JZj0A=u_EQ`wu0Kl^>rt(|3VCo;!fxoXWKLVd3hj^h+V~Xe> z4iP#pPRu+EuaxHeEW>3;&GfRO{ksj1pRo|2^n+fq-LH3ls&^O-?z2w~J(U~*O(8Zh z;?iLTQ3FQ^niFE#DSO0FZOJn){ckreDt<#DZBz$N99OSC76b~QFR1g_eUH6!VRIoi zA8n{_IQ|F(wQ@p^b#t#}QkQh)v5X`B93uhDy_ZG=c-dwACq=wPE`EXFriBdu;2)>S zCC0cCFa0rpfNC8t&xA)3+@wtRoL$M~;sxR{R@B{RSK`Y7F6ER<=w-&-ww3luWjq7* zX9d;ku-4TVtf1E4GK<%TA_AuWx^1Ft3h zJA?2BHezYXvt^eb_SrAYGZbsArSTIZwMuc;2&LPFDfHdlXx0JdEmG6yM&h|pq32gL zs8FnQq(Emt>g|9TogTu7CGKqS4JY?MR>GTtkwfuWMo!*r8ob-8j|3v%&cC_Ai$y#v z(e@L6F;-Xa-T~fWmEr)$JjTANpxxMU<{xJphQj-Nbgk<0f(6~ir`jP$S@E%R--wPq zSZ!04RlZ8m(%9~)jE@6bcx%1+h{O~9XL4Vb<~3oYM&GrR$9X*ZnCo$&r+1OHwXlQ0 z=YpAN(c1j?*51O=3sLWdYiF_qS7Yq0+EAE(ihy6=%4()FTythGGt>Mw7kipucf*t` z1N*}Q@O!KylDRBcf5H|b$Dku|N*F2eX&;JNu=43~$a)tpq_CLCUlZ{h08-g7BD{Ly zV6p|?uwHzCUiH;@p^~H5uaq;2E}`&$iAW+KQg{RCg&V~2U{UDz@^ncVXD`zH?Q)vKMcM-SwT#jfu84_jmuc(( zyfH&!1r4bLg_pN5mzpF~Fm5o#Kj>c|xJp1frh;cJhX`{HjLM=e!Ab7N=4|DEOnU(J zh8>TxXU S}HdXhu$16N}SKwuN>W^@UzVCOw(S!5nfq5lrSBm7*G+#DZql|A~TN( z*#+&A!M_aJ+A9lG1Ay#>yHC7y5W&hj{@KEmxRdYP0jv)W*P^ zVsBzD1ELVuR)Ul;vD@KNC{7!H%vmnX^O!IJ3GXul3K4q{BSa!wPAS9M^#Mzem!&Y} ziDePfv|o#24(s(T3aQ@jJ^O_eh23AH5^nY+zo2uwRX$w#%QYCSUU8Ie+!5C=R7l?zK*Wq{3h6qqbA=kB_sN_fdzhN!rNZhZc;^^_MK z{tzveiaon72z$!oZd@h#euOd6n{{mS4<^jPS>OiXtc{xzCtb*m|MqNs>09`f+-)+% zC@}{X4)xSWkGorat*otoU|f_ikYNmnlj0O-!g2x4zfDHi`%HW>Vh?MIC}GP%GT3BU zk(ZrlJEUTSZ?)AZ=D6N!tGmsGTo7pKHW!@qHUT$Gzka{|C!lb95$zp%@jR3`tJ}C4 z&(@7!blhB7+{&cBm1%q{GvMxi#3Z3;*@VDDCYx9-vex|M!vGS0k7N8}Hy7@RO54LO zS>cQx$U62 z%%&nw*YAYsvLOVpJwAFXNoP}HYJ8UM)O7lmoDJHP6@9t&Ox_Zg|9BSIPIunj_R&3I z+S{?Cx;TA4JyHbsi8(u!B7lw*s;W(%nzk=YaosL{z>E;pjPLjLyAsnGUO z&;^_6DTdh%Sh9U2vD$`hI-2P8FiPA*+BVCkeYNO+ZSybzSShVxvx*ak2UGI{#G}?w zYIv#yhk;IA!3$Rt=C&urqM#$8M^*d&dXI7){~8O6@8#HAu9xmf-fWuit~fdRe`bH$ z`mJ83B5S=ryQ%7jZ(qItQ+0C1s&iq# zHijdufd4L9cAAiQGHB4Zs8mrtBu~=k3aur7rby%pYLt5|K9Tn#mekRZn?cC%=L-GX z7kLvun^GE^ZrjjafXCuoz=!HV1;1e=K->?%zrR1f(1aO2lp*MTLv2PTS@FkRpWAoNT5Wr`Z~_@vQ9MH@xdNyY$()$Esm)L#$vJ{0){V3~u*wE2DF+wKmRw z04Dp7rT6k;mSwQMt^Dnw3M`_;CfqHDuy*RrmPth2WbKsQOB?umVDHq&ZqICaNb_** zxgkW`YjI^hAhP^HjDw}0#1Ef?q3gMS|1@GH!!JjmJx_n&4l6hP2yD`if?}oz=B8$Z zs=a9NmP=DI-K>hIzqnPYS(Q$INvKkPXWX*Kw@-O8zB6oY@}4zbJV$fgQ(E&nm%5wh zpFX{Mb6~(UUaf~rt-wDnK^8;z&ue9i&&TOOS(p3PrOGwa;LFM5y<--v7erLmb(-7M zH3giL;XGswm2+KS`+z?3a~^ts#ieRYJ)1s+ePDKPqUs*=SCIB6sW+GDPh1>-OVb=( zhiyK+6V^X?)STr~8s_NQcfB*~Q25Wxn-C4d@(`j;!`cfFV0YBy_Nb94~- z#Aq%{Jmuw>bIUkyyDe7g=*F&H?Xg~U_d4{GWRN+nBgZR%8SWfn>D|p-qj&ns~ zKH@?)OW$fMU}74_dFFMqbs>v?pJQ;t&oQnBTq<3`yS;8S)@1PoZdv$IreXZY`&$9e z)FrOqn;Ay|20ola3a^Md2Z{(+x1TAVc(df<d?b()fxa}{uFnUcj%I@%Y z=a47zP%L~q?&(BP6En@iQ0TVHLsjo;?#2wF(FOC!!%ZbmY0jO-Ci?s)lE}Td&0?<_ zn*7oMuEs{T{8BX<3k$-3(aHCb6&0b|jug=arG=4uFBEi*H?A$ikJ;Kd-T_+KZrIug zXVSwPcsc4Ade`CxFqaycv7f78N-#kB;jVcsZ!SW?EeE z2-al@4R$%>ERXEJCq9`B^FLs_dXc*Fq^RN^ZqONVXHj-2cEW&vCdZd$)c~0*13D8~ z1*uKL9vt~mps6lo-Tn6}w%)r05CPh*11zl9*{gu)ExWqjoD_zH_4gRTYxb(AiQb(h zf^}XV9!HUr3C+AzQHe_=7NAM>736>ixu0cr1m4Goa26;o?rtUsPa*PYPDHFt#z308 zKY7NCuQk;QO#se+ykqU=x8$*HcFokIAF@zR9>KTB*E_n)Z<;aCfaIfVThwYK`g=5< zLEfb6+8&UzsQ#N;Ob=507Zd=EnESYpS^MUO;AZcV+qV4b@hzCw8w28!&4ioIP>j7W zIM3CiTO-3Qq-@JyX8v%yl#Z`K*WJSV7MNR5-vWLM-CH1kHSwV1d!1kW)ef7OSC(k3 zqyvJn7pQ{frQ7=6xJ?DUORZ^nP0?4{#^rM+%~yF7v_9Du-<%)N)hleX>N81_sP`%s zFXte+hSzzq#IwgN02BD+aOFSN-`UdZqrFG$>hN`0w6Ndo-}7ZrG0YpOM8B+91&mP4 zx+OJlddV|?^rt^{eN!ncX-}-)c41+~Rek&l>8XDqcQJUSNai`4jX$LG(zb-izh z0+>2bmcF;Zh6_GP3-Roa?AawjZ`1Y`INgDxV<4Ww@fsLK4kx~26G>hUCkglnrX!p3 znA}HUziVsSXRb$c@eOm|T&p^|HYcI^z?ILHjHz#b&XL#0%;0-7dumGEhNjgP<%{0N zcJ(Qrnp>zCky1Hv5jkXGIRE>PtIjkMPkLkeaBr7UYlXGhz;fUcsM+e4;oM( zrE5@)%m=IzaMyas-n|jO4K6>M!7H@whtw0JK^8YT-H%jG zJ;l=U?ZJJt?Cp=tJo!@CM)l0y)sX9n0=^G_Q=kn!7fbph1B&8gEq6Q#x0OfKa=)nU zO`AQwoHc*3oT}6uOH&Sy4V_l+^VFQ{A%@kZnqgMIrO;ICu?=SO$Uv=DEe{;FY`dAmwz_89R-=vVTO26ric zB*I7*oJ?qLcgNTiVe}lFOk}=s$Jht7Dzt=1R&Zrk-Lqj=^Ik2NjPXvuFoJjPuKE9- z_M4&XZW=&^nfoFjy3FFMzu7BlRQ@bh!g4Voixj>onMEd0!b_t&*KbL#-%?%+h508d zwe{y&F^p8c;5;ks|8C{CQBz|cj%cxeAi4--tBxCZJ?hjuFJ00%FYTy_QxP@2?05j! zq;=o0mxgA`=M!0Te6BC8?X!p_@vgC4tA*c(zFPdHcqJ!;YAcvd|Gc^J5V^;rN| z*Rd`cPJWu6WZ@(;bkF_dX=L*neiJK2Y%*@uLG*@qz>4`Bsv3z{- z#MLPOto6N%;ecPxsy@+L&C{Ddo9TdIXXf__q5@{N1CQfHi)s@@GuBh9v8hA($fBv1 z6G`U;)VnL>n^9gZH_7O;=c9S+3+BFx)hXK4j++gqG%1!~(EzM@ixOFX@F7uSW#-nq za@YxEa1+Q;m)b*TncnmDDRtI~EVG}w$59^gEo9qcIZr$=qLrNEA~AyFt$0sc*<%G5 z3GmeDcw|}xco_z{EwHWbs)5qdU^n_>1!?ZR2L97HZHlLg+^x>+)?Y4vyDuY5HY^la{esi&japA_TuF7Bx05K^h23Wh6LiM!Q%!hbM1AcT=r5(* zmY!=hG*bC+d-{L-CwHcjc^azGho`hmXi`x8)U3hW8EdyxBrz1p^;Fww5pJ1r2s#ZV zzQY&F7fSV+*zc$Xqf=##slZ_dbG+=on&#MJGQAgnrM;I9=Pozr8YI82V{qMAC`kVL zghd+|2LYmpSED+=MhejB5*m-%2n`QBdlFlrHNs1MROs-FWHku0Ma#IF?)ho32z#ef z^3NzOn*hj4u2I9UlX?_FcJYect)d*YxGdWbJ8tOqJ$)qBB}L);N~*JTFF~bEfYF?D z3nE{CGIn{@z(QXcb!1r)`<5Qw;iI*TF=&2Xp*y9{9zCrFRAXiKtbBQ4f$JpcH0_+l zW*Y)KfB60>ybSegO}jZpN^28kA%v6sf;_G^8@4VEkS+HX>Vzw-ieuZCjr!G=fg2f! z(qzWqX+iP)Bl8&S+kn|>N^mP$9~|UP3(0bSmj>s#dmsC5_%HKp+?-yK(olCwb@>i) zfur0dAR%r0^UMd%p9FS&$p01oSxRJ12-d}*2OVS9b>)FP) z@vh^S292wXZ9fOBHNIUnGh9&qmYh|MpY&F>qV9~E`7e3N)*^;TasV{bKMUv)}vbxL2gac{M8 zU-k6+_1Qh{Y^iA**+oB%kPI5?<~C-Oca22Is^o(JUDj$r5UY894;vUEP+@#>JPQ{+ z+x;5Zzx@qAZTYm&HCiK3X5=?BB7@ znb})>_k+gK&}uz?5H$h0{We3N=~^)}r`B;ZzmB0g8U zdK_)saG4(9O-y{mryF*c>}$qD<&(@@_`Zn6)HkQ``Qr~Z6lP>n2>{fQ%a=ifd2L(5d zBIjPd_Z};FulVSKv;4n@=3v-=9(|~&p8l<~WN%t@ROEFL^rCE>`Ubvt${z=MUW1(( z#jp%Dm%HTRD7d=Z5;hh9J&LP1o+_6D7U_L7gT zpwEp5p`T+@arcs20C(%b&&@{^w~S-M_(cS_6{^%oi=cc;1x z>l$A#?6MRzdPQCN1vm(QFE$x2&5^dg^pUI2KvNwj_ctMojsE78ir$#3+??_R_l3*A3W5r6zb|A?ocbB>r-4{GW)mb-4K9tA`sv~~0?Jy<_~(nNdH*y(r! zdcv`+KereFGQ+FO5O**SKqiVU(_D)z#Ac9Q;xgC3p*fBJ1Lx^OineKg;RZm~e5R7i zFdwIV0=&Af2awFfyOmgU(zzcpET9`=`HGyGnlWCtES6xhJ zZ&4U}Y05$??kpgGt?))1^YcbP0|3|Z8sr^H)M(W3u~kje_-4Z~`wjR8lBA)Ne4!Za+i2^C+KDC6CGcd9XIJ z^uIfF3dtWsBYH)JD@o6Y{LmS8F3R`!gsktq5ME$^5fS!(eT+*`C^Asf`?kGc%^f%& zT>W);Q@x4WiY+*qZrnQv*c{Gi@HlVU%1)w4!Kd$NI?S`p-$%{0N5!dPnd*TMR>&Q`f${!I^xQTP5x1tRJYvZpkEJ7NlW?El|7R_kws`oY3-9 z?ELTN0ky+_mDWIwhHohI4T|oQBqvs+@!_Xt#Rm9-WNBRML#v-C|L!kIm#pG%IINph z8!}P)8|dzVq*4}fCP2gc;fLlv2GHxeI%^na1+eDEYiBXUv-W?8bz;hw(Id)$_Gqukx?CJ342xQWQ3DvZ?xrbrE#Wf1~+ z35Sq>W&~($*{cG-b_GmfpFpR;Yu2sZ!9775fg1l{{#CFb+yw*ff)aPZj=LbjUC`k! z?%^(2ad&StQN6}@wbCn{WxHpbicf2tK zew~rD!LU1{=A=NKSPnNoR7<}~ENA@8MZ#1O=ML~nvl2CkEfc|7&LU>p0SLeWh?%c{ z(aZL{Ax?y2ua~93%l3;q`!vqH=j@iU7kI5lxwGS-6>Fq$uXXsStV@hLyY!`bk0{4p zy_EW1y=cGJ{E7#=w{O{61ylK&%O!f}_T<*mvW`+vSg8tTE&^?Cs5sy7Gq>JjG-P#H zEvz%^%iS+>j0_LF#e{?o%?(9#w(?hhSKFw?SM>H?MDM{lXs0=o)hVG^A*m~h3KD1hR$1C zn(=!FsYUuuw-+pW#po@KKYrP=6AblIYi;DVT1cqm z=rz_|-(z3jTaekU%im zH};v^8B}%`cYop}?dMkYYovWg0|4yeLOeVa;&GyfWDK1+q2RU@4K@C(;ZtS!&DGRAt+yb}}od?H)o$1)-?)TI}GU@96mVP>R zlxzM+So!&Hsl~CQH?ieGkg?y&WGhYOR4Al|(~>>Vm~3T|8{)-e$sS~^u`*dDa>@RAMeKKRt`t+c_7=XPQd$j*e*HZu9sJ4;NX3K0h!Ma;w+x_{BO5{ z+p;>IL5(IHbL>kUM|3C?OiQo#fatCeDS}ot_-=lFaN>&2axXxWiZuSGEe$=5s^TCa z9r@is)y9YGI zu6ks@Fe-dCuu?#Ow>|uHlK{TMbHTOem5cCAEBAWw73H4>skO(;))`ed{U7d`;U z+F~cPDLIySQIWjtRPczS38cQ7#>ROM<(5BvB4O!i2jWM6q(-^BGPioub_!?%Gu9@# zEHzdEY;6SDN6Jwt8(6jFqU=l$z~UQEz|_IA&%cmtUYocz2@f?+-9&NRf)A}i)Y^&K zG+)P%L)opsuV?!8-f7!x0Q;UrDRY5Q5GON@xLBJ8FqgPfas&7ko=AgCM1kPqB&ac3 z%<%WA zo+(PND*;~e0G4UJQ;@#8rm6ud(KvPcT?jXz=agc@$ry3SjF0u~P(VdO{TSObzbJ_( zECE#b|N5GJdD$ZWA7s32DS!22aVp5yk7{DhBX2Q(J0;)OOxn=(lTWdIpEfKkh4lND z9mDoy?%KxQstm4?7(GdYo+L+mJzg)BSl@fvYfRT`JWjt+YAR?|RrANZqK5oTWag+W zK|(aye@p18{IJFgc(vJ%8z`J(>npMRFe&rNBZiHByPUE4#GU~Lj!JOnS~418gp=Xi zjKcVTn>{|lIL1vg!bJC;=bLr-wTZR+xsskdPeDzeV1c93zbu6tDfghGpGV7z-f z%dX*_uK9nxS;r4dkhBZgXU?PSCUrCm34_x50#BDTvv%6r5*igN=aO#?(n1$7Pf7+0 zyw9(jlXurk_xIZ5%J3Y&Zv6gUhzFi639IdYwRwNM7U(eI3@dF#7zHdl5`d*f5=)hC zXT8ggg zMSc2x^M$+S3#8@?ROSl_JQY7wmmN#~PG%t{J(nFx!BUc16?eXUAk?l7Dr^cYY*G<_ zd6kT1dul#JQn5*Bd=gYjf|yiZc6&!EHn8KD`VVjT01S?6)@Y;*YlhD8CUlGR!6iig- z9@)IrIn}0U4xq}foRhn0*O}9SY14gw`&;{bb+9p_Z?G|zLS5hZdFWPo;YSe1@6#$J z6zUf*CtURu^`{VSPtVE9j)OeUhi~1M{kd4kXafAz16Z@|j?I@YbL3uXN?MT2g8~S8Q#KfL_PvL$8_ojR);- z--Fpt`*weU86?hP$NPqBe9iN04I{H~g_YOIcJICJ?FUEXm|7`z=vhI;~EI)?M%Ce1l#U9#=`f&yu_Qzptms;_21s!x`%{S`j2-f{+JK z?CJZ|4PO&h=dKGe#AmAYwTG%c3d#M+b%$p&6tE>idq34fl_Feve(v9Y(U01r&*8=Y zig*9v7f)Xz+m7a@h5Q&R(| zqG11GK()E{eChFZH4SnKD;Bk7U1mOcD7mS$rNXGF0o$kAF8H>F)QF~A(kP*eqwb;D z8Cp)}Ls|8$qoMF4X9Yyd)BdkfJ6XUzV zt`Y51(3vL`1MqVw(|q4z#Q5c~pi%Xdp+s8^V`RbKn6v9XdTlh#D6i;6G)i>FykJ9f zYQ4=pqLLS(L><9FD6d~5x0rk}`?{Mw3}iQ!zU=1|?J;zke!Y=@zFBX4?;5DMDr&^Z z*I2L{qUNm+i`*XeZR2sU$ThQ>e?Ic*?4QcUKdKUHI#}^;hg#(uSm^eEA?IV?^xXng z-D$r@Tvi^cAnPu_`GV%D$Yf7scKLy|l`*I; zZn^wxMBO;B+2a197@=!cyBXv06hpHYk?TUc8JrI_HQtebv4lHz&pCM~J^-DWt3t{N z=Nc>bWWX;v)8H38R@d>BH@(vY>rPx~DRLZ343tt!zct(!y>VgAalpIPk6O?PwJe0G zYvuGs>W*TKXszH7-q@lvtdzh)XC;7{|Bczx*p}L|aZtmLr#9NC`vZnexU+$cCpqR+ zbzlGwpO}V!P|Bl(-96moH(wCT8B}B!Co^$^GMez1I{vtj9oQ)Uz{`(z_uN){Av?Gc zM!9=l^K))G&&3Mf2qW4(H=H?1IYlxh@bIg)0~leNGNb7d0i`VA}7*;8sM{3+Nmg|#Atf2StLbV@15Z|e1^ z*T{1L(4Liv37+<4fDy^K#~&nS%)VmR%9G=N3#bDai+_y5m3RkdSmZPQyqT`5%$x5x zlHFCw+4~6>+4~u*BXeoNDc25lM(x;?cJ&Bwy3DpL}{nm*MJ^HUrIge@jZDhU((9hM`V_iwBnz&u<`oPfB61a6jyShMPhT@S!P0get0s7N+UV-lSx6_Ui0Nhf-w8 zOC2a*^e^&v?Jn4;YZ?nXkpESwixisk*Udx7t@||+Lpyf&;R@M}Je7cy# zKcsFfOCEifhwIMyqF<$T9{Ep02Og8-;l8%5>$K{x`(=K^hX9Yw3^`Z(&7tdm#jLEl zE^{$s_KuAg-WvfWy-(w12+hsEshURj=^OtO2->5t58S&)t$gYJ+m_Zo?-h|lHTnE& z2vdCm_<4QR@p~}c$|FyC?FaBg>{GD8%Et1?6^3P|mGNgTEU81}`@djiCAEbXf zc>9~3d(Ygtr~fmDj1ELb#u7q*T;Fi43BI?Ym+f&EPFhFHLF6I|e2AI8is9wZ1qMNQ zP<*R>od%Ib!9ypnIvQg$y=7~PKP>Y8V*XMHbHnPG;dFrPrMIOi-{PHlB^ic!JsHaR zK8>EnT$sH(uM&i;{+`cRGH~a^nwB@3F9E28tq8#BQ=p{ z-0>auR3?LMfV;=NuL|hyECcwkxv(}v?(WP7cplBh`YJA#yQe$RW(^8<1_GW3v1M!* zw%VBjGgPx*@gsl4+Z*(MRXeQDdZPC~qxa*ue4clFv6uXHq%&Jb=H`L7?A&?*CBwasa%xaF0Q4nJ`N}ftd8KBC z(XzCj6L9($3kt*6N_r&$IE^}fd%X2GW4kG%{YSuM5JEYbBW9PznSQbWzJtx zG(P4Ct^v5bFaXjY*lS%riB3_1)^>L6nA`0%_S0$5XwVuX+%}nR&TLvc{6&84^!z0_ zTN5+4wKF{*_o1@JxBSNYMdJgpFj{=VsseYb<|^4^e{xjU!%8aNR@GGv!5hg{Cq93w zW*zKPNXxO0V*m+%YUsJmI(LQy`blhpXjsex_#9j-qjXuI7tdZFu(>Pve!y;x7!r1@ zb$tD|2tiGrLt04>BC>o0ec1f3x9!ko#!_gmr+olyIWFJI$rve4YxNg1b+L0m8nNi| z2X)>~;L}9G$h`WC6HY${_c~oT^Bkt^WOd8bxNe43>78E5$hNtsmH};{&xN+^7kO98?)Nx7 zzlO*wUPC&N{>>Y|I9=yX*RpOCW1(<~y3G^RdK^woGy#WSl@;ZX{>=8@ETn=dd2MT# zs95Q-U!?DUjz}9uv=+*qvQOq+E0w5_-Pp6sZjYp>Ja1)tzJKyN8Nyms2W3YkRu&{x z+9Xx3B~@ApTD9r7`WHa6a-muG^;>mJ(ROi#qBGvZ=F4F6TVcp>*W#Ql8fg+JDeDoErBhzkV>(eP5j2sV5&L(3AevMidGzdjyzzaeLyFP@CxG z1Y*^I6Vmwua%2;AvwDk$mC%pdR}CJeRES&rZ1rS_BlJGWoARu46HCZ{ z)aKvvjrWjepGvn}SGwynGDk*z5l;pyo;v0AHYlF@?t|j(Th$0a+YsOqbo}r0DLn0k zE3Iqr;}RJ76i6@iT*GJ9{RKBb8SXhM4M;B&SM+PwoB#fRz4IFdnBIsc+&(x6M)8rV zoy(eAIVj)6nvW*fSnoZdlHx`@jpChue&)Xpon}uU#CLib6ve`Rs_N0ZK2V}pYbRphgORx%H}T=gP{ft5(Fx7V$fLeBsBE;85OZM^^__OZC|QAx9?lO#rPIN&LCqAWnVO@-^&Mif~Iu~m#jxrAV}4Jf09XO zd}GOF0%Ro^$E*&_9rW0azi4IA$c5~bffn2rCcmRs_C*W+0Ys+iwq~-V z+8BRGaaF#i#2A!K;LEeEl`9aEeaBa5uf%oZa>&y~V!tofO3wfDJ^2A!nDEYt>5_V* z{L%E0UHc_F1bOhMh&MB32qV{jd(`Pmy5nDV#J7;+MX?iPu6vR|)+n6Gx^B%61~Y=e zb%bOX0y0dZn6<^-{b3&Y;4^1x(2pjpAQ5PjfYT!g?t|!oA$p+8HiXAjPjsLn?x@k3 z=*;W)+?VdX{*P_j?*DFEdU9#4GvI)iof77%PJZJ0hT`Od)L;gg^&*ge{Nw}WU`7qX zlmvVpPiRj~WDiF)n{Ks_(=zHNBgP95<2HzK-{l>*mFvFf?Gn;7Bl3>%4c+(OMaD7flCQd|_K`8?vk(s%3@}0@#0D<^|mlSAgiDv zFkT`sCJQQc4JuVZOnM_GF>b575rXv>dds^{z+S}lvUkm|_rI2ZS_PKcASNpjldg!# zBSiABZ0{r|VloFYX@!_vLQEEWF7G=vKWy@Hu z%5Jy*QZ338$4$vf$grpZ4YMd1O5lY6QK#*e^&P=}D8=T`Lp3 zl$o>V+#-kliPGcTQlHf@%Ypr&yO0rAhuQiL28pB+v0GDrd4>YwDLr!O27}mAiL%~N znbQ;jzYc@6u~==@W#8}beV%vbH*;t1{p0>|@67$2IcLsi z&b6_lAN#t0FoRaNi?@=jr!ts}m;jpS{xDr(tvrm=rx@U&KiMM&nvesr0c~C|?n;@8 zwkkMJHk>C1?muqJeDytOL&b=egaBegHz+Kv@=)^TlI+U?7Pg^FKL-&WGZQJ*Z}Cq zBe9Tw_pr0c-=f5K+e8>AYTQ8pwC7?DIJdxe>22|u1${t`yA1$;KB7<*M^&w{(Bdr3 z_fkz;#$3A^9l^i%Joo4H64vHUwGo@RsMmYD`kK@om3Duho;TXD>aZ-s~*f4fcLK?I5U(LY^-kqA(t+nT`m%nKbe+@gk z7s=sO<(}g`~R^?K1x7s^{i^Qu(ZDE~F`+W?uX1u6Uh>Ph0}5J~@>(`Em9c ztq_Sk)0})SkQ!T^xDLvshB)*Rda;B*{kHy%i0wx^8sX4Nxa>lI#UsrpUR-@;p}pX!hly~zJp&U+aJvk71s%LWV5qg5 z^T5XS(C};X*b{)NiJ$)L(UZrfv%l`fPM}uD(1I(EI)rc=2}CRpQ(BB;f2L9>m4xST zt`koc$VBqW`Y!+VNk!TK1$(jrSB5sO`ho7CfbWE;+P^|Vo@1^-798|{Pq?OvS!qHI zhgO2F0|tr_^6!X_4WOUAna}ODIcy~!@K*dOb9ZoXL)*ZThv5t?qRZVx&Rxg6Qks_f zy6*4@6!MrhKSjipNjXEoz?JhNxGQt>>q%J5(O1-t2U*7leihg1 zcN{Q$S@oJSFM(60eF~3eN6$|yIWwV<RV+&nRnS(~dDOWJc#x@;<* zh{`i$X&V6zEr}rnaemID(}OH{!>MCOSL0vp9l7gUGx7_}NqzT!TViu;Z7pRofL zq>|$vf?UdHac9RMUfa*SRyoP*Tjk0m?4Bg#xm?970F?2ZnZ86XMe^Da(q!?lk2l=? zA>YM%lYh#TnfuMpX#4fgOJ$jKFeVrhSbDI0hn=--7@QAi(^s3`fR*E(xyM zS$~)(R(9#angrDFPL0rPwdHr~uhUx!HH_0Bw6XzqaX%e@QWyd$v_0~O%Zg!5!S}0v zn%Mm`Wd?W-43HTS$j~^a1ck?)S?lpH)i|a6E z9my9&pZt{GAIr*6I+^mBmK}tu8QbppfOlo|&iMjPZ<8MsKzoZiNpd`Nk*O-<>Dyj* z+>u=kae%zE;lC`m7<0nr0bBmhZ?VLE4K+=apNF}k^wPs-otA|KbcAr2A2>Vio&e;0 zuiS%w;XsNf-jc!5_SQhxD|fz7ra~BtYf~}*GL4@QXkS@C0ISKxzYTNvk~N2W;0NCL zzRP1VEP1GNsQioJ3e9TngL!sG^|l1e?0F}eKfl6hw(-(QaITvG-u1_f(sX$fbY`MZ zgt>30CF5^9yGB`KD?~UaIU590?Yx@pr2N@`jgx~2wf4uD*WG>pz&rbsVaxQSCAiFo z{rS_s^$b`On;u><>Qrdw{?ng9GZGL3-RyvM-2&piq(s1FH^(RQP#_3$O4xx#j92nEcpktS<|^t;n2`H z7w!4pr)Fit`zyhcPY(0?+mm$P0}SBV-P4oMkqS$X$nW&cdZ+(9qrSyN%i|g#0@AY7 zC|I>bDOTM1RTOw;jq)ub?`M(e3hokrRQ=WSb6Kv}w&^QY1qML@JTLv5zR9ffp;iYr z1n2>RFA$^0Yj#L^Ocd)pCJAGVZmw^TCM3Qb?+iV@v?p1A1mU%&)1ymyTgu}hjH#^f zX_&1w>pzwf^UQ*s1|@b3Kj@%%Vzeet(aOx5z%GaW%qtC)>ZBq!-Zp%sL(=nq#J%_O z@9;xnneIc%ZnL!)pr=Vs@>eW~zsU)yQ*J$bG7`bgi8hyY$&PG~8xD+iA=68@r_>8~ zBD6TA)k86Pi8s!s$kv8r%5~gRw_SO4MCxXyt#6Do*2BELsivOxWEAwdZIUvHy-DTw zHm#sYLO~8uJ$Ip%xvK-G0%bhelXokwJT3`#DDAjd^@{$v}wVx%TQm;m{uX_yW#X4Po(3*BfEJczB z;KW$xNo~AH!b$&k*DOED3Q0vNWXn|3;kydSXtZX539>~804kWv9Kt8G=*XDk#7MzJ z%{1Hkl2Yvv_8NgBFii0&QtwJLcFCsOGt|UZLS@ZJ@RH8rs%7s3k2;Ihq1B&5UK{7g zH=i+gw6N2WH6R^acthfUGxV9~R|9mRvlw8WdoyzLDlZD~yRRILcev$(bV44l;Bu3X zs-cvZ06{>$zcP7SoemqDQvbCYoXR$Q%IxOdP5Wz_*f9i;QzCQN| z+S+>o5{4cum{w$Ji}mLR1oxEWjZ-d*jD>|f8YAsr7wpG2+$cB zH`?~%3FoDg3>pbs@%uuDXMV}@IBw#eN~++eI4+Yz#a{Ej33>N9DneJoBDpId0l$oc z9UFZRJ>)bEayRDaBlK*0UZ7VwsMIL91L6Rs{o+p2DSGr*xiWR9oi{5Qc0mo)SSPr5 zKB7#lKd*i$UYMagf3FOfeld0J{KJR%S&OVP+YrDQf3#n`>bNC%HFxt;1p{lO zEhKy<&f*|0C+hX2=G4rzM0!f1K$^ZytUqh8l4nsO$cH7kNsIjW>F)OCvT8Z*yEosBe9J@uY(>o3GC6ZpVD1c>7`FM)Dw7S1sJ%vzJKD`3CSh5 z3N*gao~0fPe~s&Vwqe@)cRmv68JEJ{0aHhwnr+E-U~J18i`R)#F$Zsc#V#V25eoq6 z<@W&<*k;=G!-3%X%{fim=QC)#!0=`*Hy-qr@kC`x`->_r0f9Ya;){EEGuHBeK(&gV|9xG9; z!;!fv+Uwa;+q#TuOi*}d@elFjV{ruAGK-);2l;O%&e&Urv|9(8n^@N{pa^xpU8VjY zTt~OoOk^pAQ|FOQEof=6&1t1MtJmXT4=1LAs7_?IFGiUyN)rQ{r_xn?+ z*l05%f3^j8DG0u;^~K<7rTOrg_oVyYJ(;n$++c^}<4sd+XCTV>b!tHbsQ-<@nXt`_ zK3+@%wWJD6YK&z)^_rNwq&O4dt$d$`TA3TDYTa?@6_4!b&#kQ9ap1jXY%v3rRvw?c z*md}OZh7q^W#nVl#_k)I|A#N*C>^INf z?kZ(v=!21F|MM-D!RY@bO_D4eiX3!rUdj>Z<#hYgRHmzGs72OPIMm1gu;--vD)&07 zo!a}mbZwdm>LI@#B^CX@JHjI_7v$sjCtNP9RARm5`pzT!W3xzXKRQ?(As#2axh7G(_UetWJ^QxBX4pA_>1o^8i3AK?my{mw^ZBbU za>(f{UVTthSM$id)PDWj$w@8c3AZAsV;EwaZVp9F-EK|ccxe6S1be=+6zevf2f0^u(wdC$TvOsNK;#$fs36k*sGPH$7z|6-h zrzHexn#|9cZ`XMs0RT>4i>OA^iYRV~aQ_L3)Q#e#My%C8vwoNo(_I(ymt(UNS!rBg z15bkHQS1?#=?MJd(-Bk!hqy>K^lNT*UTo>0A` zu2C8hrebk>ejStf6e^`L^arAT%+0@2TVmLO%M64Us)tuK6jlm?6!T0 zMmJiXA&7UOZXqCpo7^$3jK7NZ+WpZ!3GkJcW>+0_Ty%837JyJ3L}z*NZQ!u}N2~ST z_v)uXT^AJ&bM;tkn>$(wHU>N_%~mL{#iMVXerkroleefLHa^#1uaof-f7NbVe1e0C z{8ac-Rtc?$MX-8AN7N=y)!vJ&)&V&Y%9RK*mAwHbIHt4%>cl>Y!5{hz`G{pZ?dl^{ zEl#f*l3s9_r4p{3a$m->_Egzlg%a(U&}-k7TrK$68n@pKiF;3A)KRyZDZOnr`4#`p z%2iScu6*@OpV81lISzI9e{PJ8?Rl06pix!O1 z9MaN1hs2c-uzO5*xLb$oT}=AL0wNN8dxqLBI^McpLmn6D@cG%?f6jl%LJcPzeNJqx z@gq9RqvV7gLU_Q}lcyEy<8>CTwUmE6mden6ezt(tkEYBGx={6mhN5g|m5;s-jB>j_ z4xf597}+J7Cxi9p;V#{c(Ow&PX5wXr8$ue@t)sbGm66H ze&-gweK>8yCOs?(Nre7!=3R01K33c)h_xXSs=!&JWk^QLlx`a+`JnG5Y{L2}^~F{D zbXaxm(;9Zq!hS%b4eU8Z3WGEv_>4%#2J}1SOQ~AyFYxUyf1fc4b6|$EjqbUDleurb zQuuIDe&tUwN~C$Zm<}~@K&;?IU@4Sn5N?+8Q)73DB^wV+c)W6R+_ueqD08GX5VOWE zO@M6Y;fMzmVH$h3pKlQFA8}TIOxc{5 zBoAE6pGXGPf2j}~d`SFC`xd!UEj{XG(<(_mPF?b~So&<$68sS?A9G9GtZ*PubV;1K zkQt1vvPr2|cRR|qK0g?_0iAA-ia)$}`AN!Qq&K}N(0{Jum%-espznvM-;PQ`TR#)7 zMLDx>Hd1NeWXDmZ80sfuL0$_5v^WNlDqR6ybsUc1fAS*17WN0-z*T7r>(1VoC#S=sQOe|E7QPbbcTiQFCpQoMJEg&0NdH^4hjZX&! zZfGPk7zRqd{Zo|uPf7(Cj_ohhOrn9L5J^Ue5Ba7e?G}|@Yc@(0ay1ShqKe$-AbXz_W@mvz`t<*6`n9Wk9zQi>3d>GSwGkF(ZYV? zZsNRz=(Q??Z$ZNs`fHOLrVDeZMg|#;Xf5G1IKRx9al5s;^T0LJEYp6=(Ya>&iw}9| zpR@h~@$#R0x(}TOo+%U%#~RG}@B3w?$7kxEfB4d}Blt9Ah-G^#!a7VQyF@}4-oC7U zekp*x)(EFh0lX5CB3@bvQH)wgYALOSo{mXMUuTr5;l7dHHHA?4ud2~jO5QDCmSpuF zC!+K2AJ-=PpGkl=(b@|aH?rW98{g7g82W~BrBnaD2{CvF+VPAenxI*)ke(AIqM@l; ze|cCB)x&}|;ji11WOGhX4qI?UC<@N1Ux+P4XzF2QG&{nHuAGB6ALd~0Wx(mXGC-ie zPxWTde?A_Emcw7KR?4ipt?{lZpF^*2*^53ZpT|z3p|SV}3=4RC6#iw{Dq!l6Yfe{| z32d*?w=%vP(44d2rY(i>FO`km#g5nce?65xfv;PplnNKnWSphqHkV*CzrbUQFf#Y>~^()=}`&%&-!ss+sO7L;}q+IS_E@D9AHQx~ELFkDyhe{#zP z%MgA0;yam9IawCVXm4JvL>lVZ7`%%0qG|t!Ldu%XnK}F7;3cbE3ufIndv$)i%bThj zpa*AroaUi*i%kEP=EQ5I+o;D85U;kOt4fPYT<#$EdO5uZTaCoXR$OCspzZh3?t#AX z`s$Bq%1=K&f6r7?z!a)sVg9B;fBilyIhlfaN&=>JULv5EMl!#bX!~QJb_@|`-IlN0 z`29^n$1Z1K{u_1FDtJ!~Ai2hSfLs+}JM4De>`@aKUfh(9b(@?M7BnH$VTs@b& zXlQiATqe`yZFNaum)OJEWcsOk*bU51Tz{~jl2976bC-I?cd4|oLUgQ}e*i6{ysdkc#+if70=h+kF$@jIJAGdZ=$Ly0J7F;m{qkOlcPknbl5akkMge zA#M#R>K_qyO4x*(iAYez90Ov6ZA9kH$6}$zDGXgX-3J8QGf`LkgQLSEyMjDo0@J~)?M&cM`w0EfmBvQ)#1*#uMs5-(z z(p;Z^MKC=je{D!{@T?G#;V(%aeM98l9-Udkt|h1LEHJL;B34`B0t)MDHeXu~>j#ds zUt3bNvStaJdA*gkA-xiwIDu|`>YTWLMWGrke@U95KOwIBb4LIhXxsSI{aYJf z+z+bQPdO3tF6r3~>W*G6L4rT4xt_}UVRrl^g8WkzsY$FXLnNZ^mf6NAbALB``>`{H zI@-gpmjOE*>_up<#$(@FQ7JlOtTJ+>4Z$~Och8=^++(@u z{__>`?@GHVhPBcvvrV?!=fUE?TsAM=VwW(M#>WWT2C4O4^?q6BqlX6*N;(ETU318a zX7X*B=hM#V2H($!ylLi`j$W&7eq#9PxB6;Kf8bGfnJA`KLgR}dA6;4W_$NFd%gD`l(w_iv51~uO6^>8; z`tDOhaPWwe^qAsNyN1<%Ux2rs$}rLJ+9Se)>>fuIy7TnEGcQiYS`^CB`g)j_2blt` ze-)&x3|9507sE5&Tdgzqs`Xp!kH?A8DW$A@f)|^D&76kHK{DZQ+ zeI{RQTUqJZtnS@&X+(=!#wz5Q*F&-^IWd#Z&3aVr|5X@8*~A@+qwHV@wV69(e`rJ2 zwxA-_KK3)CIE4O^!;6nWoMb|LX*o||&2-V|nCPwg3yklabck83!JDiC=J+a^e{<~H z6O)TCzwuRM&tyMMe#GUlW_42rEm1xzSWau_M?YX`;LpbB3p1x;O&L6dJ+Vk_2BWun zPg7E6d}IzRA(46>44YXpm(ttYe-2P@!zb5A%sQ91ncj%q+2dj16I6(sEXhrZTIDt% z-+abymKLKpWb~%64VEDS;O-kawUh^Bx85~GIH;bH86`oy)Ak^hL81~G9W{#f3{n*cnt09V(x|? zQBQ}i=y{Y*1vh*xqf%gaRTbgGqW5e&hvMPL4~BWU;d*X!7e8s}cB0ADp&{~io}n^H zKL|AJ`r1(b(ZNRcLG!uren!>J*T-3hFuSgz;ly!>0+R^Uq3XH_^^0)*i6gbgSuGJ` zwi1E(f_{oR46P}3f5rjk;^QLXiz#OmJ3P|3!ll3BVJP&SGG;!lc(6DTMJX+}{)=F90d95_EbdrW&ZTPWE=bZU zG-7YjLZ;!Wpw7Z*KAv!ZGvoeeUQESvsV_F7*lIVa^a1|&;!sBMFJs37o5wAL$jiVS z1I`c`&Tchcf4;AYW?$v$_4>YaKiumo`TL5Th)PSo`oUm&D~76xjh?3~?3&q`Cu&hJ zb;-fSOXg3ftLB@VTO-hr5rynq&wm;3b>dj?dy~gC{X)(w(3177gV5=31^sN+&(-0Y zN?;SbyH@FGjPxs$qgIPyC*E z$^!rOK061x_rpy#;`tSFCw(TTNIQL=+P@`K>?sRP3A??t_IVtO8`PZ{+?F9B4H#`o zg0gHzU37G@TWcrU4=gxW%I^I#a>#VrG%z#DL8}FRO-OlOKC0PRc)MAf9|ni7J23b} zf9m*Ve}%I$yP1C#06t7I!5EL+n2-bd*2=9;&&Mk^Cq0ba)D`#4MmsC5k)>ZaRXU(h zLBL98r4b3q27*Gp8hSUh4m3Y%6Yl{TY0t5tP8%ec)|oz+#Vo(w=G;0x(?~2+-y0f& zxnlc^QJ{HxAz9$<#2DM^yE`7=?Vd*tUp$?Te-6)5^RghGo}u*NrFL;KJluqbhaV0a z$6B?nZb@5HUA3)zOP~9EF)g4g)HA+^`dcp-I=@i_SOIRh*o z2rO`84Kuk5%=K~qc-z4h3Yo*8uq%yZ9ZRV`^|0K(15C8NSa0=3pRDaQ`G+hvNVM;T zg|E5yLrx%Wnmq&m{(CXf9sk~LL>)5iEdHD9p?w<^+-IvrKQ7Osj&w& z`ajtp`}!Jy|Io1DwBEfl;`@%@{pW(%q&hn%SXa%juFtK`lMGJ6?8oLkg5q_(y~|c# z;&#SXxL*rqr>tBEpHsUpyTVK&u=AE+In_wD*J+|o3omB*gUI%h&pId&0udDVe|+j7 ze=3jcBJnAg_=Jo;gQTCDSCOuUtFf>`ojuge_3y~LfC3E1USaFjov};=N){ZBLIifK zNcSBQrmb)~naJIVclgK@N-ZVVI>YP6fKHj+rnRzn&3SO0D_>D(*j<)PB&tyw@?m=_ z{t9QbeOkG&bt?0hA9C#ZTN&~je@ah!E~CBAr+#&$%=GRx)~HTDlxxR1MM!OLr6{`X z&f807o77zwO8>s*4O|XP=ZZ)a%1CZco2ES1qxF72YWlVxYdhfw*6ku3y6rWkj2dhG zh8Z?KnGl*fwU{(|uu&pYiu~TK1%5bkBxJuak-(UKzayXf`6g?LQ{zLCYT~3Y}e#->AXi zUzoa3a+rhw;jz0qUhC?4aw{3f;G~*MV9)~wIVJhHfgtk$T<;c=-}PC+zlD(A(}@qJ zpMbZd|4!d*%5f6;m}YhBe|`1*YA02;?8KZDksqzc{J6{DHbH%1)IWeN2Dy`*zslm4 z*mvy9UHQiKzMnL4Tomp37HuqdEIVF?Z2x%yc4c~l(`x5-JlY`oDGl=mWP<#CK~Cfw zZ9ijo)?9-vS1Y#OAjJ>YIt^>a6D~na&F?;}HjCXh8SLXq7AR{tf1w0);93&bTiTZS z{7gS8=KR-uWrJd~ElpM1U%KV?=x3|ugNZlwU+l37tuwz0mWZzU5X8r#Oa1&R=Inrg zq1_Db|4a7H2)J0g=JRizXkmxDY7YGNt9QX~tJ?~wSZ~%~W$FLtj!-CG2EB73oRK#T zXY1MF)okd<(ppF-e~gm~$8K|>(G*=*sii~14lM5D&7l|ai)8j$8>fc2zTsQRdU6c* z;pS*%0B)(km-MVh*JTP=AWpthie@oYY-&LW0DWRuS6_R`) z42|Wz1d_=D`nA3#KLlS~&4$!=Y?aYRY8Ic}x<{Qx6QI&U+(x6OK1lx&=W74E0y-+V z@tBsV*|UBRc)UV~cN{eZ*PObKgdzx5uRkoNCAWvJt)R*ySxxli$d6SeuR64bjlj<- z#i#*JMn|F|e^P81osf=S8*Y$O>T}=1;Ebn=q#>k0a;fc7*QdXh$hT2!J2ywTHp7Os zc3_8*PwN#w3SE3v$F;?MRnd1yfM{Q9J)Zf$6JEAMau?|5!gZ%Eb+r|A^Knv3%x^4l ziU}CUVp|y)fztk>6GOU@Efj(n6rAZQCBCXUkU9$ve_`Kb^ZDx`aS}SYj$W$W3~luh zrj#D?pA*vsd0JJ2)oa1Sj%HiUXwFc)sB;R(=mAoyc8$qiJk%y52xTK_@dgJ<>+mM~ zAKGRHc&_-=48@Z3f%bE}=RMaiER2F!QD+)^MWWV<9Li`1$3_LYoMO&^PuuKfJ%1(bW~{CvA$$HdnFzew1I5&latxKW zfP>9o3z=V_WZ24V(c0HXnY~B1Ilf}!m+|T^f9O-@DUp1}G<*>kBv``W)}~K4F)kWP z&8n`+i`~{)E}JzQu<7?N&$xX*q%|48o>Q}Sd|;VIefTA2s<**)G2ax?PySmGA;g)& z`DtT9Db|zDPE@6o(=(8H>5ofMVl|M<>-LYukx}xWkX?>TOz0(I>T>QKC|mXfV8$1m zf0dkk_-|AC>wlt7m_s0ckfi_Ld707DY66=0SB*&(215&O-*k*0JxHqq?X|8l zqo#|iA$H-7!6VKDa|H$Z1T>LU%5b(Q@4_2186~)`2E}*;3X~U%dy*7?f zbt<>-gHl1E;|+auER2S+-^vf6SUz>jAkAX$i<_&GkC=1 zFQ2sPz{oOwQ8X;kHs+->o5N}ge^gj~`x3X{huJ#$b+z+QvFAcwQTLU!MBSN@^4USV z-oUvI)IWs~x{tMrDfyx@^W2q=YHxeEd6ZAtAZ+3!kme;VuBpA<$#F%frmC12M&SLvOdnU(J$Pf!_<|8;wXYOA*rq{-!WX$@ z&UAe$3%xo;xXTpF+<3n$8>GK5!Aw-mTox-XkB5N{?|LY$Bmf7JvXH{}~f=o|xCZxghhif9AB%L!{Ne;szy0 zn>)s2Tddz&eC%uCr`;5zR;5+9euKR3?P2g06Y&*e$66m!o!Tk$69H(0_a(A3m)>q7 z5>3t?-zZx0qzk+Me9zvRsB^oK3vFJ$v&p)NQ$5|LP}BQzLOzbe;oroLUBnihUOw3! zmpJ7WzxIprq(qgJe=^FBlcRqHy0sc&S@Mq2**6Ouz%5_k|LXwO(t55;V|FU=wD?`} zm*PVAT&597ufy{vF)9Qh;{h~84+`s|U)r`w{>thND9GlaWQe{^*e+2wEHu$Vym3`w#M zt+t(;*L6?o*naekKh8xEvP;mTlciJv@vpdcc1y-&lR6=h$FT~~Q23A>9gdC6Y%(g6 z&b?+-HX6)sefMw?H*t)M-3~k)r6Bo;N5jnlj{LZkpDX^<%@JmU2f`8ud@y>;Q%?bN z=Hp}e90CeXe}oHZp+GR;>7}z`U4|pc4Y@PX*zHlPvN3NJJUHjawvG~0{;_7dq0ClU zM`Y?joDMpnt^&f4iGE{OyVpWqUzN0#>M*m2+_UhlHRjb4c{2Z7Yk^(WxkBD~Optp2 zZ!myu<0cPd;okOa!cwS}Aq2dZFrYUbzS>#vU3r=Ge*pW^8g%i_Ta|GM(I5>@7JAvR z!&5Wj-c+SB;}*UJP~+kEf8p!TeHs`i#8{32isv!L{F9Ds?Uk8$Riz%0VfOBQf~KL_ z6a_N<*)?RLfDX`{;h)^5Y4Mg(XrW;HUtg*~lci=rnt~uHfX|tFVZwK4gzQi|JnT8S z;g`2hf67%Fp;5ILmSf@zi9?{ddQBc~aTa^=1kLGbl?yPocZ+jWK2|m`gc(eVbiec} zI*;&i?%m8k=Ap5CyBszGQZ)VRVWoyU)z)qZV_JE*g7B4!nJALwFzJ z+SOEYKJ}=M(`ESga>O~FKA>?$SCY}Y&GhHze-YD_%a2I{Oob$|uIxm!DaV29ceNLT zWEz0?ATjIJ+W+p#_L!#1#LVmD2e7@R!5AibOzc(%<{;;DI6% z?_R3uWN+gaMunT4SL(Pn=J5T~8weHy@xj5{Ry`6!#jRlQjf+5~Lem7gy5@9F3iTmL zALdo>%~;e{aSOOZwd+bFz3^Y7IMY+}Z!tc!M^BA);#d*&#jK(MBedm~kHtPPfB2s_ zd4?~u{&`PGP^Ypc{L%Z-U`9rbXmhA>==a#{hC&XM^w)Z)ur-IjU0x*IgiE3)9;&3% zIaw4gYxjIA{Vcq0!PuA$NmGo02~kU4dlmk;uu80>!>S$W)7F@v3>PO|uJF zv@Z3j->`Rf_!X~sZA#O__w2@Vk->yh`EU1j0vv91X9+u!OaXSfv;#S(B{Fe(sHW2O zWsUxY?e0~&`Q(lFk#D#$?(GHd+~U2WiwDILw_s=y2;Ib2>nEdM-xPi2f0d!Qy~faF z%rTCkt(bHxo3nU6iFy3R8CN?0>cg!}M{nFH$sz#uxSz`gmy8*hJzNU-h+obqq`@iZ zcg6+v{*;r+-v4Wa(E>1u&|GYrQFD~|J=yU4{ziMttd+VU_>to4S`O~;>4H+L_zy*k zUbY!4A8XHl^e+`iXA=eWe-ebpc7?;oV>{#3Ib$+D$1qjH+-K35E2;a=Y9F83Z32Zs zPza*-7Pmcm@1D(q^!;8DzO4ZF$O|2l6J2*qjknS{cx49^2)vcU`M#|W}OjM5vk>bTVeg=D_`%Ah>eF3-!@k9eTqoMD#lML`#A%jx71VNhn) z$y4e=&5mO@f1{_di~?CenZUVHq(`gt@!LwgVE8wepsP8oa!e!C7tK*Fq1@T!x#7vO z?6T(rOvz&Tdo!B>dA8m~Zw$~w4pQT{^G67m0^a#y!=AqBfV~c){KxS?t$!NkLl}uJ ziZHw>E(P>~K)Tik$}f4wSkh6mYo-&#xrYL@x+L1sJM zeD@^#Vu5E&#TPysKA^9_o7`>sdplE~U*VNOtdPH2sVs&npFEkZqc8>Q0{rrrboWme zf=UxPc+!J4cBsC`(TCcz}aoK0$#$$iY z(j$&+e}}oF&T=E!9m1> z=VE$}s!MnG0+APwc2;8r9I|T0!W&7M`3t{2QM!RMD6hIG_6#qEdKqWhQrRfAsr`Q7 zGS(zvpUFCW*htpeTy_#%`|IOyV~7c1ZQ||4e;{qop%gYiBrtT?caPvc%WZbV$1LAw z$0NSN6WY?Mu2O=PRQoUQ2JG|)*SPaf_Y(%d{SW9#hwdBY@rfR1=v)1fF#BVo{uuE^ z0%6kMm%_}Yy$i`5)CDv<9~oodJ(f(!=GqFR?SkuYCp0;xQjVzye=Uz5<7zCg$Htb| ze^2&AXGk@4SzZ_t?ue(xtxkKJBWpnKY;Mi>l<}e0euVu-EFacpiYZ8IWj&{@y?di^ zaTr&iJ(-!=HTGf=Nr<_vw`=IxWVV?k zFv;%IQs)|iA3E%=OZOGm#;F`ilT|+^G?o=+_xYJT*>8Apqx0l!5>ll;aT~oaO_)a*ool-M7*@%?YoB*#No})m8Yh(EGbP zQcS4malBh)=)nM|IOu|x02Ln8bKSCaljR^ELbWGW*8dxA@0RD7gfddxx$#m6n|mqg zMX$u{xGO#P$^`OVp%7dp3{xJ#e;WIay%K*CRtVP?(e`8W-J>F`?q6}OHs#70W-uR? zuYZ&`ztwWfw-c|k6HmWdd%VQ$1!mtJy&i8ykmQL(X;aye+G7Pgg%5`6|e$uJl>#DRB!fqcick0|9KAE@iVm!i-!%| zs825%D6w>sF1`)^*N-y{Eu=tC;I!eWh&0rjI+nWK0LwxpDXPz7tx6Nduamp{Z5+6( zZPP$09INW~t4kwjryWD)6=IV;(@#rbm%{29C>TxFDHR+j0)Igzf9~;MN7ysqW+!l0 zh-V#Ma;(4025%tmK`1x{be4;Zz5UCK;>dCfJ*^T>J4vEb#J!XLMQo;z&W6`vEryR)mBWoG)ye+7ZcKU?nmEN|MI!1oSW zz^-`Dv`lc*qRSm+%G~hJ^qE`9)X+Baz-6;7@71akL$vVu#l+2xuM+|RJ7@8g^2&}r zz{}hsruxspkUPZ8^s#6pZu$t#O?&8(inON}uH`DgvOAq2JWhO7Mrw6mDW%)0Pu&Qs z0%jYp5tF~ef8uT5%YJlZx23=|Aqr=3>p-yui11kJ)u;HnHluGcBT1K^IL%y>AMHf@ z7}#|^>c*GnZJIqE3FSU<;rxJacsv?v66eWZ1Qb2+^JG@h&s@%beupuMCc>NF)i4OSJ7~_YTGhQ$!gKrO=XP0yQ1I z*HTAI0of=6{k{Ps({bd9n$vz-n5s!J!(+~ve=kK04^@6y8Gl<);Xu`Jpnle6XcS?7 zJMB^CscF~?hkI1K-p53KfS`qb@~iz6_oaQ`q`ue`%P3kOcVMx3uM6<|2{b$SD!(q;# zf3xFX{uH`M>Mb)-yBFfe&$bSZW3vB*!q!<0{*r^<3q`bFb_dv%o(@H#xzyk&4(SxG z-BbzYfQAaig#+2=6ohj=(seJuxUC%7!@sG0fn5EDx6RUy(3Gv?RN1^Us=Kd2vS8{v zoRB1#{DTDen$OEubE(j({WNN^@6|>Vf5gJ&hFu(@2ap_apJrtKZc(Ib&x*Cl_sy#* zo{hKFQHF)RcsBj2rYO+FzSha$mUQ7^*!eiwyf!-7t5i?_H#skr3X{V0OG%C*MZ)H+ z{KbKsta4$R*#$O*1GcF*hX2wxjgQjanQ7htk0p>byUqNZx((`wY?i$6?U$Fqf4422 z93i{BM~1yKCTx;CpqmFhSG01tZ4S^!^%A&T5H6DKiuKI9Q|sZ>?d?kjtXN@V7*cME ziP`+2j4&#=r?P&%XysV>sO#7>&8Pfo(4FGu&A33@optN5YtxR=2{DXsRMrHyO)$!} z6k0(nDVkq_U;Ri|$7XcInjIcVfBg1gvWIkT>)(U}W{!~XejL>nqOr3G{Jva|HOSHxkY+Ra)BEGTGqJKWmaPhi+#tijXPglmk-4EWFPGGe z)6?wZi^ClsEa*TEKKOLr{4FBuFcb=}vdp#b%$uffxxN3Y687Gu=GDWSTOClu5`|gv zri;WEow&n}bj4M$OfTTie@$#mlWlF6t$FBFh0y@2S1OOSnb2ksP5)>V1=srZdtR9< z4P>DMUwkXq!U7}1dtMIfLAHusy*11x|NO9}T>;23ul2zDh#xXHd5J_VZ~o?iapF7Z zg%K2-?=!MKH})*EPQCHy@s&|BHB8WtNz!LzG|Odf}d z`MG;@*-^NIHM{B^k19@m0{4HYdh4htyr^qfMOsR_QChk|Vn7rG1f-=)K)SnIx=Ttr zq`QY6q`P70p@$lVm|;GD@B2L8`o6X9-*>IM?mg%3v-aNSglZ1qhC!=q*>$v+(wc>C zr*Oj!CTsaz=oDP&f0XNuZM{ym9uWE>IcaeW_`6pl4aMYTbL-i83mPfARuyFtyMll3 z-%J{l_a6F*ZS*Lm$t5&2*EA*WnxJk40#H#q@Q%TRx$JUG%*@qk%~iyFu!3ipGnvPX z*@YN(KBkMf4+ChSef`FJZ*Y#Ytv$7k^Be-#4HT0NFn$gQf0#T*(A7QRjFfJ=kR1!@ zu0fvVc#7uiW!kO=I)T;l1hC&7q#6{M zw$GJn*%ZRbG}=B+-YWudZJKgj_tkA&Y-%Z1pklIpzG3YR#8*9ZlV0 z8ky`u*URoR_L&+%@83E_yhJ&@5?Kn(mVMuZywG|HfBq9}-V;pHV=7HYe8V)qfiKj? zg@rz4_1+QUj9drK2vIAN+H;P$T(;CV2Kt`uA$h)brMuHZFoRgeB3#RCEQMK zy9MeUAj9)xI;|)kX|EpHZgS+!$OQf8JMFvw)VJ+6`nZ5Le9E%6L`$>WR^iDRD#l&3 z#SF~Ie|#-a`aWICf|tr`e6g(e%Z}PB$;hlQk;R@*FuVhOgSQT=#VmYR@pWfYnY8UM z#WBowb?);P)%UuJMz-AwOW6F8W3NF9?5w9_%q`c9B1$o^n|qZxEGf80 zhHLLl#QUFbi5Grb$-<`JAv8#sV*R498iM}d`HN|XqsYb?HuiQHT^y2#xVFwCX`q-T6a ze;eq}e{aIZjx2WcxmN3F8n$I#UcZQOgX^q%^Dc*q{N(kgyF$MA>baI4o=f<>$iP`` zE3!-DjRf1OkKD%X1{&s=5+n^^d@A6e`yXqB{hb*NYIfCFA7X2Dp^zM96IHxadZD| zCUVZna<9JK(6_6r!N|XxY|6+q!PPSB^pA#Fp&n6vs>&QGH;J$cgbgS$!8j! zSVG&mV?cIB4b#mDuX37buD$Ic*!J4#5w8EZdZ!=by}U>zF|FUU;EzC>jT4Boe?P2i z+_Yy@O}(Ru_Nxe1B-Sq;`g!Z^za!z|_9;G(Q=U$Y0kSgwL6?KJH?j-s0dDt*ho9AWaZYZY$!~*Dd&Hj+U=9l9kuH2?#D24j`BG3=Gd0Y>vRn>ap zbXMCyk?#XzuMbLkJ2<=YUlM?_e?OLiWOW->Q(&9SVDog?8$NGJ@+Pb1)jrZo)@s$z z3u^yCU|ytTF|a?a{F>8-BiX1NkncZ=`D)hYbn1ISIa0t`+#^!7wc_@3o>dx(F^$BdTBkz$@|X|J$i zUeVnnCG{Tq=zTAApo>Wue^h7KY+5aL@xoh}Vv~0&ZOLdC(Jm@ZygyZPzl#u?2xR`G z!mg_ldWxCErJ!SAx}r>nghFO6MT_&$if{n=WuG=KXcFt)2#%jeU#--?1RAs=y7K*6 zpj`#}WbaI`cX(~q0C^*glklf=qeMVpy&qP!oW~DwwMWocIdY=Le_#Ux*?kE# zTf*H&MPHzx{V4Ga2r7Rja19lR_WvPF=!qGo%h}S@Dgqs$hz=hnldZde`)cCCxj1=xk{bQgl!^8g0pr6gqOG%pd2h`D9xFEPJ4~E;`{ zXy+GRhv1-lZwY<2op3WEa-1P~B}mU?DA_(d;GWF)f5Kw=a+BaLs6|{Tg)$TZSi5&= ztGZ@g0Y5ybjsbqQ-FNp>k!%t~V_uX_A6+v1P=G1;;9~@wdIs7hvZVPAI%VSdLb)sM zgVjJWdOX{%CI%~zR;vY8IQYR<7n+j8v3-5hQ2b?;P+<{?b-alCBT`8J1A-HN*atE{d_VIyVhWQ{W6=?RTcUUsCbkXkpoTWYkyz)ygIZqVCIeQe ze`v>odUfoH{y5AM2Si<+td+0TN<&6lxCr!Kd~-NAYIkY%YwXY+AwRIu%{pO*Zo7c0Nv6|ycwKn*91q*ESt<2e>NW8UkZ z3Ut`~O*Eb6AEc?r);37;Ai+1~SA3Joe+kZ?-g|aN#eedL-gb9|83Q7Yhj~bWI(P}O zjDzkYU>PU8jBQPA8-uY_d~>Gll%e|l+m;S;l?t>mBdYe^py2p3J`VEYK|;F(2bqBpH!iHGiM~1Iek}U^)OXK+eCn-0iCS80Ivuq;m)`J_m}FIQQ!+ zKYzk&$_UbiXxt;M6I^W!=3IN>F2tqzw?=tOd;5(0797Rw7AkTU7b!}c-n5L62o{K3 zQ_j!FKq>v4e6FpUNe;|c4d)j`RX(Aa78>U-KkLZoXJxBmxJO3vxzt#@)O;FSIZ*Lm zdn4TIIwq@H3Tlb~(8dMoV|XvW527!wRex0Em#ndIsmbHUG;2x~=p-CYm@7(n829y- zXcdhlCnLYKlcJxuGCK#Uk;{QY0$v@^^hoyA8z;a zP5s6XTIOonFBk8k=P1l{zTvQ^G9-Ag&bIu?vhaMVqQX)#t)zq-K3fWWN~Li=)_>b-Qv~YkxJkWh{j692)SJ54T=7usXxp4>uYDOX z1cbEbO=j~}Wt*K?hM(7!;aNYUCVC@?q$?tnOH9W4{=QU7F8FKT0KP|ss#7<5Jvl?~ zCCBfW{H3k@lnbkHhm3yS3&RonpYFhSVF9W zB`wm^_3OAMQISMPVbpn{y)(>nar{a_65RSxYTSEECl_3 z2d1JNSV)Kbk^?n*b)&5TC!hg&#Fv7!nloU{zF8W8? z=iB}rz17B8#5scAeIwcwH8=XcCNdYJlO;9)*<{&m&}!*}@NO^NG+%fsTa=WVQZ!C^ z%777Wh5{|8T2H;@2b2K*AFFEzYUn>1Pu*#H&t7uEVOiX&cH@#tgLx^Vjy-O#+i%(h z3=o^NF8+O#lYg}twvsNYcMCo{nRinzdIu=GhYr9S|3{T7|CDq2wC5-zs@s4)id(Uw zy9rp+=%R^igX{c5ONuzcDAieTr2EkS-%E&Gk72XxI@X>y2Ip#A95i`_@A0P!a#qO3 z)j>DI&aITmoKDjeqzjvn4f&xx;^(1`D)cl<@YD>tdw=?QI8>&!CwqryDPOn1@hy(z z=YkIU+?-{*AsB~m@|V>cZP8GwLCzaPGr z`q2YG-+%Cg-iEy zI^^65?9~k^N}5-$QXc~4cb`v^qInva%e658i8iGuqa+{I3~MXL2C0=PAPW?mP3a;P zQ+i#)t4+t)89vEs^wwQwIGZKhT}nSM2Be|eBNdyULyXpI_`)Sh_FEU4-`I61tqS@* z6o0V3KX0i9ZxGt+IE^xQ6$heixQvR{Qh0=R$uieRF=_Qzr1Wi;4>`YmLatXBO-{!g zu#pD>EV@MS=n|t&4x$XfZLRIi`YS7y#MHn9@$vBOspH6n(al8%uG`UdyP6UGbsNikVH|f^vTUh7n%lKJL`!}Hg8=YO%c zI4>XkR1@e9od{f-kQ(cG4OT5n+nX*O-+`N#uW=_zF0N*j1Cd{FM5Z5!VMeNR#@k4G zbuUiy90qV1elwE;4yZIQ0lT$+y=<8|Z?KSZJ#vayr?aRwfZ?^L=wpLyuI#v7Ge-jp zF5TDD&iNOAhhs&;msskGp}Da<_J4G&v6sp(cWtqw0jqSJ0VHF{VIF)-Q6vc179eDS z=)P`0bD5?Mq`j2~hf6*bBP5(RW;UP56J(~p07Q19+NE~4Ur9ahj-pUaZvdoQ15bYR}mF7g@{so__5UVzBc@$3wC~%ouG3vk}S6Av~dkS;pA06hwJWzktO> z(5e2ru?E#@>;q+_qO2vN4MC!IrHj`vJ=8~t4Y<~;*A*Xdic#44sn zSqhRW^M?Al?7z)1W629iQUz&zT#iRto9$7*8{wfu^GM0OrS~OgkF}H%46J(57-No+ zNmB;#+mg0Dy=g=|v)*1lr+!ld){nau0}hFyVYLCSzuogC&GUZ=o`2F@i7f|j6ZqhB zQ~3>j?D30hB7uBSAC_n&J6&RzXnmEZ|5pMVa%L9bZe0-8*|BveIqv!d+Jccezl(o( zy*k?6tCxm5^$~)IWS3aN%RBiiK@esIxcG^C5rTQRa+)b{0ZG0De3hY-qU}wX)tN}1 zh_}U z22`K(v!R|JcjK4lTSRfxQu{GDs$`P*E){LpzfTP zi@KkmFk9^!%`1J#i}CsUse7-`h(E{Y@Bg?pbT=ISBZ#kCEe9HY+XfrG%8bTWrfN-x zFe!JqmD7TBUkKJDwVebNe726NZyzaU_$!nA$E5RUBFON(Py`LbZuyqbKdeVOSn>nC zsl;p2u_~Is^?z&MrNemV>)j?nuAlShZPe9L|8!|(${O^uRc5t~{30vL>_EV=HygU* zE5JyTzYp;nyIuO|!Zb%~I^zCkUv|=k z<=absEq_f&rUt1dNNeZU-5V2CF6Jc;*6qDQ=fzBAd`kBuUEcduyDMx=gIxGB{;ofH zsHbdyCs7<$q;$g*<{C$jApW-Pj;96B+~SN(XL%2VkFDf;{9KuPH4f zLARc(!i0ZUfqzx_u99|4%-tyUIFB4%_?VgJSB6v2c`|u>xre%TD(CrT>V<>cjz!mZ ztQXoQ;y=IUJ@H*Zm9C)jW5#k14!NqLLVwZY--W}#b_bhg9x8b5F#!}kKV#4ipd#Ex zcfMe5TBP^|Jdph_5?Q7QL7;VyenDG1X6%e-6T5k>3~lG+QH0h3=^YcG_T57dhs{0U zH>EmY6y-oG&k=gl?Q&mBQQ8PyK?KJ04{L0i^knJH{0=MQGuWl?7lrH5S0rn@>VJy- zW6mVQJPUf~M#HbPE2@rqGfRKI&$O{VFK%iI-AFH4SvKX;hZuacN<~4Ue1;2QOzt3i z>#o)Wh-sV&^@`8#@1}%b=}~Wx#t!Y=MJLKe0c7{u8$)uu0En3JmyQ4w*>Y$yJYnm( z_uLzA7aIH;*DREF{FPB)69hi01AjtxrrO52wdyPn2M25;IoFho0On6BUU+^PJ`$|i zB!aKfm-<;MS7O_rTru@WoCSXxh22zV6&1gfwP7z9tUKJ>k0A@6}{j z7+O=&b=Aa=|H^f_$*E+T-{uE8u9O0{cE;CB`HMS7#w7GAtVv{!#rhwWuBW$F$LD8X zPF}F>cq-GW{bqa&vq>tu%6}@IJ~J+P4EVx+CP}#r^`Fo%$aB`}zX$pSiYh;y=1<~B z1QL3Pj=e`MI5|EYHvBe4 z7|{XUWzdd-$|6WscRfg%r4UUCr%xlrckCplSwSQTItWB8>rz8!h zMA50uaUD18sZ??NcWuRQORL^p!Dz832`EUIyCZA?q5Fm%V zv+}K(Rn5Jn|Nk-Mel0R@_ofwt68|AnKeaVyslE^O3Ll6olnV#HGLe+*!j>ro^K>WT zD~R#;LI%+*K$~|2cYhsDvNZRMKj*1;hSR789+TqBvQJl4))*{GVCUD9kI4V@+_z`c z=+8JST)*WmEvyiPn6srm#tPg8)+y6zK{^Uh9VGy}Bis9lt=nR-*RAYNcQr3S#Cs~o z{@#i0%6Kmm!JCh_S$?mUT6bU zWm=qF7T;V9eXy`KrX)(Ri2h(O`u`>RXeL9b2@l4R#XId|(P*ucEBC=^S3R;&ITK#; z79Dn&12Aq0PJbeHXB@%6T*-Ua`?-Pk?l zM*?1qi%ycx4Nma>Xq6p{jln3Ky7nvr=9&O0p{oHDS%F<@H?;}+ea$dsCrKlYp3erJ z7pGn#uF+Db{uU5SU;hX+g1jHyCm5=~B*e)^SC=u8Nq@9nLioMTP06vD+MgwjGnr<} zY19a16%F{Kq|ZpA^Yt^@-2KU$YX77+`s`L*+_b9P22}Xf-po9yNM+<#e@{Fq9To7m zZ}VrM-USKz41I;dpC%D^dTgo`0nerBIz(?s3$}BwDy|qSF`s-gO~AhCz^2$rV?oLG zJ_@qVJ%6m)dMa{!Zf|anz4+Um=&K@X4(dVU76qD3Cov79tJUx$r$M)r?`5=;#an{n)uk1#^&Pes?-t2t-*R?N zNbW#TI71vna-~F*XY8UVlfv>aR7&Jx3=D-zQvQH#lfxN(I#)OrC^R_FdVbUV8HwFKQjTp)FIJ0W6D|_FIAy9 zn{FbN+skvX+0a*k%-!@8ZM3-izU3iDPvd?(Cr?gWr~b|pzsl$W6HOq6Lq!(N5P|Xz zV1Gk%M~iL;uqC1LLUx%+GaEo8wa$H3WuG4RCM8_+@gjc6lQo^^x*{G2bLO>H((KoB z9kSRzt8QI{lP8TY^VZ0w&b;z44K(So_H4W+{chauS~(H=mv{7kn95ya`txfNz<(UY+kd}FWO?PWg%${V~+bsjT5*15ChHS${V=6b(#>)YzHF%NZUEF2ArS%RKE?&n+R1G57L zEe@>^uee+CFLB!>kg;z?0a8213-(%?8BxW{fkYnkR``pg7VnY8PoHZMpsiE)x_@2H z3HXveS$?{wmW-lJq!X#a%hr#yd@f-j$taT6Y@hGsOJWiEb~i1?ODHfBBh3*J^XNVU zlzI|w3(4Jlz{76SK}P%ukahB0aBMpkF@RB@dK=ybgszzyoi&3KQ{}<+2i5y^4$~H) zxv6dM(q*yA)42t`V#kEdG6dJNs1=g zAjWb*y9wfRmI6E_nvo zmRSJLu`F{nDrBgUaEcfvImrnF;T~;bZtMY3|F5F^ABrt&TvisT8Yw{cp??r2lN`*_ zQBqjs{`7viCcEbO>ip*o_kpjXO@qs;-_;Y#SvJ@y2u(6JJl9#5t%p^Uu81u3?GZ&ODoOfLv!S zcjgz@I3GRgj$--WXZFMv@=zgHQSHhoBK0a;J5(r*FJyPO;^0pv${$BXU$<<_amMhc!7JrK!W+Z^ezWqaPhtnx$Ewok1xV^@B8(l=%r&N++2gj07UAg54I513>>Ax2297gB73 zDXIew_f1d83mh<427i`-ZGK!9$V&wANu>MA@^9_1_hHzf@WAGOdYvk0i#2U=oW?`9`Yfe`>y({pYS~M2n!8<&CjMqwFbLub?I2{ki z$@j<(j2bU|;pOxTv$V&g_K~;aXtQ}PIFpp<@)vnBw00iV*ofppi1??3EsdQ&e2Ql* z8*}}LIlr;rw11JW&zWm8*heVQ!Lv9R%;P03+FO=p84OQvT?yM*dpJEpcQEeiLT?EG$<%^NdiTnUcw-F88%5-5i=oLG- zJ5B6Up7P_;-+N9!Jx>A!uiu}Vz!+9lq1R=jb1ua0dw)-;!IGXv)6sVM%hxGpPm1F7 zs_Y)PQa|pfGUTH>1Nz0>_3Aao9m}e&8ULNdZ;Cu=rF^ryzDKvcaZ{QFLGh5zm7br$ zW1ChDoA9w4-O)3C{Hk+t^Rdf}wpsMxgF2|Ijx1-1U37^g$M&!2QqrYX3}#NImW@V+ zc|ZYqZGS*p(<|SRf##8X>sv#0Cm!bAfOid>(jG$x;spb9O5etOx5I^^u61!HKcPd+ z_$Sehe-Rk$VZl;gu0A%JtIYs2t57UFS7s+zNVUgzY7dROAtA2YUNmY&Vw1CJZBK&Y zf}eotRe*OhZ=Z9YI9a%(8|fN`D|I~aj-Rlyi+^I`Ov>=9&_dA*^5)A%)TERfROA`! z1Mt}4fxs!sr%q-now4UDDB)c(Lj}e7VJtZpnX! zc={|ivfbGFF&^1TFY}tSirFZq)zwTluSd_*ndcH{DqoI{7=cTZW#9%-Q-(Yq17r<$VS^} zRZh>MwJh-D`1$GSI?0D}wzV+3l!my1Eh-&1#TNZz{H3NsdV!@k2=-c&ggg_Otk$!8 zJheeO=K^r5T?}LdkH^qqL`OOIvgB2d8q8P`n$P=Wfrk0x^wIkCv=*?jyv`-DvVRVW zhgB^6mWmD3?&c)B74}rp%V=+A*_3&)DTxL(;xu|7Y5`U{EneifAMkTu0!Q?&;4aEX zX<;dRPW+dmpR~)i7@mF8YiMZKI_W#EOdG52d3Cd**xPQs^{iXwxM?TtM;wXRH8y$b zylmjj2|VCl`}Huu^y2xM$S8MnYr$J`NLN14;qEAcxgD14M+7iMN4lstG#Iw{)^< zzWQA3^!dV$wO4(}Na)qX<4)^+AHvI4`pGSTw|i3}cHNl0yAr&Ya!NmGzkl&WkCCAK z7ztG&g<61c69uS}M560FX$Fx=n+N-;g%AsUEBuuqq1Ro=FA=7JYij;Wx)WA(moMGa zQSL=>--u0V%*Q=4W*XN{AA|mV0dM56c;Lw6E-ME9H0`Z?@EGJQeq-ALugi|psN-X} z64UV)6ImryVar89B>wA*h<|2!V`vKMOv;-U&I33{MNIAl(B(o=>?AP2H1#(V+sKs( zEqzC0dFO}Y%ctR$wpEzc_0Btp$j0iuC$sIhtEaCL4363cf8q@j1FF z#_g2=?MB=WJIgwe@v_I2tkxRV@|3STM?Ilbw=bx~jfIcR)~>Mv**#>#O9&0y>>C=6wa`8g>7j-=H?18CVp-tM1?kgMzeo zKd_giVUIJDCx0K8x)%VZ>yqibCT6!JzYdLQMxs9I8D{#Nq zC(@T@B>AW$)3xH|tmQg0L@4Hzq~Vs6AAz+R7H5zBZGXM@gPU`xZ{gXm#cbYpNjB%V zKLxmw9;>4w9|rP&w80{Q(+d@Vn?@;y$}u4`*W&?o4XvL~SFbZ@qD|-NeI{gIUK3w0 z{tq>ytK_&QM_8Kgj3YSxhRcU-8qX!sP@Ktre_Ioab3vOLt;JkaagG6NowPk!__qgk za>G6ux_=+L&%4B;zz;LVGe-KqBX8$JLlI#&^K{}I-1auI**C;|mEqRspT(~y#wRDw z<1vJksS^`^=xiPJ3gAppNDN$E6Dhr{CuQae+dgP^O;(o61mT6^}mMls&CLT<~hjtnR3L zBz#{Ek+d#zHqjOf8tTOM83ZLn(5;jDne*lJk@OI4jVb7{t@Q_o+Pq)>$KKsvE=!{>H77F`8dfJCP|6 z{wv;4#67p%WB<1m(;XkKvBDKn!b=d)!+3O=X)MUK>=JcD>i(U;4<}$SZra$mVj8}c(&6GE-7RNOX7O8EfmhvR ztx;Yx_!h(O;1$w?LXqS0{5R=MXK5Z6J~Y#}OW*f^*T2dh*+rrM5R*!irufR!>whKL z2>|1-Ux9*WHp?4vi_t$a%&uk^O(kj%g3L@lk_8%Q-H_kBxU>${vW}_pA?!1f{+ky# zcSCWUBvNeJvar7FJjf%`I2!CBtTF0EZvy6W7B%zU!<({tZmO_~nG^iWZRGCw6 z$l4!cAwl~YfA*V46@`Sq7iL=f|H8@3`dOyqjK+KYCoxZp;2=iV$$?E&B-y!#P|e!3 z>{PnA#pD6qrgy_n?EyMQl5>JH3HzP{T5qKHT_)WTJ5iiUpJE}oC;oc{2!Cbb{GdOQ z5TEgyIh*!BbcVV6lLkk0u66fn?v$70UakSb79N5qYyF~`$@P1!vGK>MV1D>zb4tjZ zrqi##qFS>=8c5|Q&2z&0x1$gsSDt5Hte$$F=%2?gv;MvIOIzQZ9}x1L1l@TW_l>6n zHa!yTDAPw+c|Xq~LI1e};(z?|PpZ4#RX~cwhs`#RizlMys@w09fgi8Ea;_s~k7d%^ zsAhb26{qR!1sijK$&=J|m|;&;q6ojrNfeM>6v*a-^C08tIxxw4i0#OTD-dQ+-Mp$I zZ5SCwIg$jyHkMytDWPP>}6>R{#A={e$sFyXyiDQ6GL4)m(Eb((~x|AX>M^ zXS{|v>%H5eJft}pe?=Q6lYkdGv3`7O0W-C=Irjehcfc{ZGk=Gp|2u}+%;Z@}1U@F= zP~yy9FJ>`kP$u3_vEPDNbsz3yKU2IEE!ZJskSz$1tb2O);z4)%hNHJhq)i5~o%pOk zwduoQ7)@O}-RFa=!mP1~18zd&7yVshVN9O*ibdIx6S?C*&R=Gc6JWs4W~`$Tc$n#g zDEy4O??J<5FMkB39Hn<%pTl;pCD1G`v7ghQ&RBmqHy_%OB4UE`F+>SSZ$#1%@Cvo< z1d~!!j`-OembC=R&50xD9?>yA`q1MAJ}l9bQ_2klGR&cvBW5n>M{WYMp8NVMIr#VE zmsAkv|9JN6yxf616l0}KZI)P~K@mEpaX(s;IUy7Rr?tc4mF?dX>D!`P+mBU9m$oDhIyh^1P-a{Z{ zdytZYv>+0hp`Vwn48MRfei?(wAM+7=gUREFuAsrLc^anci+gH}#EH$Y8&HG5kxY$zawO6LxiMd$p_tu66U|yX_OvMVDyvo2$bJ{mTBV@G)?^b z3@`McU}IAnDpJ&3RIUav3O%O%0yBS^dm@kd;+#bKS_F%6DPibMltO5Qk>ICB%t4SE zPk%ZS%l04As6VxC)2DNNHu*-MEfrMWO>4VeIW-wXg<|M&3{bSj=lwfpM&sp{6a2LMsBbYZz5ve$dsu!U;#T!NL zPowD??07%jQ8NU`yfk%P%tOz^a;c>41eTX$xCfUaq3MnVoX6I1Sxz5I)>2B&edPVQ zXeH4uu>4MT^!EnFADsv7{BnW(dAX_S750jY1AjB_VDun& zA#U}-hL~zqUT>-??0MtWn2)`!dl8YBMa|CD*~be*ox7UIt9=JqWQ=e=lUdc*FZPot zZ?#sXmE$QG$5I#}o%(S3SRhaP{ z`EBO}d*!&fuA;0qu)z-oZhxqxXEiE+wA4fj?p)-*=HTiA7RUEyqk}+1z@cVV2O}7S z@93%gI%pjJ(;+*3xe;zMhFkv5XxRt*AkF$HKR;iD-mwP`ZCC~U)#yV=3^2!f=;pWs zo@1Q7Zm@3=f5kMG5UW?SDd2?g!&nM})|PiU$x@ajLK$P-O5Hcy4u5`Bp=I5cMAa{T z_@&^sE|Azq-{imAC^S}@aJSY@;c?HUK=VuergYu8g?(1akeVx=Bz}Ivd6%NVgM4St znYTQ@OU2+%$3~-L*OT<(hKcjwgR5wbP(Xt_g#o#Zff~eW_IeAqK!kKFia6h@m=j|y z{MA6ZGW&IpXCk`&NPjt=Ul#8i&!X4b8Ij@3981jCXhn?IuZ3%&p?%(@EVkH>MmQ+mvsQ0D+)v=aXMdK3WywqP*+=9uh&Z4uY5N4f+I$#;f7t-IiH7!f`I+}v9YEX_GnJhK z^0K4sUfdHW^nP|b$Wyoqz{b_5pv^OLF|=Oea6$x(2R-H8AU*Z2NzzbYZLcsI8+HmV zV6nfk(`-ku6My66teCI$j$KY;%AS8KgB_V;d;?u?B0{KoIsfXODrP&ur-z%(FZ^qd z0a}Zgm2g$zr1rW5U7xGcc01`Lu}eJ9-YD)+vhZ{}=s^%lAVu6M6WJDVkAHNv&r-GD z?6L?1EXQxPmtGj)LcFEzcZ2b`o~uU1&`rgQp$Br)pntdtp3Ic6{eV?zoR_C&v;gxvZHz574Jlu=4D~t;BQ6f^P>k19O$# zwEt>1+1;*<-gi&kcdM!+O<^C`egAzz9dIdBP@^kU1ASmg{+mB{gXX|@ioewP#V23n z3q#_|=zrZ+Q^J6sD2ohL0hz`F$1d)M%$M1*!J9z(oIUt=9+CVfX>L?U)oqzS;QD{l zCdzhAjs#HVOhvF7G1Es8TH(g5(EXq^TSI9&SaY%v!6FdVN;dj=YIaDQ^(4&geEo^P zk#CtN^a*n? zLiDpJRa_P2IPDq?&WEV(7{p&%@dX4%jR|{XPropsdLUH@d?OubG^;wTaRNi_r-S{n zPFkjVU~7{`=S*ksul+ke7%%7U!Uz3t1LTfD?Lh$}P@cP2bo||)u&ua1@~FVl+s5Co zg?|l(2$7rb0N{yehM((j!|aIXN;w)qi1wQhx=`t*X@^HesN}z`RHU5v1X2TIf;f1r> z5g^5pajI%ft1;>wH_Rj>vmE634KVp?Ssd**viQ$ZR027H5rqFFFt}qM->y(fz|&ye zWi(-mw6 znD48RNL=F6rlwQo7xND|RFB~aj^v(KYeW7&e$d-+rPTO+ufB*(LpV5>z3Xo1ptR04 z(z>X@*eR*3Q{l_taKou&sh>8C=5 zvKt=9QM6?daw%o;M@DDbCX;a8VDq~uT-J%3Lo_4Q`P_7=4e}u}3nWbcIn}x9-K|dO zS>Q)8bEW7Nu&jG*lj>*)H=zYh21$-mk@L6HQqd)m?~kU}z?x-adV63H*Qt6CW|rpd z1Lm(ARO4Znp~giG`fikF-+xxaYMh;RXZxj;Wano!r(_%zeu}c_)xmt~7#8t~1nImz z%()RI)?9-4V~{f}z7guIC!{B(Yz+7j$OwWC_IepPRKU9R$T{CVoJvjrPZ!bOwmyBC z0w3OsOY*$Dc+Cu~^tMz-TF;AzO#Qu0f=WS!b92Da{@)Ky3jE<-*MIQau!oAH(}YiJ z+q*V?X}G(_cTMA{?5F*LF3*5IcjJ<2rbM9wQ=NzA0!6h^Tj7==_Mnn`%%}9by;zYUgg@?a{!#_;vRtjrh|NuH z2GGhIb^}?^?YZ!#{C}a!V2r?ixPNQ+G!@c!Z^aLLkZ`z* zP72BqPeb;~W1C=u$QAvh(~A3#G_1PdxJTdgaQx3CfS6DjfO&)MBDGq;6mF#~mPf=@ z!f3`Z!Q3e0ZZ+Dop1Y&R*4ap)-G(!&{bC0MXepfM!Y-lz!hikdgwG7%`Wg8?fMzV` z9BP>BQnMyy`)L124Ll=ZjhTAmVFm8=%UOZf{9AKR-6#Ls1j^V^Ux);F1SDlD#lefp z2riSnQT_JhVPA$Nq^td7W>MST#;M|~}gl`RO(UuMVRwWA-d6xwU!AbBGe zuRUziKFr=pn14OZ)ZcEU4+{#-Zo4^qdElwr`YACf4VCHAApwrOFfS?fZaY`Si1QSW z7)PRzWvPI8;gL5M?wU6D<&$s*P}3KM7=fSIjtbo;J1ZnpvHiIX7hP5tpS?3$>ZBR# z4hs0~A5t0mNsTO@87;d>tch;&-IS)Ol(T|6iTwP<3V*hZ<}NVe7z+YU;>}0jn7wvh z+>PK1U06IJ%b zun8}l?GCOXxAv6&XH&8@!%soKw)v-XgukdGJ0MJGPph$A?eq!qQHRI$&`{uj9Sn%3 zfK>J|T7MiqvL9-Xi4zF7C?yD2PNUO@3g7Nskk99LmUPFRMcnE%3Y5!L4?Z%6B1vyd0Y^`ae&}_sNe(@LY00vS*;K$iEB}?LYq;%dbah z)f>!-Z;SasmpHyI!OdSXetEbSQs9Ev@_$2EoyfrL>*r7x{?qyA1pS%ryR5F?Xmx z4D0ohZ2it-q)M$}Ne=gY57x&kmQQ*|@+G4Kv&ds3?v$}5^|!a6Q8=+=8#b%GE`LbW z=Tiy%dhn!rcTLe~dU444E~=IrEpk}{Joqcxouo!cJ3yr7@dsZB=m4bWo_3_HGf#E2?abjtyc7;bw`OIW?vs zto>kImY*=D4fw`?mtN&pfnzsf``xkhPYt~OAWgu_#UoF7^dCU0i&gxTNO|I?b{*{v zZe9EoBH`8JMC6`S?#)Sc7vtfl+nOjZzY}?M(q%+X8Hlv-Rt6;h7Q&p{&*r>=WK@9XfmZ|EH?IjA{eux`ts| z9Exl4;_g};N`V5!ihFU26nBDCic66qf#MV?#T|-kaEIXT0Rjn0-s^hq=l;I;{W0sT z`8R9L%wFf5*?W(9DT**}3V&#^Xuq}5F)2SCa3+j;n_a;#GWnD``yoH=?Ld#rUiDj% zkb<2GaJ9C-+~b$c^SH5f8K2P+-J`%wnWXvcLL5@W#p~1K2brYpr%CFHObNRgtg!7f zw6q;{^Y9lK{0_TR;~)DPSq6!TjWU%toEoR6u-j6VuU`c-RKA&s)PGLPJ5ApE`_ycr ztUbP0#c02E4VyJ=m@fz=yQ=_Wc6$Q`VYAj7zhSz4BGa(h|36chR)xH<)Nk!tzm1cW z%3O2t!$+L^x5;_KUb^QUT<=_>e$bfWs!Rv?fA%l|x%w}QzIda;#Oj_JfWaS_XnBjX z@#*@d+K<#nRl!DSvwsv-+TnO3calOUQRywIBWZxQ!viZmn&bd1aUn1`SN655%tTPc zy;K7~%a$W5rjGlVVVdyRLCnWw_(@90$~v@Od$O+_BYeAWX!fV1P=9sUi5tN*4;~?q!v*i|hEXEdDxFS%+s8zZ4i&Q5ete_bWfUOIcQb!6 zFqumCS|NwDWMwa(SsrLL(zE$St22(4A;DVU&kY&;bYD_z@QPevpQ%(jL)KF68+87x zX4%Bpy|{1%Q!iXcL>R=On)j^8aED$%PoNpb^YS70xymR zs`T%8w;Vx6T^7OZJq-q(&9h3BA!HA3aS6Rlmf|k!v}Rh)W1sCyLydK=@!|uX*iQu~ z&7;a}DEZ1AJ44W8uqF*8lYjTOS8tnZ4Y$Wm61|<=8LZZi3wi}XDD{||^8YKgsUTg~ zuK=@QLVxvyFN0-Hwe}b2TF8QUyV_b__s#e!HlC;`8MD zv3SqB73{E_b9Zt?dVC-wEnf=S^Zf{(nQ6 zE&l;^9wE{@p!#{pQN6Vc;Qhr-$J=sWK=OeOLU0_R-(8WU0c??*4*-UAp|G%S|HI=T6IYfehQ-Cv;KZQZi37$~OYzUL zT*b-FuU5ey&9&!tsPU515?PkjKd`l#^A0R}y{1e!C>U?LOch3`pAvd?YfYKCgn#DL zcT&s72J%e*koR)0K@Gw{HN8I3p-3=Tii$CIz($OwmlT@#&k=PI91H8N*#OQ-QlTiD zKy&RY0mIWnkEq3ltq}g{A$Av{$9z%HMR^FnrQz4d=l|u+{vSz0IX#CjR*m3y!l|L~ zlV4GdWzBThXL#hw2a>C#OzKI4JbzfPVl*@oYd^AM#($W%c%|synD-($TJ{5@jew4I z%8V*CS3IuPM3!4%ZiGsN61~QewEX@XkkpJX&y0&i;l(+_B9Z_4%v{gx%e;TnZxb!W z&PF;_`A(t)3enKq8{yb~^?y1?FJFGEJII-CfI|ZIjkwBpQoBA(loNi|n}5(s=~80n z!+*}^dL*KFjvISipLwo2OG7gw*dnikOsn_Zd%DZ{#x%?z2=pz_+iENLvaZ64P6B{U!Su3XU0w zAxQ!}J4D;w8?oeB0v-12sef0`Vb?y^UEeNFyTumnVGWTyhaa}Rg7|_$fZ1CI-XvEw z5UW<+NW{*g`d@GL25+~_f}0?#J{@}aDPT>`LUlY`@Gll zHk)i8{9_;e#6Lp9JKqpYv-5alBKnetp?8`R#nt9+)6{Fnh!5ZQErDrRNbu+mb{~Zd z{qs5NBA+*3l`ADY4~U*Q?oKg3R{S8ts$LU-w)sB-+vqhH6ic%#MQxUIe}x0 ztm3-@;xEm>g1F@jo_7Qe?6-n;+M%D{$gLcSFXaukw!d5P)KRwn1Z!{uM9tphpc@Hs zJ^NcgGP9P$e*GVxnr-mJm&MROgPhm}b0!c{vYXfWvh`_Cp#H}|1L&&BDNbRlQ{14k zY5t#2+!PUxrGMMC+yVJp%G0lZ@hY%(JAiDL<8HUr5#QpMH&UUBl(_iU2s~5 zY;J23j$zdrvPxLGO7^I1t`2`EB>#46km1cp9vx6UXn*-XCz|1sC>oLcu@W_!HG*Dy zuCJymbsmcIM8$PWME-;wf6D_ZCM&|42<{k#Ee&>&39E~dwWuq}25|+satFDxpUo;A zeZnznE&b~XogfeFVAj^o;z*|1N_{%@)LIYvG%wC*(7d*kz>&K&>pKjUlttDf@=+Z< zg{q;ZlYc74kbho&2sGX;CQ=dtFzL0X7-`H&1XehyMd2ZkRw41 z35`;Le=B4y{Se1$I*&eOvpp%=rx3Dsl<&$61w08NB<9O#tSldcYd$-sT4Hd{(ndPGi$MYASl$Kdq zhN)Npx+a93T>2Lkb)tjXcc^dEw$Gj3_RoNm@)5VZnSqKx+T@V|zOj1TddbRUkcapA z`4F~LgIrgRE$T>8Go3OhOZNNOhWv_#VIq1pWgNP%ySvPpvg-~Q zsbxu#{lUrlzLJ`4SF+E2Ym+obT^|qI(5*4R5Aw!}^4w@y^|WFLm8l1HN4`t+v{3S7 zh$^~)s3+QpK7q0KqbXX(q0Pv)AgS-yH+7c!R*8eR(Dg{nt8aANj7xu*_!A}Djx!r) zAUgn}sNW@_8eSW-R_mdlO`W<;JV-{fnPZ7~$EG0AMH~00chvDuAS;Ugjcwb**pW+1 z?8%(#V-wQnVBS7N;rh|j_A9W^Wv2;1OG6`-xF3-KoLw`PXR{X9Du@@^tFJ9H*C*0W7eWzHf$+QC8)Eu z#@17Ivi>%9=P7vv?}VKv^Vc8h=od8SGErJ=x$^Mq!ckWQ$_)< zQ`er%Yc<29NGd5lR$5kNidFIM@8tOoT!$s0B)th_G7Q9(ulvinV$$*Y+|Sd5&!PKa zskQZPfNN)9|HQZT)8V_hq6NKwi1MciDzA(2XIU;?7kxzfF8nY<2DpJZJ=MAJ+T;pX*wL5X`-dWICn(* za*X8cw?nkQXagu%9V5=q|Cm z>f^weM}Gn%h|xMh6lvmXA)g{GHLfvJ>y#w1_e3()U1R^j)UGF!YbNe@_(flrMXSuW zVOAY!{7@6!`3?l=(G_^@#<)1uAfOZBO7EsD{D^_d&(e7#%*;cBjr}a{;8@e;YM&Ra z=2t1rO1LhL$`hofO#zCfM~cc5=@%1ze%blOwl`o*#T$!Ve{5J*Vbi-=q`+WJxW3*xiR>~2I~D`@BWn8$?tIuyC03GyYmG~6 zsvku)H2fD}K-TyS7Ykwnj|ciW(k}L|g@pc-9lOPWtoIFZy7e1$@b8*&_>WrGJwWc) zIy1D94p-0I(M?*D)uelbF`5~d4*!1V+QOLix;CFH$4lj_wHwlk9*IEi7?uY|;M&rc zCW9e{rO_v#XkPpNa^di`d_i$U(dVihjs5rUihCWMsak3U;BZIPoG0^6oKvmy(CHu?mUjg>HE0KCO3Il(X(P6CpUyF+ zb+kIA+%wks6;+%67GHjQ;FJh$#yabm z$heD3DK=lq5u?v~9tf$FfU2Pqit@3*#X{<_?E71j5cR-gH7e-+rvyE_>T+b1(rzof z!@IFI>v2PWg1Lz}rs}*M#=edRM8Z-dErVxgQV1(-v^gC{4%27TmubJjrEo3T&cmj} zec~DbC%Vyip5WEhpsXv}#zH+^5-Bb5-Fl@W$2yW6z(db&hb}rx|&^~c&m?K~u7rJWPTXUtAHhWCxtjYl7qbopvlt}iDva>WsYVfDZ>M8>EmY3>; z=eoS6b85rp&*gTj_K>elG?;A_x=0;Hs(I3upI2sZrkXZDZ=jiEi`ncOgH{N0OhZpvW z9vhy>C1=Mt4(vwBZ80P^WL{Wmp4r}f0mqG)c3s2}tH2a*g+9qhS>MI8b zlQu=}YV*d!@eL9+pS0VVX4%~e=jW2dq-TzwHuNro!9s-?xv_=ZEvv5aC>od3_fsOa z4A=A6IqAEWuyh~{8W+1S`}?2g)Hl6!16PYEhn|$e6N5k1cxWV zWQolQDW#2;tu*h48|Y@1)1b`UVsilhq(U~Zjc{h~wmV;`l#S754q|(}cxALry{##i z>)~>|!liR5#ItEEBMJD6dje~%r-Qq4kjx^x2|NAE@t#Cn zMp^R3kOBII`E0;UN*Tq3)+u1^T!2l&tNB$w3mSLTbZu?~@ZmM*VdTmm$T?G3eMu^k zIX-80TE45mOMtipuUM>0HPfw;-h_Z=j&qOgSaBT`|+RAB(5vNn%$Tm z#G?TlO%1#*PmAhn!nB#sLeDas$dhi`fHd(iF=%seMFuHUUGp1$bCCYZ>jTjFF#!W=nx%7X#~@bLDsnRVdjq0Cxt3y$E=oqdtsQ7c({RZPoZX zfD8@~tf+&+!aPjpYy+JAY$8{(rI@NBt0i>5=g7i^50U%hRboCLj~jn6?1M1bgSUeT z;>q4#9IwWgx6SG4s&Yb+7+6+^wF%0CB9*x7@2adghJw^f(G1^7e;n8P)XjF4kFds1 zJaF`b{>lI%fOHV>RQ%TQSAt5EXkSzrEFCnvNiv>o&k6dD{spKH`P9^)$`z%}4J@wV zpHsK9=_1W}m^$$a_~XSAex#bW5wLdjcU+<5&nfXKZ62uK%g)E)p!P63>7h-T|KAo# zuwNzZ#(ns}vzF1`r(Av#Iaq$hjnx$v#FDNqDS+~xrr&%S2EgG*4#7O z{$ZHveGafqT|eo2AJFf+qgm{Daxj6?E=*N-{vvl5V6Y1>$y+BI7pTwmr!k=!yi&3CPv z+>wsVci?IvhkG~t|AZU)-JA#Cr@twWE4=M-va7>I6rghYjHz%k)$?a#7$_>(YZ_$r zqsiW)n&nPB3gXNUZ%t?}a;YbmNodjOUwzd)oH+pdA9lxcKrD57&&> z1*bf&qD*}h)X)3&aY3uc-%{^BH(v6XPdJ5U2NuR<7Zn|w>e%%Y!ydkGAe+{D&f{Bo z@>fvXH%A*YQQNeEShk??fBI z7{>UaG~32#5!7Ur5$ZlCg194xf zIK~g1bu#~Is^B;*a9i9gyjXtx`DmKsrv6#jM3ySKQ5I3Z!l{_H|K*-iqG;>FlR>}= z6>?bKMNKX2tmG#j$B*mMx;{^dwYbOw;_$5I0P6vNdBzSFr+0dK-IfhR5Qp)-g-QhU zynh_}%G-NzRmxtl8b_w3X6uisTRT=>Gt+pL&s7X8ex=Hkd47!Q4T~05P}nl zEXnJu>CL@mpyt4qyhW}`l;0z4vCIc3u~m|#rSJ5q?FmUM_Uu8E)@9%|6wVlVJV+>U z;hNI6@!kvq3;9d7>FdD<#Ag2vJW@W32bTdR58svR%AIJW+_N|S<9}6T$vO>9&~mmf zcAbv=J7y#rN-wuuoxid2_#%Bs?8BSX-4Gm=t#ta0|6#F6hzds4IjH}QkV+RIuj?tl zX&66bAy{nK>!tTRbr`Y~?oF8WV#TI+1ee^vB4vu+(w9F#XeEFXmyEREXb~2nU?-*T z9~qzIoOZaootRbR4}24 z{+jxgByMtBA*0kTM@nY9fzFJyfy2d;^Fw}~aw@_yCubAaICy7S_D3S`l+gyB#2M^1 zTFoMjV`$2{N9av9)OQ4U(bx?V=uApk(l`6O@OF1HxU(|5@j-AgNDcXCINv&hnaPcl z1mg;GTmOJ{BEWQ5LLK5n;w-FX$EBm^TCcj~x8BFJ;b7GN(u!5*qj6mXHlVFikC%w# zHHr{UFF!N+e||S8NnVxo8EiHMuPp&;JYG z>JQ~Ag%(k)D{_L}#ZRW^zBP;f)py6uW^ZE}ZA;CJ?{)U&Ch#F0^Xjxf7FiNMx$>&8 zL+6rU<5z%wXe06cbnkBzWJcUz-22UFz%&{a#a|67LWSj{>7zePHMj#$8$rJKm(XNa2L(c6A0GsoH9qCiLZ zzuo{WyjiA`O`~OkL+kke@^X-#>Bt*BBN}mpD?8A@GdAAn1?%!a!X8<>_Tub0)$+1^ z)J$*Mqlwm(*@w5=lpNS(V$<$bXc7DzkoqVA~ zB4$^NLBi(%Xf9Gin@`)5Cuu>jH0|;a15yCKa*AVws%L2I?7JxY*QP=>I;po_X(D|* zN|mBSI#S6}I(Gp%*18?VXya(vUcAYFIUvPMrVW(U8FPQn+U*0HVz|s!)H9Z^)X>Lt zB4=ZKF2d*_?_Q`+Tr|1D*(%nfdF(ScQ7WAZW^6S@Y2h%j=|wbiidfWjeP#G&1swqk zI}am^xOk=G(C#h{dJ}O~;Y9kb!bqATEv97WBxDItV;^I*Jc1tN5*s?P>6S7U{s;!m1|imQv_M)f_G);u;W)-xP8V?ZhE zF-&l_NaQ~r#gI>`2tlImTl6lIt2_SyGK%<)<#bClB1X6SE3J|ggw`RK$)5=;V{pnk zWEc1bW%=%wFvCwr;&NWfFdi~hUlAaM?zd^9t4mG5HB7)))HNyTST!om4H^I!f23IX zVcJHQZhKTRI`-3RoKV)Nw1)T(I+w%7krN$bC_{~i-ck6)QC_MV=61$|TFY?Sohze2 z|5VnZY`=`tYa-0D=RGmy&m(Rn-cQ6Vgfh3>EiA+^zWg3n{5R${p? zAY^;&nWpeQqxO_=*ECf%k*hc-NBJx}=*Y?TR*fK}Ey%S}{`kyG_k)0Qm7W`&&G7CSV#Q?by8SD@a0V2Mu86*g*pz;X|XjVdagjWvb zYoaY+T`Dr~en@uJof_-eWDiJbQ%WPF^S_kn2RmhkI+V&O{n)q|6AXN{%vCJEN-Q0F zlFZ@5!$nt%8xz?w-+Ki_?enN6&HSW|?i~?=XS+&zdC`p-t4ksd*mqM7B)M)N8yz4c zVFweweTMTo4ozKT*eoJ(EEx1#@U>~rWn)wmd?d=2e<=LnUvCXV`&I$DpN-r~l;%rX zmI$A=*1Xp|uYW^6tp?(9iB&b+5po;04R`*(RYP|^m#T6DVb7hWT+pxV}H6vtHt zNy$;7l+Iw9@D?&W&OzUFbLNR1W3+GBT0^qcK(g7VeB1zDfv+*nY7EL--w(E*wi*Gr zi}%ESeSTC#+B@GQ8A0!Fo`&O;s?NM>eb)yCf6>HXa5rQuPaz{SZA@$hR#;9At9kYl zhMj&@@YB)X(4GxpH1a#iM0P_-C-R`>_oo@O4XlzWPXEekVV&hE(N^)G9`XQtcD!+Q zQc>>zBU=RE=qJ63u@0}*75GMNzhgnT$3CX4AwzXCP`n^eiE`+G?5-P?S(6X+>!GZ{ zV`&NLniwZZ5o1E>^_^mx0$jB~QO)b`vxaDy&VB9Qa z54^Doed%bKbDr<%$7?G%cS5vQSU}wj*%HP*jA?mYmED|^UaY+KW#_#R^l9z);X!1l ztT6>R!B%2bGrPnUE-w)^e>T+fJ_pR3Otz>|FFAw)vH>kS zkn-gou)3=E+3C7J=9}b2RCD~+7VGwYJF@|xgXmld{-ptdyLMJGlab>RS8zV;9pc$! z+UqCS34te&D8iY}(&Qn3>*GZzk6UF2!HlIPfbk=)vB`EA$VvHJi*U#{2)Cr`m$z#? zr^E&EH_dSv3N?7fI?+B9r`R9bcEn%@1X7!lyL54VW1(fn4CAT|FL&Jv-_2>x=_LXf zP_Yi9Zu1vkQa%Jfuj9mU!6Z)WCm-09-c|g8^7v#u5q5e+x7_GZwqGG?$9iyI?Qu9x z&PVj9n3nKrOvJ!Fc?9}}aGmHq+h1?r(9J)I?=4TAGeUvq`+pAsF}b+p7Hg4OCQB0* z8xO3AZ4wGSqW?Ju_^jhv7yWE3ihux)n+|m*0hqlUe(!*AxJ2tf*!h*CX$SnrdIKCZJmu{2YNd|Q1e!;%Kfnq?`=58(z(^O z3Im1mib%?59_mfyrIiM`%DmHn^PGrRZd}v|l8y2FyKy6so1RdTXD4ZDwV(&cKr$_^ ze|ao16KsG1dMXIH3U+6%-6IL3@5&h(EYI$80|b^0t*`|_BT&~Fa`Zft2WrOcM>$=D z*96ABw6aV3U-sl=ltt7c?qUHtk4deZxjj!s15#OC<@myns#*A820)fBq`xk$G6!BAAOH+oKQ< z@!kagusk9m-8;kM251NN%%B@sXuMmT6{#We*>hH8-31QmrWo*7BW4-n;r$oyjs?i> zjQc!Bs@pCLGujzjsEvq&L?<<{m)G-2EU`KZHG=hgI-XQJ9kz?p$UtbIa=k1IVRxJP z{NI8xFJ4v;%3rlH-VvZ#546xac9Y|C708)zuN+|<_X!}JYn1-(1rvx2MNSuShSKcq z9OA?Yvb0~>%u#>^sqe;@UL>P%`$ZJ3I>L4yM%Ut$%K+fdWQ)t27E|PJZa(YOr4f-e zWWVnQrml_?$>VW)xNo*fI#jMl3b(aw%s814DAs0X`bY#=VZY<+Qc;oB-dhL0*R#B; zx9#uRVZp_=BPURb*7iB022=pwZ*JWHfvp*}JWdd=XBPl*HtK>yBq0NOam=F}jWSm; zrcfIVS7nbwtj^)1OSqkr>7<6Q^Bx8}NseJj!%Oh_>3H=mgw_Opk_Hv7Q99mm-CIgE zdzy5GScRxpc_KvZuf2WNi_+6>|GJ#EK7nKn9q@#5 zoTAPxkeK`iNCMl>1VZOA3}HLVU+*{m(o?G|cQm3|A>BAF1l*lYtWAwC=k8?+lrCEyMrfI%CKjvC(aN#!jiH;8; z%1;Bbh4WUra9d!#$FEAVcjLWfqY5+T4IaU@p}Twqr!!BtaefQ?ci4>U^GXQd#T0cr zZh@QYx3p!hRsW(GAaQX7y@U#NSJd%{Nv~Ty6k(2OWo3^mOwsqrW~Qhm#>TN4_=X%?zmt z7bxjKCych|47{O+DD5UIP^)b@DsqqV`YbnZl3gh(RtUqs7ruQ^mo6;RB*Qd4^neVt z`tcd@T=v+qpOi>z86%4F-G_LzjY1nhgs5U(EmTVt73%gZhuXzG4 zQ97K;?)8#f!`cRX{V_{nzM&J?LZE7-eUm)J3}9^H=7D$L%@%JZ zSwkeJO66}Ku$VboF;^zos(P5G*|q?6e zL|;_fWXjCOF!%RA;;WMTYY%X81Fu1gK8TyTUpUn(gzK&4LjKhsve!Kjik*M}sE6(l z4f7Z$zxA@u0FO}{)|!v;yt(@ue^k->_j+4K4di++3>THFnRJ_flMiM6PDd6Ox8Lc6 zpM?7|6$N1SLBS+e!Z4E`ZJL{1=-Uy^nb;r#i+j)d-W5qz}H+qRz? zXe0#9tnezQ++wuFwm*O!dv+C$Fy-s`f8W`PcdZ-si(vSyPg!cde|59pz&-F`cNei{ znz+oCaD*dfz_T~AvNco=xwYViUe1QumMxbccZ~nDj;vnIrYauRd{+jD(aO8Y8^P+p zL<(dPG6*MKWEs%uTB4Tg-a00;xkxWh8t@{4nO$yV4<=Y`#92*JufM&US}7XqCx83& zbXQ4c=OG~7zxl0aH6keNBx)ok5^$tQFy1+MI7r-G$k~W)^202((U94}k!dzN?BJ>w zwSl6QexocRPpehmL8k*4YjJS1lF)ibO4i~EUwDupBbZ#X^A`3s$D+Cx8Wh+jEB>uC zIyWTj=xFAj4txe31_0E!GGAQmqwZ=29a&=+JGk)*yu$AY52G0&aD!;H!n&%W9n%{# zV4;UB_QHfB>dmJo{Kz=WxBO}I<}-T6{_Yv(7v-4CY)#>MT}=TNaAq$}b^G?T_0gXj z9NF{+ReyO0NO-^w1!qEYE>yZsy;vbf+A2O=BEF zD1KA09^y$2hT#WDJr{Q99l&?(D`cS?pbkG@kpP!d=&;R*KJmdpzRAw+;dhNsw*dFt zO=eK)k^s;JBODw)oWSIu>vaVCLa7~u>v7SMW@YvI;$mMPDNG3j4TD^OTPe-$9437Z$7CBJ&S^8lh5>W zyr<(6^5^hbpF*Z<0gCoz@4|Tza3rwFf)|iIKFBS^7;8ZUau4nZoEvKezoniI$;60LnL<29;Wioiq(A3HQ!qOk$Cw} zj6E7AZ?7p}vJb3TJA`Hvxo^iG(GbZc@ukH=?$kSj&(i|<_w*WV!GzCoVRO1S#2tI7 zomsnb&%d*YeW_Jy8hZr1niK(ECaoz?KB6Pp_~-h6&WLa|thVS^$WCRZr?Grr7VM9! z+&uug#Cm=IRF!aE(9TwuG4hqE7{yhAv5p@~DuKpq{X>hJB_|KBrZ@n-cbu_7AQA$# zne*nbHsup1P)jF9W*f`Xe?o}5NbN=>OH6(gy|E6x9X?=+%L)ew_&um4j9MQ-_&y5@o6;h z7ooa#a(~+lmTwE@egQUn-Gv-_9@q3##B8^yyt1x4?N*}(O`~+n`5b8~4*jlQz#{=^ zoZ81F(%e-I+6k^z`h^d58Zw*}fU5%<_JQAq8L?e~7;Yhfftl*lffE_;{>AWB(pLUy z`Xx}gc%5wqf21QlzFq9*7Zaxy%pn#o+AtiUoi@j***?o@LvElQer3CYIE@Fme7P=7 z+q{K-e_aezteA8@6>uCio~8q2NoqT}BU~bn&HyTBN&yEF&0(nUa|4=N4)_5|=siUA zI2b#FU;>kvHLkQrI>iO)$?5FSzkF&84KuLwI;tgP;<9q42DMi`cf);nx`gM?MyHni z{X2QYr{!p(Cx5fK-08o*Z;H5i*4@7%>edEUmQAbT@_EcXygz5+D!7=GSBju;sl%P0p788DaNS z&SYG{2M{!av&<%cewB(D{?S^%FA0WP#9yz2{AP-KnzV{ePZQXhN9kB~8ZLA@ae^7m zw(o+!h2)i;DOe;EZT%+fQ}ovYntc7hxc^& zW`*CuE`!9IdG!=v@2Tg;!+uAFA&`|Tt*i;V;~0QQ=B0mnp3nMo%uQj;sf&NaSzf@q zQwpsUHUCQ4%N>sVD4-I7XYI{GeAoS2FKo>8=oyvm^v?p|vvS0%8mSvApD{n?`SG#~n{1nr=Wc)t8XWk=O`( zC9ouhcfGgq?JX3rsXkI?MZGe71NjfV5u7^E1%Ff*+`sZp0bv=bze2d+ccEm)LXD{k z=t56!6XXPwm{xE}`_^?X|7ya4Sj@g!vTSK7E1!?wogTz`gF|8y{gaOAErL zs6!6%AbFfhl9Mg{c?%xGr6o8@T)PKciag03#(D~;6NpYsmophs2na0k)ysYPEQqk$UqHDc4 zksJ|a)Jqb7^p}t2;$#T2K@B(cJlb9G1qT%a)FiG&```1yYGwHial>HZn`S5IXVu-d zFVS)Z!_$d{A{IIiey5VX9(>)DDp9J_CKcU7f=lZ3@^_2@#I*0@uRc#vg8S?|X)HN+ zF|joyN|;_#DfJ6{1X-^PU54NMd(E$TO~5TMb-`kQF+tNWEqSjv4nE!lMzMnH*sTEucN5DT%lHkX4CTQri{63RZHV`HSPE@M%yF_|D7iXPm~sbIt~FpaU-x>c_E;u8MR6Vq8h!0k(yVkCTHmrLPSC2XWO_OS0IDg z##AJ6B`QbXNR__)xQ-t;D{F|a97xf|fkCt8M!DT?rViMr+V06@0%f9m0daCjuE19q zhWB$qEu|(0jxFnHwZ(_q>3aTUF5^*%4zcdw(;eekmtXgbWcs|*?l!>YpYpcD&}5os;S zka;yu9gCcIYZAdKW-szECBpaqe25XyeR1i8%tdKmFcRT&PaJNiZ@pV3ZBh60!HmB5 zD{8S2xGa^nxeB3CfbzqRtfspU`^;izp&o+PNlhSn*L@ne<7PDKgfYi;8ijVkpa{p) zE$P#FFJ7pvXrj$O;yw}T(zl1htWCBlzQ`n&T=dI$IZL89yVR6fU(l~!IX(bTUE4DG z+qA@$!wHKHkkb9}Ua$44%$-^3LSg-l=dj%})s1iF#@A=;DfRtvU1KOGoWkcS(v;%5 zW+Sd?Ya7mTbU`G>Dl7UI_GSAa?})mNWW4@6-HOxPw0BmP`F2D$!t+!y;0LZ`R z5f?&ItJ-fY$QUO%6Ew&@oIYXQd!*9oQ=(;hP+CUIspaf}ONdNgC137;-fl76bVUvJ zEl}l0;`pjbM|qqk)EW&wxc2oY)p@8(T(`eG$FX!fOODh@Y8glt0ja(x0SW107Y2X6 z@=s|01`7WE?k3Bk&p8IrI6_o$LCkB^LUU-IS!GCC8^t$$c}h@xvq@Z{zs9qOHR{~+ zb_YjDdeTz$*{jF1Y;iLdv9~E@nxrzqYJ&%S(B-srp3YV~Yx=ZHuY4jP)*!IR*Hl5P znQwjOkX3{de@@(8>kPzeZGPGDK7({F0PY2=98{+{)wEH zUAd(`IB$F+r69}Fw5b+>yNcoBOuyHJHNL4KX|A7KLZ9Dmp}t+3NM5s=jr#ZAnw?x) zlp$3(Yf%f7d%OEDu?G$Ot07dg1YWC;{&m~imFWDKUbQV{>u&SP;2XFQBv(WTI*4ro zTeBFuN%~V?RuSC3}|B9 z%>fkvmRER!y38Vv6Uh)k!3@rl3vQzvt`Cpgi{pu_FQ_#WoaTM1btz{Imd9uPVC~1Z`&f0D@e%;oPTyaTF((}3^8_-tp)u`S z8pat|Et9;>HY+nTRf&l5Ds!@mq15nZuxgTrZASmsL3q)J`cSzoyt8mg4_&s_7}2e0 zCq2{Tj?RINqthGzmtI$Dsq0;qrmH^8BXIu-oK}eJGySe4Q|jrfJ&*>Y*?BBpLl&IF z#t=~UpnC}L??kuVa0EzQv*u`eJcq&X_CL#=#t4Jq%661Etwy3qZH4eI1d-54@O+^4 z6g7->|GPv!MWgqz)G`WE zx;u(O{J0~KGd9C!F1*L_!JM#9UN|>87o1`FXIBi6VVG7u5$91v=W|pX{4e`*+afCT zPiN7Y2?TlgKtZtoauB$+8Cbg+462*$1DuzjUf2z|Ce8+btTr@CR@-FeyjBvsaj8Yl zl?pEZ&wr(?Uu!E1WgH+~YGgi%EN}^CMW7`Q&AtgM5;KU5beaL}vH*YgVkCaVP>P<^ z+FXCYxL^pS%rO%%BQ@2%7h>ppir}nh2V{(P4Z|e!w2*&rP37+7?{>#aL0{fzx21!g zRt~H_fGu@Uz_x%!L$A-XnYCM zWyy_C8PhIOH0gKqS)6hj`nza*k7s>a=1CQRSi15aCz$e_t0QRVm&T^(dV{}%O%&V% zKt;CMWocPBtCtf~yw`GCvtX zjky*qs?cxh;l}1p8u?4X(12iwe#@|T08mRDA;<+VBBrR{gc2|iP$mcv5H1i< zN-ZS_9v~=QM}B|^E9m-}7V4SaWRjmu$2D&?2`6FEtdsO%Q{0Lg_-_k<@v||VT$f;K zcNfUEzAF*@4aCT#h&?qJSv*%XNyd3&XW0s~lDR&*A`>&oAHLgv$Sh+DB`>WMt}|6S zz#fI}j?5%&2G`3$?w4>Sr_iYN3F=rz$XMcrJHR|z)bVySM({|nk&K)(+i_S56z)NC zkdFnER4GSx7Q{g)*B2$RAuu@c!&v6D8pq}eYeH(xkNR@b?mTidBFU({`n)!JJ@ZhNb|rcZ~8n@c)%-30dmB(M&q00 zh-uCzUqeEYR7NkA2O}hHh#)0mBK&hc!lgxiH%*-g9P z!cVi4t=n_EmzM)NlU(FV%8QrCu!gSkLQiwTTb?&xX58PEp;XRZV?TN^Ne^MjGMCtr zl$aP5%WF}fPhXz!=G8{SQAbr~il&mt#1O7re}1IO+1PQG+rnE}RR-9WcC^{_=^cfvx7`&$ozD;*H{he^-5-NEuf0*Wqf4spcLhr2mii)N$~P&<2mH{|;ZWO8 z#~6Pii7Ew$36J<@y;1-iSW2UM_6&7vvbwKo=->;(^ZS9IxfBgivd=hHu3$bNlD*dBT(ja*%Ln z8RO4=6jmUh^pp?^5G4=`j)WKvyp(4O5G1^;owV2tAz&a*VPGJvpPv8U^0}HqN(mwg zI)w|8QcVbgox=9N_5Z(l_MhrMgY{D?@l$FjLFmE%8xp&eAn2eRgdiz+WFR;xBa|R$ wDU?(oIH3GQ|G7n(Vo3#pg#Z7H_kUUe0{U-jbj1JX(RwNnLI_%tpJ@&BKS)ee6951J diff --git a/code/+nansen/+internal/+setup/getRequiredMathworksProducts.m b/code/+nansen/+internal/+setup/getRequiredMathworksProducts.m new file mode 100644 index 00000000..24590bd0 --- /dev/null +++ b/code/+nansen/+internal/+setup/getRequiredMathworksProducts.m @@ -0,0 +1,41 @@ +function requiredToolboxNames = getRequiredMathworksProducts(options) +%getRequiredMathworksProducts Get names of required MathWorks toolboxes. +% +% requiredToolboxNames = nansen.internal.setup.getRequiredMathworksProducts() +% returns the names of required MathWorks toolboxes for core NANSEN. +% +% requiredToolboxNames = nansen.internal.setup.getRequiredMathworksProducts(Name, Value) +% accepts additional options for module-aware checking. +% +% Name-Value Arguments: +% ModuleNames (string array) - Module scope IDs to include. +% Default: string.empty (core only). +% RequirementLevel (string) - Filter by level: "all", "required", +% "optional". Default: "required". +% +% Output: +% requiredToolboxNames (string array) - Names of the required +% MathWorks toolboxes. + + arguments + options.ModuleNames (1,:) string = string.empty + options.RequirementLevel (1,1) string ... + {mustBeMember(options.RequirementLevel, ... + ["all", "required", "optional"])} = "required" + end + + requirementLevels = string.empty; + if options.RequirementLevel ~= "all" + requirementLevels = options.RequirementLevel; + end + resolvedRequirements = nansen.internal.dependencies.resolveRequirements( ... + "SelectedModules", options.ModuleNames, ... + "DependencyTypes", "mathworks-product", ... + "RequirementLevels", requirementLevels); + + if isempty(resolvedRequirements) + requiredToolboxNames = string.empty; + else + requiredToolboxNames = [resolvedRequirements.Name]; + end +end diff --git a/code/+nansen/+internal/+setup/getRequiredMatlabToolboxes.m b/code/+nansen/+internal/+setup/getRequiredMatlabToolboxes.m deleted file mode 100644 index b20e6296..00000000 --- a/code/+nansen/+internal/+setup/getRequiredMatlabToolboxes.m +++ /dev/null @@ -1,6 +0,0 @@ -function requiredToolboxes = getRequiredMatlabToolboxes() -%getRequiredMatlabToolboxes - Get names of required Mathworks Toolboxes - filePath = fullfile(nansen.toolboxdir, 'resources', 'requirements.txt'); - requiredToolboxes = strsplit( fileread(filePath), newline); - requiredToolboxes = requiredToolboxes(cellfun(@(c) ~isempty(c), requiredToolboxes)); -end From 8582f14167a58fc22b54109acdfd2b2869308ea0 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 15:58:28 +0100 Subject: [PATCH 09/29] Update checkRequiredMathworksProducts.m Co-Authored-By: Claude Sonnet 4.6 --- .../+setup/checkRequiredMathworksProducts.m | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m b/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m index f1cbfdc2..c0cbeae4 100644 --- a/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m +++ b/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m @@ -1,31 +1,43 @@ -function checkRequiredMathworksProducts(mode) -% checkRequiredMathworksProducts - Checks for required Mathworks products. +function checkRequiredMathworksProducts(mode, options) +%checkRequiredMathworksProducts Check for required MathWorks products. % -% Syntax: -% nansen.internal.setup.checkRequiredMathworksProducts() Checks if the -% required Mathworks products for NANSEN are installed. +% nansen.internal.setup.checkRequiredMathworksProducts() checks if the +% required MathWorks products for core NANSEN are installed. +% +% nansen.internal.setup.checkRequiredMathworksProducts(mode) uses the +% specified mode ("warning" or "error") for reporting missing products. +% +% nansen.internal.setup.checkRequiredMathworksProducts(mode, Name, Value) +% accepts additional options for module-aware checking. +% +% Name-Value Arguments: +% ModuleNames (string array) - Module scope IDs to include in the +% check. Default: string.empty (core only). arguments mode (1,1) string {mustBeMember(mode, ["warning", "error"])} = "warning" + options.ModuleNames (1,:) string = string.empty end - versionInfo = ver(); - installedToolboxNames = {versionInfo.Name}; + % Use the resolver to get missing required MathWorks products + missingProducts = nansen.internal.dependencies.resolveRequirements( ... + "SelectedModules", options.ModuleNames, ... + "DependencyTypes", "mathworks-product", ... + "RequirementLevels", "required", ... + "MissingOnly", true); - requiredToolboxNames = nansen.internal.setup.getRequiredMatlabToolboxes(); + if isempty(missingProducts) + return + end - missingToolboxNames = setdiff(requiredToolboxNames, installedToolboxNames); - missingToolboxNames = string(missingToolboxNames); + missingNames = " - " + [missingProducts.Name]; - if ~isempty(missingToolboxNames) - missingToolboxNames = " - " + missingToolboxNames; - - message = sprintf(... - "The following required Mathworks products are needed for NANSEN " + ... - "to work reliably:\n%s\n\nYou can install these from MATLAB's Add-On Manager.", ... - strjoin(missingToolboxNames, newline)); - - fcn = str2func(mode); - fcn("NANSEN:MathworksProductCheck:MissingRequiredProducts", message) - end + message = sprintf( ... + "The following required MathWorks products are needed for NANSEN " + ... + "to work reliably:\n%s\n\nYou can install these from MATLAB's " + ... + "Add-On Explorer.", ... + strjoin(missingNames, newline)); + + reportFunction = str2func(mode); + reportFunction("NANSEN:MathworksProductCheck:MissingRequiredProducts", message) end From f5e949722cba058725c4d55b272b10ce40e865eb Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 15:59:00 +0100 Subject: [PATCH 10/29] Update requirements-dependencies in update workflow Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/generate-requirements-txt.yml | 4 ++-- tools/+nansentools/generateRequirementsTxt.m | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/generate-requirements-txt.yml b/.github/workflows/generate-requirements-txt.yml index 47739b8c..9eee6818 100644 --- a/.github/workflows/generate-requirements-txt.yml +++ b/.github/workflows/generate-requirements-txt.yml @@ -3,7 +3,7 @@ name: Generate requirements.txt from manifest on: push: paths: - - 'requirements.nansen.json' + - 'code/dependencies.nansen.json' branches: - main - dev @@ -30,7 +30,7 @@ jobs: addpath(genpath('code')); addpath(genpath('tools')); nansentools.generateRequirementsTxt( ... - fullfile(pwd, 'requirements.nansen.json'), ... + fullfile(pwd, 'dependencies.nansen.json'), ... fullfile(pwd, 'requirements.txt')); - name: Check for changes diff --git a/tools/+nansentools/generateRequirementsTxt.m b/tools/+nansentools/generateRequirementsTxt.m index 5470b856..54f34bb3 100644 --- a/tools/+nansentools/generateRequirementsTxt.m +++ b/tools/+nansentools/generateRequirementsTxt.m @@ -2,18 +2,18 @@ function generateRequirementsTxt(manifestFilePath, outputFilePath) %generateRequirementsTxt Generate requirements.txt from a manifest file. % % generateRequirementsTxt(manifestFilePath, outputFilePath) reads a -% requirements.nansen.json manifest and writes a requirements.txt +% dependencies.nansen.json manifest and writes a requirements.txt % containing only community-toolbox entries with their Source URIs. % % MathWorks products are excluded. Entries without a Source field are % skipped with a warning. % % Input: -% manifestFilePath (1,1) string - Path to requirements.nansen.json +% manifestFilePath (1,1) string - Path to dependencies.nansen.json % outputFilePath (1,1) string - Path to write requirements.txt arguments - manifestFilePath (1,1) string {mustBeFile} = fullfile(nansentools.projectdir, 'code', 'requirements.nansen.json') + manifestFilePath (1,1) string {mustBeFile} = fullfile(nansentools.projectdir, 'code', 'dependencies.nansen.json') outputFilePath (1,1) string = fullfile(nansentools.projectdir, 'requirements.txt') end From effd2537b8c1eeb9299ecf7eeb2690ad67a592cc Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 16:00:36 +0100 Subject: [PATCH 11/29] Changed dependency manifest schema, added manifest instances Co-Authored-By: Claude Sonnet 4.6 --- code/dependencies.nansen.json | 158 ++++++++++++++++++ .../+twophoton/dependencies.nansen.json | 149 +++++++++++++++++ schemas/dependencies.nansen.json | 6 +- 3 files changed, 310 insertions(+), 3 deletions(-) create mode 100644 code/dependencies.nansen.json create mode 100644 code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json diff --git a/code/dependencies.nansen.json b/code/dependencies.nansen.json new file mode 100644 index 00000000..97955b94 --- /dev/null +++ b/code/dependencies.nansen.json @@ -0,0 +1,158 @@ +{ + "_schema_id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev/schemas/dependencies.nansen.json", + "_schema_version": "1.0", + "_type": "NANSEN Dependency Manifest", + "scope": "core", + "scopeId": "core", + "dependencies": [ + { + "name": "Image Processing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "required", + "reason": "Needed for basic NANSEN image handling" + }, + { + "name": "Parallel Computing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Enables parallel batch processing of sessions" + }, + { + "name": "Widgets Toolbox - Compatibility Support", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://66235-widgets-toolbox-compatibility-support/1.3.330", + "description": "UI widget components used throughout NANSEN", + "installCheck": "uiw.widget.Table" + }, + { + "name": "Recursively list files and folders", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://160058-recursively-list-files-and-folders", + "description": "Recursive directory listing utility", + "installCheck": "recursiveDir" + }, + { + "name": "Scalebar for images and plots", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://109114-scalebar-for-images-and-plots", + "description": "Adds scalebars to image and plot axes", + "installCheck": "scalebar" + }, + { + "name": "Limit figure size", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://38527-limit-figure-size", + "description": "Constrains figure window dimensions", + "installCheck": "limitFigSize" + }, + { + "name": "cmocean - Perceptually-uniform colormaps", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://57773-cmocean-perceptually-uniform-colormaps", + "description": "Perceptually-uniform colormaps for scientific visualization", + "installCheck": "cmocean" + }, + { + "name": "Spectral and XYZ Color Functions", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://7021-spectral-and-xyz-color-functions", + "description": "Spectral color conversion functions", + "installCheck": "spectrumRGB" + }, + { + "name": "Drag & Drop functionality for Java GUI components", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://53511-drag-drop-functionality-for-java-gui-components", + "description": "Drag and drop support for MATLAB Java-based UIs", + "installCheck": "dndcontrol" + }, + { + "name": "Get structure field names in recursive manner", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://33262-get-structure-field-names-in-recursive-manner", + "description": "Recursively retrieves field names from nested structs", + "installCheck": "fieldnamesr" + }, + { + "name": "plotboxpos", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://9615-plotboxpos", + "description": "Returns the visible position of a plot box", + "installCheck": "plotboxpos" + }, + { + "name": "findjobj - Find java handles of Matlab graphic objects", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://14317-findjobj-find-java-handles-of-matlab-graphic-objects", + "description": "Finds underlying Java objects for MATLAB graphics", + "installCheck": "findjobj" + }, + { + "name": "getjframe - Retrieves a figure's underlying Java frame", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://15830-getjframe-retrieves-a-figure-s-underlying-java-frame", + "description": "Retrieves the Java frame for a MATLAB figure", + "installCheck": "getjframe" + }, + { + "name": "undecorateFig", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://50111-undecoratefig-remove-restore-figure-border-and-title-bar", + "description": "Removes or restores figure border and title bar", + "installCheck": "undecorateFig" + }, + { + "name": "Catalog", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://158241-catalog", + "description": "Collection for unique, named and ordered items", + "installCheck": "PersistentCatalog" + }, + { + "name": "File downloader/uploader with progress monitor", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://118460-file-downloader-uploader-with-progress-monitor", + "description": "Downloads and uploads files with progress indication", + "installCheck": "downloadFile" + }, + { + "name": "MatBox", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "fex://180185-matbox", + "description": "MATLAB package manager for requirements installation", + "installCheck": "matbox.VersionNumber" + }, + { + "name": "Hierarchical Data Tree", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "https://github.com/ehennestad/hierarchical-data-tree-matlab", + "description": "Tree data structure for hierarchical data", + "installCheck": "datatree.model.TreeNodeProvider" + }, + { + "name": "YAML-Matlab", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "https://github.com/ehennestad/yamlmatlab", + "description": "Reading and writing YAML files in MATLAB", + "setupHook": "nansen.internal.setup.addYamlJarToJavaClassPath", + "installCheck": "yaml.WriteYaml" + } + ] +} diff --git a/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json new file mode 100644 index 00000000..1123e2f4 --- /dev/null +++ b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json @@ -0,0 +1,149 @@ +{ + "_schema_id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev/schemas/dependencies.nansen.json", + "_schema_version": "1.0", + "_type": "NANSEN Dependency Manifest", + "scope": "module", + "scopeId": "nansen.module.ophys.twophoton", + "dependencies": [ + { + "name": "Image Processing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "required", + "reason": "Needed for two-photon image processing and ROI analysis" + }, + { + "name": "Signal Processing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Used by some motion correction and signal extraction workflows" + }, + { + "name": "Statistics and Machine Learning Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Used by EXTRACT for signal decontamination" + }, + { + "name": "Parallel Computing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Speeds up motion correction and ROI extraction" + }, + { + "name": "TIFFStack", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "https://github.com/DylanMuir/TIFFStack", + "description": "Virtual TIFF stack for efficient reading of ScanImage TIFF files", + "installCheck": "TIFFStack" + }, + { + "name": "CaImAn-MATLAB", + "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.caiman", + "requirementLevel": "optional", + "source": "https://github.com/flatironinstitute/CaImAn-MATLAB", + "description": "Computational toolbox for large scale calcium imaging data analysis", + "workflowNotes": "Needed only for the CaImAn ROI extraction workflow", + "installCheck": "CNMFSetParms" + }, + { + "name": "Suite2P-MATLAB", + "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.suite2p", + "requirementLevel": "optional", + "source": "https://github.com/cortex-lab/Suite2P", + "description": "Fast, accurate and complete two-photon pipeline", + "workflowNotes": "Needed only for the Suite2P ROI extraction workflow", + "installCheck": "build_ops3" + }, + { + "name": "EXTRACT", + "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.extract", + "requirementLevel": "optional", + "source": "https://github.com/schnitzer-lab/EXTRACT-public", + "description": "Tractable and robust automated cell extraction tool for calcium imaging", + "workflowNotes": "Needed only for the EXTRACT ROI extraction workflow", + "installCheck": "run_extract" + }, + { + "name": "Bioinformatics Toolbox", + "dependencyType": "mathworks-product", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.extract", + "requirementLevel": "required", + "reason": "Required by the EXTRACT algorithm", + "workflowNotes": "Required when using the EXTRACT workflow" + }, + { + "name": "Econometrics Toolbox", + "dependencyType": "mathworks-product", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.extract", + "requirementLevel": "required", + "reason": "Required by the EXTRACT algorithm", + "workflowNotes": "Required when using the EXTRACT workflow" + }, + { + "name": "Wavelet Toolbox", + "dependencyType": "mathworks-product", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.extract", + "requirementLevel": "required", + "reason": "Required by the EXTRACT algorithm", + "workflowNotes": "Required when using the EXTRACT workflow" + }, + { + "name": "NoRMCorre", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "https://github.com/ehennestad/NoRMCorre", + "description": "Non-rigid motion correction for calcium imaging data", + "reason": "Alternative motion correction algorithm", + "installCheck": "normcorre_batch" + }, + { + "name": "Flow Registration", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "https://github.com/phflot/flow_registration", + "description": "Optical flow based motion correction for calcium imaging data", + "reason": "Alternative motion correction algorithm", + "setupHook": "nansen.wrapper.flowreg.install", + "installCheck": "OF_Options" + }, + { + "name": "SEUDO", + "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.seudo", + "requirementLevel": "optional", + "source": "https://github.com/adamshch/SEUDO", + "description": "Calcium signal decontamination", + "workflowNotes": "Needed only for the SEUDO signal decontamination workflow", + "installCheck": "globalSEUDOWrapper" + }, + { + "name": "Neurodata Without Borders", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "https://github.com/ehennestad/matnwb", + "description": "MATLAB interface for reading and writing NWB files", + "reason": "Required for NWB file export", + "installCheck": "nwbRead" + }, + { + "name": "Brain Observatory Toolbox", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "https://github.com/emeyers/Brain-Observatory-Toolbox", + "description": "MATLAB toolbox for interacting with the Allen Brain Observatory", + "reason": "Required for Allen Brain Observatory data access", + "installCheck": "bot.getSessions" + } + ] +} diff --git a/schemas/dependencies.nansen.json b/schemas/dependencies.nansen.json index 474d83c2..b100c8fa 100644 --- a/schemas/dependencies.nansen.json +++ b/schemas/dependencies.nansen.json @@ -1,14 +1,14 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev-claude-standardize-requirements/schemas/dependencies.nansen.json", + "$id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev/schemas/dependencies.nansen.json", "title": "NANSEN Dependency Manifest", "description": "Schema for dependencies.nansen.json files that declare dependencies for NANSEN core and modules.", "type": "object", "required": ["_schema_version", "_type", "scope", "scopeId", "dependencies"], "properties": { - "$schema": { + "_schema_id": { "type": "string", - "description": "URI pointing to the JSON Schema that validates this manifest. Used by editors for inline validation." + "description": "Canonical URI of the schema that validates this manifest. Used for runtime type-checking by MATLAB and Python." }, "_schema_version": { "type": "string", From c558546998e00466e67ece524caf84990f9b20fa Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 20 Mar 2026 16:02:07 +0100 Subject: [PATCH 12/29] Create TestDependencyManagement.m Co-Authored-By: Claude Sonnet 4.6 --- .../+unittest/TestDependencyManagement.m | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 tests/+nansen/+unittest/TestDependencyManagement.m diff --git a/tests/+nansen/+unittest/TestDependencyManagement.m b/tests/+nansen/+unittest/TestDependencyManagement.m new file mode 100644 index 00000000..e24f15cb --- /dev/null +++ b/tests/+nansen/+unittest/TestDependencyManagement.m @@ -0,0 +1,270 @@ +classdef TestDependencyManagement < matlab.unittest.TestCase +%TestDependencyManagement Tests for the dependency manifest system. +% +% Tests the real-world workflows: reading manifests, resolving +% dependencies across scopes, checking installation status, and +% verifying schema/manifest consistency. + + properties (Constant, Access = private) + CoreManifestPath = fullfile(nansen.toolboxdir, 'dependencies.nansen.json') + SchemaPath = fullfile(nansen.toolboxdir, '..', 'schemas', 'dependencies.nansen.json') + end + + % --- Manifest reading --- + + methods (Test) + function readCoreManifest(testCase) + %readCoreManifest Verify the core manifest loads and has expected structure. + testCase.assumeTrue(isfile(testCase.CoreManifestPath), ... + 'Core manifest file not found') + + dependencies = nansen.internal.dependencies.readManifest( ... + testCase.CoreManifestPath); + + testCase.verifyNotEmpty(dependencies, ... + 'Core manifest should contain at least one dependency') + testCase.verifyTrue(isstruct(dependencies), ... + 'readManifest should return a struct array') + + expectedFields = ["Name", "DependencyType", "Scope", "ScopeId", ... + "RequirementLevel", "Source", "DocsSource", "Description", ... + "Reason", "WorkflowNotes", "SetupHook", "StartupHook", ... + "InstallCheck", "VersionConstraint"]; + actualFields = string(fieldnames(dependencies)); + for i = 1:numel(expectedFields) + testCase.verifyTrue(ismember(expectedFields(i), actualFields), ... + sprintf('Missing field: %s', expectedFields(i))) + end + end + + function coreManifestScopeInheritance(testCase) + %coreManifestScopeInheritance Verify scope inherits from manifest level. + testCase.assumeTrue(isfile(testCase.CoreManifestPath)) + + dependencies = nansen.internal.dependencies.readManifest( ... + testCase.CoreManifestPath); + + for i = 1:numel(dependencies) + testCase.verifyEqual(string(dependencies(i).Scope), "core", ... + sprintf('Dependency "%s" should inherit scope "core"', ... + dependencies(i).Name)) + end + end + + function communityToolboxesHaveSource(testCase) + %communityToolboxesHaveSource Every community toolbox must have a source URI. + testCase.assumeTrue(isfile(testCase.CoreManifestPath)) + + dependencies = nansen.internal.dependencies.readManifest( ... + testCase.CoreManifestPath); + + for i = 1:numel(dependencies) + if dependencies(i).DependencyType == "community-toolbox" + testCase.verifyTrue( ... + strlength(dependencies(i).Source) > 0, ... + sprintf('Community toolbox "%s" has no source', ... + dependencies(i).Name)) + end + end + end + + function mathworksProductsHaveNoSource(testCase) + %mathworksProductsHaveNoSource MathWorks products should not have source URIs. + testCase.assumeTrue(isfile(testCase.CoreManifestPath)) + + dependencies = nansen.internal.dependencies.readManifest( ... + testCase.CoreManifestPath); + + for i = 1:numel(dependencies) + if dependencies(i).DependencyType == "mathworks-product" + testCase.verifyEqual(dependencies(i).Source, "", ... + sprintf('MathWorks product "%s" should not have a source URI', ... + dependencies(i).Name)) + end + end + end + end + + % --- Module manifest with scope overrides --- + + methods (Test) + function readModuleManifestWithWorkflowScopes(testCase) + %readModuleManifestWithWorkflowScopes Verify per-entry scope overrides. + moduleManifestPath = fullfile(nansen.toolboxdir, 'modules', ... + '+nansen', '+module', '+ophys', '+twophoton', ... + 'dependencies.nansen.json'); + testCase.assumeTrue(isfile(moduleManifestPath), ... + 'Two-photon module manifest not found') + + dependencies = nansen.internal.dependencies.readManifest( ... + moduleManifestPath); + + % Find a workflow-scoped entry (e.g. EXTRACT) + names = string({dependencies.Name}); + extractIdx = find(names == "EXTRACT", 1); + testCase.assumeNotEmpty(extractIdx, 'EXTRACT dependency not found') + + testCase.verifyEqual(string(dependencies(extractIdx).Scope), "workflow") + testCase.verifyTrue(contains(dependencies(extractIdx).ScopeId, "extract")) + + % Entries without scope override should inherit "module" + iptIdx = find(names == "Image Processing Toolbox", 1); + testCase.assumeNotEmpty(iptIdx) + testCase.verifyEqual(string(dependencies(iptIdx).Scope), "module") + end + end + + % --- Resolve requirements --- + + methods (Test) + function resolveCoreOnly(testCase) + %resolveCoreOnly Resolve core dependencies and verify filtering works. + resolved = nansen.internal.dependencies.resolveRequirements(); + + testCase.verifyNotEmpty(resolved, ... + 'Resolving core dependencies should return results') + + % All should be core scope + scopes = string({resolved.Scope}); + testCase.verifyTrue(all(scopes == "core"), ... + 'Core-only resolution should only contain core-scoped entries') + end + + function filterByDependencyType(testCase) + %filterByDependencyType Verify filtering by mathworks-product. + resolved = nansen.internal.dependencies.resolveRequirements( ... + "DependencyTypes", "mathworks-product"); + + types = string({resolved.DependencyType}); + testCase.verifyTrue(all(types == "mathworks-product"), ... + 'All results should be mathworks-product') + end + + function filterByRequirementLevel(testCase) + %filterByRequirementLevel Verify filtering by required level. + resolved = nansen.internal.dependencies.resolveRequirements( ... + "RequirementLevels", "required"); + + levels = string({resolved.RequirementLevel}); + testCase.verifyTrue(all(levels == "required"), ... + 'All results should be required') + end + + function resolvedHasIsInstalledField(testCase) + %resolvedHasIsInstalledField Verify installation status is annotated. + resolved = nansen.internal.dependencies.resolveRequirements(); + testCase.assumeNotEmpty(resolved) + + testCase.verifyTrue(isfield(resolved, 'IsInstalled'), ... + 'Resolved requirements should have IsInstalled field') + testCase.verifyTrue(islogical([resolved.IsInstalled]), ... + 'IsInstalled should be logical') + end + + function missingOnlyFilter(testCase) + %missingOnlyFilter Verify MissingOnly returns only uninstalled deps. + resolved = nansen.internal.dependencies.resolveRequirements( ... + "MissingOnly", true); + + if isempty(resolved); return; end + + installedFlags = [resolved.IsInstalled]; + testCase.verifyTrue(~any(installedFlags), ... + 'MissingOnly should only return uninstalled dependencies') + end + end + + % --- Check installation status --- + + methods (Test) + function imageProcessingToolboxDetection(testCase) + %imageProcessingToolboxDetection Verify MathWorks product detection works. + entry = struct( ... + 'Name', "Image Processing Toolbox", ... + 'DependencyType', "mathworks-product", ... + 'InstallCheck', ""); + + result = nansen.internal.dependencies.checkInstallationStatus(entry); + + % If IPT is installed, IsInstalled should be true + versionInfo = ver(); + expectedInstalled = any(string({versionInfo.Name}) == "Image Processing Toolbox"); + testCase.verifyEqual(result.IsInstalled, expectedInstalled) + end + + function communityToolboxCheckDetection(testCase) + %communityToolboxCheckDetection Verify InstallCheck-based detection. + % Test with a function we know exists (part of MATLAB itself) + entry = struct( ... + 'Name', "Test Check", ... + 'DependencyType', "community-toolbox", ... + 'InstallCheck', "nansen"); + + result = nansen.internal.dependencies.checkInstallationStatus(entry); + testCase.verifyTrue(result.IsInstalled, ... + '"nansen" should always be found via exist()') + end + + function missingCheckReportsNotInstalled(testCase) + %missingCheckReportsNotInstalled Empty InstallCheck → not installed. + entry = struct( ... + 'Name', "No Check", ... + 'DependencyType', "community-toolbox", ... + 'InstallCheck', ""); + + result = nansen.internal.dependencies.checkInstallationStatus(entry); + testCase.verifyFalse(result.IsInstalled, ... + 'Empty InstallCheck should report not installed') + end + end + + % --- Schema consistency --- + + methods (Test) + function schemaAndManifestConsistency(testCase) + %schemaAndManifestConsistency Verify manifest validates against schema. + testCase.assumeTrue(isfile(testCase.SchemaPath), ... + 'Schema file not found') + testCase.assumeTrue(isfile(testCase.CoreManifestPath), ... + 'Core manifest not found') + + schemaData = jsondecode(fileread(testCase.SchemaPath)); + manifestData = jsondecode(fileread(testCase.CoreManifestPath)); + + % Check that manifest has all required top-level fields + % (jsondecode mangles leading _ to x_, so _schema_id → x_schema_id) + manifestFields = string(fieldnames(manifestData)); + testCase.verifyTrue(ismember("x_schema_id", manifestFields)) + testCase.verifyTrue(ismember("x_schema_version", manifestFields)) + testCase.verifyTrue(ismember("x_type", manifestFields)) + testCase.verifyTrue(ismember("scope", manifestFields)) + testCase.verifyTrue(ismember("scopeId", manifestFields)) + testCase.verifyTrue(ismember("dependencies", manifestFields)) + + % Verify _schema_id matches schema $id + testCase.verifyEqual( ... + string(manifestData.x_schema_id), ... + string(schemaData.x_id), ... + 'Manifest _schema_id should match schema $id') + end + + function camelToPascalMappingRoundTrip(testCase) + %camelToPascalMappingRoundTrip Verify all schema fields map correctly. + testCase.assumeTrue(isfile(testCase.CoreManifestPath)) + + dependencies = nansen.internal.dependencies.readManifest( ... + testCase.CoreManifestPath); + + % These PascalCase fields should exist from camelCase JSON keys + expectedPascalFields = ["Name", "DependencyType", "RequirementLevel", ... + "Source", "Description", "Reason", "SetupHook"]; + actualFields = string(fieldnames(dependencies)); + + for i = 1:numel(expectedPascalFields) + testCase.verifyTrue(ismember(expectedPascalFields(i), actualFields), ... + sprintf('camelToPascal should produce field: %s', ... + expectedPascalFields(i))) + end + end + end +end From 6014c4e713b7b0321a838ecadbabded083198c95 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 21 Mar 2026 10:48:29 +0100 Subject: [PATCH 13/29] Remove getDefaultAddonList - update two-photon dependency manifest Co-Authored-By: Claude Sonnet 4.6 --- .../+config/+addons/getDefaultAddonList.m | 170 ------------------ .../+twophoton/dependencies.nansen.json | 12 +- 2 files changed, 7 insertions(+), 175 deletions(-) delete mode 100644 code/+nansen/+config/+addons/getDefaultAddonList.m diff --git a/code/+nansen/+config/+addons/getDefaultAddonList.m b/code/+nansen/+config/+addons/getDefaultAddonList.m deleted file mode 100644 index c6ffc5ba..00000000 --- a/code/+nansen/+config/+addons/getDefaultAddonList.m +++ /dev/null @@ -1,170 +0,0 @@ -function S = getDefaultAddonList() -%getAddonList Return a list of addons that are needed - -% Name : Name of addon toolbox -% Source : Where to download addon from (FileExchange or GitHub) -% WebUrl : Web Url for addon download -% HasSetupFile : Is there a setup file that should be run? -% SetupName : Name of setup file if there are any -% FunctionName : Name of function in repository (used to check if repository already exists on matlab's path) - -% Todo: Add git commit id, and use it for checking if latest version is -% downloaded... -% Use git instead of downloading zipped versions of repositories... - - i = 1; - - S(i).Name = 'YAML-Matlab'; - S(i).Description = 'Reading in and writing out a yaml file.'; - S(i).IsRequired = true; - S(i).Type = 'General'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/ewiger/yamlmatlab'; - S(i).DownloadUrl = 'https://github.com/ehennestad/yamlmatlab/archive/refs/heads/master.zip'; % Fixed some bugs with original - S(i).HasSetupFile = false; - S(i).SetupFileName = 'nansen.internal.setup.addYamlJarToJavaClassPath'; - S(i).FunctionName = 'yaml.WriteYaml'; - - i = i + 1; - S(i).Name = 'TIFFStack'; - S(i).Description = 'Package for creating virtual tiff stack (Used for ScanImage tiff files).'; - S(i).IsRequired = false; - S(i).Type = 'General'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/DylanMuir/TIFFStack'; - S(i).DownloadUrl = 'https://github.com/DylanMuir/TIFFStack/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'TIFFStack'; - - i = i + 1; - S(i).Name = 'CaImAn-Matlab'; - S(i).Description = 'A Computational toolbox for large scale Calcium Imaging data Analysis'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/flatironinstitute/CaImAn-MATLAB'; - S(i).DownloadUrl = 'https://github.com/flatironinstitute/CaImAn-MATLAB/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'CNMFSetParms'; - i = i + 1; - - S(i).Name = 'suite2P-Matlab'; - S(i).Description = 'Fast, accurate and complete two-photon pipeline'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/cortex-lab/Suite2P'; - S(i).DownloadUrl = 'https://github.com/cortex-lab/Suite2P/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'build_ops3'; - - i = i + 1; - S(i).Name = 'EXTRACT'; - S(i).Description = 'Tractable and Robust Automated Cell extraction Tool for calcium imaging'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/schnitzer-lab/EXTRACT-public'; - S(i).DownloadUrl = 'https://github.com/schnitzer-lab/EXTRACT-public/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'run_extract'; - S(i).RequiredToolboxes = { ... - 'Bioinformatics Toolbox', ... - 'Econometrics Toolbox', ... - 'Image Processing Toolbox', ... - 'Parallel Computing Toolbox', ... - 'Signal Processing Toolbox', ... - 'Statistics and Machine Learning Toolbox', ... - 'Wavelet Toolbox' }; - - i = i + 1; - S(i).Name = 'NoRMCorre'; - S(i).Description = ' Non-Rigid Motion Correction for calcium imaging data'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/flatironinstitute/NoRMCorre'; - %S(i).DownloadUrl = 'https://github.com/flatironinstitute/NoRMCorre/archive/refs/heads/master.zip'; - S(i).DownloadUrl = 'https://github.com/ehennestad/NoRMCorre/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'normcorre_batch'; - - i = i + 1; - S(i).Name = 'Flow Registration'; - S(i).Description = ' Optical Flow based correction for calcium imaging data'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/phflot/flow_registration'; - S(i).DownloadUrl = 'https://github.com/phflot/flow_registration/archive/refs/heads/master.zip'; - S(i).HasSetupFile = true; - S(i).SetupFileName = 'nansen.wrapper.flowreg.install'; %'set_path'; - S(i).FunctionName = 'OF_Options'; - - i = i + 1; - S(i).Name = 'SEUDO'; - S(i).Description = 'Calcium signal decontamination'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/adamshch/SEUDO'; - S(i).DownloadUrl = 'https://github.com/adamshch/SEUDO/archive/refs/heads/master.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'globalSEUDOWrapper.m'; - - i = i + 1; - S(i).Name = 'Neurodata Without Borders'; - S(i).Description = 'A Matlab interface for reading and writing NWB files'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/NeurodataWithoutBorders/matnwb'; - %S(i).DownloadUrl = 'https://github.com/NeurodataWithoutBorders/matnwb/archive/refs/heads/master.zip'; - S(i).DownloadUrl = 'https://github.com/ehennestad/matnwb/archive/refs/heads/master.zip'; - S(i).HasSetupFile = true; - S(i).SetupFileName = ''; - S(i).FunctionName = 'nwbRead.m'; - - i = i + 1; - S(i).Name = 'Brain Observatory Toolbox'; - S(i).Description = 'A MATLAB toolbox for interacting with the Allen Brain Observatory'; - S(i).IsRequired = false; - S(i).Type = 'Neuroscience'; - S(i).Source = 'Github'; - S(i).WebUrl = 'https://github.com/emeyers/Brain-Observatory-Toolbox'; - S(i).DownloadUrl = 'https://github.com/emeyers/Brain-Observatory-Toolbox/archive/refs/heads/main.zip'; - S(i).HasSetupFile = false; - S(i).SetupFileName = ''; - S(i).FunctionName = 'EphysQuickstart.mlx'; - -% % i = i + 1 % Not implemented yet -% % S(i).Name = 'PatchWarp'; -% % S(i).Description = 'Image processing pipeline to correct motion artifacts and complex image distortions in neuronal calcium imaging data.'; -% % S(i).IsRequired = false; -% % S(i).Type = 'Neuroscience'; -% % S(i).Source = 'Github'; -% % S(i).WebUrl = 'https://github.com/ryhattori/PatchWarp'; -% % S(i).DownloadUrl = 'https://github.com/ryhattori/PatchWarp/archive/refs/heads/main.zip'; -% % S(i).HasSetupFile = false; -% % S(i).SetupFileName = ''; -% % S(i).FunctionName = 'patchwarp.m'; - -end - -% % i = i + 1 % Not implemented yet -% % S(i).Name = 'DABEST'; -% % S(i).Description = ''; -% % S(i).IsRequired = false; -% % S(i).Type = 'Statistics'; -% % S(i).Source = 'Github'; -% % S(i).WebUrl = 'https://github.com/ACCLAB/DABEST-Matlab'; -% % S(i).DownloadUrl = 'https://github.com/ACCLAB/DABEST-Matlab/archive/refs/heads/master.zip'; -% % S(i).HasSetupFile = false; -% % S(i).SetupFileName = ''; -% % S(i).FunctionName = 'dabest.m'; diff --git a/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json index 1123e2f4..7eadccc2 100644 --- a/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json +++ b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json @@ -45,7 +45,7 @@ "requirementLevel": "optional", "source": "https://github.com/flatironinstitute/CaImAn-MATLAB", "description": "Computational toolbox for large scale calcium imaging data analysis", - "workflowNotes": "Needed only for the CaImAn ROI extraction workflow", + "workflowNotes": "Needed for the CaImAn ROI extraction workflow", "installCheck": "CNMFSetParms" }, { @@ -56,7 +56,7 @@ "requirementLevel": "optional", "source": "https://github.com/cortex-lab/Suite2P", "description": "Fast, accurate and complete two-photon pipeline", - "workflowNotes": "Needed only for the Suite2P ROI extraction workflow", + "workflowNotes": "Needed for the Suite2P ROI extraction workflow", "installCheck": "build_ops3" }, { @@ -67,7 +67,7 @@ "requirementLevel": "optional", "source": "https://github.com/schnitzer-lab/EXTRACT-public", "description": "Tractable and robust automated cell extraction tool for calcium imaging", - "workflowNotes": "Needed only for the EXTRACT ROI extraction workflow", + "workflowNotes": "Needed for the EXTRACT ROI extraction workflow", "installCheck": "run_extract" }, { @@ -102,8 +102,8 @@ "dependencyType": "community-toolbox", "requirementLevel": "optional", "source": "https://github.com/ehennestad/NoRMCorre", + "docsSource": "https://github.com/flatironinstitute/NoRMCorre" "description": "Non-rigid motion correction for calcium imaging data", - "reason": "Alternative motion correction algorithm", "installCheck": "normcorre_batch" }, { @@ -111,8 +111,8 @@ "dependencyType": "community-toolbox", "requirementLevel": "optional", "source": "https://github.com/phflot/flow_registration", + "docsSource": "https://github.com/phflot/flow_registration" "description": "Optical flow based motion correction for calcium imaging data", - "reason": "Alternative motion correction algorithm", "setupHook": "nansen.wrapper.flowreg.install", "installCheck": "OF_Options" }, @@ -123,6 +123,7 @@ "scopeId": "nansen.module.ophys.twophoton.workflow.seudo", "requirementLevel": "optional", "source": "https://github.com/adamshch/SEUDO", + "docsSource": "https://github.com/adamshch/SEUDO", "description": "Calcium signal decontamination", "workflowNotes": "Needed only for the SEUDO signal decontamination workflow", "installCheck": "globalSEUDOWrapper" @@ -132,6 +133,7 @@ "dependencyType": "community-toolbox", "requirementLevel": "optional", "source": "https://github.com/ehennestad/matnwb", + "docsSource": "https://matnwb.readthedocs.io/en/latest/", "description": "MATLAB interface for reading and writing NWB files", "reason": "Required for NWB file export", "installCheck": "nwbRead" From 4d03d7ea5af1b0c5712d22f8688722e4ea45f5fb Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 21 Mar 2026 10:49:21 +0100 Subject: [PATCH 14/29] Update AddonManager.m Get singleton directly not tied to user session anymore Co-Authored-By: Claude Sonnet 4.6 --- code/shortcuts/+nansen/AddonManager.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/shortcuts/+nansen/AddonManager.m b/code/shortcuts/+nansen/AddonManager.m index 265c1f8f..dc9d6ce1 100644 --- a/code/shortcuts/+nansen/AddonManager.m +++ b/code/shortcuts/+nansen/AddonManager.m @@ -5,8 +5,7 @@ % % See also nansen.config.addons.AddonManager - userSession = nansen.internal.user.NansenUserSession.instance(); - addonManager = userSession.getAddonManager(); + addonManager = nansen.config.addons.AddonManager.instance(); if ~nargout nansen.config.addons.AddonManagerApp(addonManager) From 80025c30fb6d41783883dc1f25c4d3a67da074b1 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 21 Mar 2026 10:54:18 +0100 Subject: [PATCH 15/29] Update NansenUserSession.m Co-Authored-By: Claude Sonnet 4.6 --- .../+user/@NansenUserSession/NansenUserSession.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/code/+nansen/+internal/+user/@NansenUserSession/NansenUserSession.m b/code/+nansen/+internal/+user/@NansenUserSession/NansenUserSession.m index 8492cb5e..69b44ef5 100644 --- a/code/+nansen/+internal/+user/@NansenUserSession/NansenUserSession.m +++ b/code/+nansen/+internal/+user/@NansenUserSession/NansenUserSession.m @@ -89,8 +89,11 @@ function reset() end methods - function am = getAddonManager(obj) - am = obj.AddonManager; + function am = getAddonManager(~) + %getAddonManager Get the AddonManager singleton. + warning("NANSEN:UserSession:DeprecatedMethod", ... + "Deprecated - use nansen.AddonManager() directly") + am = nansen.AddonManager(); end function pm = getProjectManager(obj) @@ -115,7 +118,6 @@ function assertProjectsAvailable(obj) function obj = NansenUserSession(userName, skipProjectCheck) % NansenUserSession - Constructor method - import nansen.config.addons.AddonManager import nansen.config.project.ProjectManager obj.CurrentUserName = userName; obj.SkipProjectCheck = skipProjectCheck; @@ -125,7 +127,7 @@ function assertProjectsAvailable(obj) obj.preStartup() - obj.AddonManager = AddonManager(preferenceDirectory); + obj.AddonManager = nansen.AddonManager(); obj.ProjectManager = ProjectManager.instance(preferenceDirectory, 'reset'); obj.postStartup() From 4d3e9da6ca1d4226815b59c4a4f9b70fc775ef9b Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 21 Mar 2026 11:02:33 +0100 Subject: [PATCH 16/29] Renamed "nansen.internal.setup.getRequiredMathworksProducts" to "nansen.internal.dependencies.getRequiredMathworksProducts" --- code/+nansen/+app/+setup/SetupWizard.mlapp | Bin 141527 -> 141534 bytes .../getRequiredMathworksProducts.m | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename code/+nansen/+internal/{+setup => +dependencies}/getRequiredMathworksProducts.m (88%) diff --git a/code/+nansen/+app/+setup/SetupWizard.mlapp b/code/+nansen/+app/+setup/SetupWizard.mlapp index 5f6b0678064a4addd1dcd83daa37d656e12bb4bc..90fcd786d7953dd289bbe18e844e934f4e62d636 100644 GIT binary patch delta 89385 zcmV((K;XaE(Foqr2(UE+3Gs#aHWDiz|DyoEo%m#Jp{*eIUN}RZ%Y@N=#{@B)Q!<`NkbG zV>EErSDHM-i*C||2wM}Wj%1#MKn_$NLwI|Ci7P)(v8;{4uQXY!Nk#0gnkAlc9KoUB zxq%Ss`R6rTPHE0}ciAi{y$h4kWPaE1RFFzph+L_a97_@_Cht_mmT2X>Nr2Z+9+Bst z1%Fg`)Z^6W-(*GbG)_@K7*pK9$O>gSoQEqj@(E(v(bL2qvBfHymP1P#U^_()DPnwo zN_p)J@gD+p#&xhQhpC{<-7kwG*q}nB(yk*; z9FlDyvt_XdzU9pdfRUJCC$MJ`xJ~04);$ZS<8%@#i_R=w+7&-9A;e0&xAzUhh~7pR zF6V8Nip6=*NRIjyocYX>B)i4aDU~*Vh1+-6R80XU2A?1DIQHIywaFp%Q4eyaE0g!4~0S-SV>yv?(VC31Wws~VNz8XeGhj9FN?fBv z(@H_}Jj?sN*I7wo2n7JIKOCB1jVQBOX3$_)9K2Mr#`B@()yl*%u(<_$0bEXhKDLnX zoT$Pq;MM>$Dmad3bdKj%vb0~LKgDasuJLk~t5^$_&}U4@_kMdOpqKb2 zh$p^<(bw0lCJ3yljlLBMtqHk*0RR?H`tX3t26v1>2Yy5dEKv%lc54&NW`Bn*W*0(y zzj1W!6tf79S@C8#Pxl!N&Ex;yVlo?yRa8!?|7h9wO{v1{6+mr`2TCLthV$_vJD%ya zXi7s{*V4+Mb7>920Tr279tWI4KAyLj#~x{`$hTx@r^_?U(bffuExP%C{EmXOvpXkV zw3?{R2MjOfc=WiSl)Dspf8QYq6hd(Vf9YXF_>AWsM9pFTvip0Ic_JbcE|EGtjE!K}GjGMM*iYQ>g^XcQNqyO#2~{YS50%q2 z4M2{NNaN=biy;0k7kLpbhQ_;;n+S@K# zodVXxKzd@X^g_mA8hq=VWlq~6@*BY+x^XYbS~FWa+|7UQROXn%6VNC5ws;dkKb zQ6M~j&@=EnbB+2_X9cv-xg_#4&xaM0rW(eUW>U`&)>Cyuc)Ll;}kbi| zjR#^i4jmnn@hRiZ;|V!z>a?72n1vOd)7g)I-g#E-v|1?Z0FIVcZUs=Ax#9}2P}$Cg zE(gVUdk1n~BOIf3{l&QN_0}rQMAvu6kd-LC)*~**VCi>H_ z+TAxG%#TEy>L<*aKVtIvXhbIaUJ)(w;<+@L`c+$1riQ3>8F`sauyki_M!>p%)fx4r zq0iKH`kUWb9ns*nP%!w+@vV~PA{p$00NHAhy#E@x#S+8@q5PaifEGkT%A^=|_WV77PlTW8XA7?!rP6W;>U_@%>!_ z$6JWGJMt-c0Fko6UC4_g3=WgsY{#aXWPj(9TPMiorcd zRtaOM%r-Riu=B9lz+2m4;{)FuI531$i%v<%Ed<3uYe8|)a^fG@`q2Ieq}<^sF!K+# zQHKtyg+cnRACZ4#8#0YjJRQ2)BxSr#jEfhGAx{j-{)a3&H*iaTRy=3M)EsZ6E(xSG z#5Blxbc>(^5)UZ`?pD!SV1QlIWpop>Zt^k^OyV1@)?J9*Hp|du_ zai|qtr0b2xmmDf==s0%Uyd-er>!R=k@ocU89D3ICLqi&WwCbt=-O4&Uyti?7*j?p1 zY^!k{cC*Y5+v#VA+icYyR+IeK>=qRrTsex(wTN1mcVffUf-&TS!4(D99bV!W2o1p{ zrUD{N_hKVm?2%1@+rA9qKg8)Vzdm%irqg(S2ZBcBOZTc1D!dJ|h48grfr3c7E<-_N z%`sge=(h2HSxqIJ6o!5ukSZjw4YmFFJ71Ph?*&#)?qVhxx6CLYya>uhcaU}H{uBH zciL_Bmk-IelgrQ>9DK$Kr66aQX` zz~$X7(chcS?z$y`es$h5G2l9Hni%lSTOS5M+szLLSZMphDDEMoIw z+Dhc3ZW8&ZokTv`Mj{{8mdB?7iIP=TV2YNU{z%^PYgY?l97eiy7Wr4WWQJ`eQ##*& z)u~=Ys%+`X0RMV|=BGq48a?oq)^6&kQZ%!|TZ(%VtSkl_tn=RnX!l)J#U-wE~2 zr14f$X}kqbk6SbKxFws4a-9w9qiqc9BZpzl4|MKep!XE-5UlRAEq1`thW$~Doq&tp z%n||j8_!hfSb?iIZI|B)pk90VBbSqZsVduf)fE{w`31rpkH=Z)DQIwE)f88kJSf`x z27L%R`vrZ7ntg&k$hQ8#5PZlN=!5I9xclj^Yvl5N?26w)0?HSuVFqf17(+m8wag#f zdzs%NFr;-{$U(PdzGW22!8XhMfs%fO$BIp52Aw1>a8ak9*KGX-0z`?ti@d0R6Y9t~ zG9fe=peQ2}_mbOXJY8afdvO}G+C8r^^Bc4w!bI+-_u+h-z#z@ILTMGpR7qbw*liXU z>m<5^++%FLwh`NbX2LerhHXcma^nheoCuDNymyQlJrg-G6D$DpeE0DapRqe7c zj*GlMcFUouvSweDbj5G9yt>WETdsZ!iH{daim)vv0j_ePu*=tugUP|V?lFKB4s{GC zr-ytDk5Ai=p`I@sn&RkqSUNazqE|H<1&n=-hJiAGJ8WQhQnC9_JepO1iM3XwWy2Gc zUd>Vg(HJw>S>g z`ZQSU!}4nJMlE-;jg~uqF<0yRUzFo_#9bAbfcw z1-^7#GQ#o%ha{Rq2qwBNV+DoZClS0-OE$?_iWr%iRAPpIGHtqWb;-Huzun94uyEF? zXII(>_J{i}-0lY_hH4RJZ@nb0#xvhc{qgh8QeBoiCxX_@ssU+<0mu8~U<3)a#|`YN zp{SB?W_t3tUqM}A>MVKiGZ5y%8)ihYKOsk_`0Ayj_wrfU60?9?()v@8tFRqYygRPE z4Q6@Qs%qzdJ+r{nQ97QCaFl%BGk5pCm-p;-bQ3QEhs%xkh62#;-V_7J@Cn|Adv&+Q z)iBLc>Y$+o~Ua=?18h2Ap3t?wv&T z-SidnRj;<^j2cG=uBd?;I6}p~EjK7QT5^H`(Z~f#`9=;<%4%wJ!{{qul?KOt`$rvx z-^*-~xl_Iy?~NtS7=G_fVHLdAm!t71Il%1i&SZHe=(ouKo-l0io8Pee5x!2sYfIp+ zN2|qufwC6i+N?SEx@R&3tefW#j@U}>zjZBysQa?cqvAgAtxk*_2lLDlmNJw`cy@;F?6>mk~k_q*&cc!jY1{R6N6e7)wV z<>5rUo;LPhMY*|Vqo&_PnF(VB+EYERE}mo$85}n7_xN8?KI`8^Y-%jx)VhAM<(-!B zX?30DZ*&13R37C7?SKQ`*yU%mh!?40^W>s9E5KRSH>J#ao`0s(jkqBm9S56r)qlNz zhE00O-`CRuTV5DXC5gT~`nqRS7tcw`-enuM_??lF_6{kN&?wi2LLGW-_~rP`M3gw? z{V2#acVYv{G=9(qR=vpBAjmU(RS)Ftl5$3XE9~%{&d4xgS-P+F4ij7Lc(ZbW(#obBdzdmUx0X{Y=X?H6NPb*6*7iSSF zZ3|B-RSS129&RdbZV`VjZV_HSDjqH#0jmGM;Ux?Ae*v$kiv3@M1rG=3n}6`#+#JW; z+T0vr0q}Wh7!JN#LxL9X_{09;>sI({_fmJ-w;U0|k80)JI5^S%omQpUgnxP3iH@=f zKYxOUr^NB$qB_TojN=`&Bm8J)12e}lgNyONS9ZrszfC2i`m}x2)nA2M9D%#U* z7RO{jZpx1-)0BTx?*f8Ne5!mZjdLvuylRX5-2AEwEh~Uxajve%W~YoL@H-818?;efyoczAnD&^N^p*yNj`y zbdZv*JtKG(fKe;0wvu%CsNDmuKR`<+58H*@_L{WoeIOkrYo5#xHo6Z~%!7B}(tioB z3(al%67frMTd?8URC+;yp*T3>Vc9QdOqCS=x25L8gBG##MbtTNX0web=Bjji^KP{K z)0@+K)rNo1b5I2Q0Xhtu)K5G=1O`4(N$mFvDBrEy!DjE4q&D?Z|23WR2{$IjnDI&$ zqc^oH!BLLJGWE_-r8ScAGF?udE=>Msf(DIf^`w2v*9J&|T=$}|%i5o@7XfymY@C_D z0Qr{DaOF(rMg=9z6~Y9^Rb_ON%WkAc;z4n1APaxgjO}4H_04N2_(yebtf8PKyq#2x zsAINo^^u2UF#FTnR9_Mj3~R8DHxw4>M)-W`PV*PYf?>!*^l7!Ge48!XdQq>EO$Zqu z+o*7c8tQ@YK6t)Qf#I>BB0jUL-CoDm{wdOk+jUfKZ*`sJ^@5F9EPXg2)P|%|S`-iU z@x_0!C1Ck=L%7_x&hUJe2HJ#hU3+Wrg?@6#a+mu5Dh^7 zq7mtWbv>PUK=#SS{3R9R_)&WliqR;^ivy9@SQfh$Wi%N{|8mgz%F<_j;Jzp$+c^8*^*7>YmkP_wFYQFQ zm$J0ZtcnEOSghW8PITK0+Vejr-`+;Uq40abT&_jX25h`<@dBSbtKD7y&REg?0x4x0 z8{UWw9K3#9nOptEf79i)M-RU^n_=(EVqBRKa~Z()Az9WzBHs4U`=OaUeJP^tb`yWZ zcas^XnCLCxwNrM}+xuoAKbvk6zfHPtLYC))@@J;|r_@zL3HljZj8wYgYB5UavAw1* zuZfJ*@V`Yr(}x2Wn)lMwQ89jShBPVd2{2esk=& z^UIrS#(SfRLizbEo8;i8C#o;$37iwMxvTYwiR_zK+BTE_Z1Pa(CG$&vGChATJ07D2 z6U}({7BwxFnO5}ABOjAY(jiW=OTWl~V971Vc7nm4P*+ak_VtA;HhXQXJejB+%4h-O zaM#$dDxz$W$G_?k6c3;|&9am?<{{HMcM-w#vqpF^lx?ZN-GKNvkw!DYbBh_rXdK@M zUMTxDZ4N~|U6$tlgu5a*Rx5wA*%qgXh56o6wvTf=nCRy$^tt$JMV&UrM6WTo2pPxu z>nX9MqnFdC=Z3hq{+}ocRCIAZ1|;`|_s@*$t0k{L7I=Es35+|tZiLTPgF)ne6M8fs zzmEl={nK+&VU(1gZzrGFBz{yroswktHj43?WG>~+9!zQfO@@Xg8byDcftwjAm(Xsg zkr^cVdz&Lco``T+Jj(1)?1be8R7qlH&<@^0_>2msw>2T`N~NsCh1dof6^O=OsgpjD zIqF;I9T`PkKUC%A;Rb-?=~i;g+yQ~r1*()BR3Sv}Azdook%HD&)gbK5b4BC?Jn`ZU z{D*xByC7eyhQ6?K7vg`1n#i)~t!HyJ!Kzu`;6{^D3j;U*V2S1{fV|i!CdD#eQqB90 zoKPF?4955bNvgP1uDx81#dWY1-ge#3U78F?rp3Bfmz|2et&e1VQJoGSgbp;&$=u4u z&n(SSJem3JSt#sEo$6I_*2C2B$%UpX@8G7qG@?UL0I%Hlz43plTSkl%H#u%^?xSx5 zP_4t!z(s2&{Lc6Fv*%R38E~1&Ml)K1v-PO&B(OPX6hHFTk|}u|_G-yOrCK7PH~H$! zrT8`VsR8Iw(XKS+P1EM=4g9KxUT8W4l1S$@}F)6`FUirA3y;Dy$>*)kQWXL2<%xb)42-AQO+8 zQcT$)#%!CT>KA0wqY3x}Y{xtQC+qxoWH>k&Y|8LLeM^6U*hWiG*S_UJ8(NWOgz8=_ z?{6$`rjROkilfsk-CcqIWr%L3U=_#4P3r{5mhzGDe74|1i0*MKUi;FPh*?B9Hl%NK zwkt@m^adQ@woCBnvtPK}chgxlTJF9lMa40cZ0EA zQu19U!i#^k!OvcxVaEpQ0K2(>TZlq}tU~U=t6U-QQ)cB;*o|Y#%<&q%K=P46TJK6d zmZdovyLX_t1jANgf9H{Ib-;9}2R3jEL8vS*;Sc>?_tDBw7xvX9Lien&X%{;jW5*2k z$NXqG5OqKGAXJYT^^O0F=(bMm$r%I;l>G3N{9}L5WpwS2raaD6+ZJAkmcI}mPz+v3 z9ZoHS+yO?np!Q8+P%b$l*rY4>j6mbRW~RBP!j3sE2BIeE*%Nxb?RKS zifOhcAa%~0^I7G^1-^GhL&7FHUrF-N?aLoNTZ6^k@BFweCgb>IzNQ}vvxod-WVA91 zv*v$#F&;a-t19-JnZNy7cc#=i=(l|A3VpnUGmZ7I@At!WHN{Rdd-@Z{Y(+|95eB%= zEsL$zIaz3Ay|%uI7XZ2>@B2Ks=HODx@@veT_(jbg5+%d$9;5~~>P`G)WPqi3uUv38s=p%nlenv?6LzG@r8|ueOd+|UTKq-nkNfQzk zrBa&lmUVkm_AGGrEX;HyaC#~X43P+hS(?)joi)s};gvLnds__DwCw2iw~4s-aJ3Nl z9hIP>Uxq=wZYO#A4JktZ1bn*ZU0tP~x?jHI98dRwgOT@h`mcT!YJ;1pK}#BDIwXH- zgYhq)l5mBT@=)IOP4>?ICeQ7)bguV!R=Gd_)E}ZdQ1qkSR#yBo@sVK~QjCq;R9eOp z%H*tXady>lR3GMzbEqGgcF)7KkYXz;$j?nM6(T;1(3 z7BkIg%wk~^FXcPx7!M_FQ8zK zYw0p-p|-vorpPiO&z4mynOROT6#)PB4y(4B)12=sdts+cGpH3~b^uk|NZJ=SB-mmlbBnoK1` zb3F6&4*4&YttM&6&6GCU%VS(b8w-Tnwqg&Zi(EO2MeHz21GIx_48ccxvi)6aHp%Qa zHgf3;fKacun+OCjSw30LtH6K!pwn2P8QTD@#TxLAb3r4k$*Ij$QuGW^lU$~0Kb<%a^YJs=k=sNaT?JcmRx@z{zpSZ11MFw zqc=%Ac}{~+BJ2_ZH%S{gtU$YN;ufBmH|SjK~HoM|3pQmN4wjs1@v%!nw1JdZYB-mxfFjktUlUNS)&|Qj&C(u z%FSd`RLD3Z!hC~`dR?fiywr|ZIR42c(LBD@c3~DpjY(Nf&)rVTm00c6eU|jvlF&U> z0xN_~a&$y*Fvr#vQ&5n)ssx>Ve)ju0SAM`$vvPh=E2^Fla4E+0QCP7}HttSqAKW77 zuWMm;(fuk3_kVxvzw5Fn2f$tspoag0jbg`nVp_R|qoU35IWe@A*@<_)R_mud-Y>TX z&T&o9j7X7Da5;W*z}5l9W4ok>&wHwnS(kV=A|HCyb-~+nV94%c(%-M{Z{?S>XYW$m z`pa)7BJV*jfwJ3uB_a1M84`cCqQqy*is=$i(2>KMMtgt87z1+lsBwGL5SG(ZIj&<_ znQbm`t)=&u$;RCBD*!H-?qYEN!-<0ldcUD?@phcw3Z~d9+-wT~+hRv%CllSZku_Oc zcQydn6(IaBHT*3xg%u^s5?%QA#^O0g{rE(BmgIXF5aSjr_Y_Gr zo;sQen0K{bO_iEqNNF-;9Z4pNcMZ!Cmi&1hfPb}(7$}lOcv|LnZzd-yLnDY6&J`>6 zSNul%e%=5KQCZ+WM#l(b?_d28NYTvcA4hCWZ6SZVXyolM2wmxSKrrpniy37Dpwk?_ zbvXb#Fnyg@nJQ z2(I4tTsxa?xUw9S$oUn&u;)Y3b#+l#Hb#ydKS!s=L=)n{{@8Uh0+Y&aYEH5esp=c2 zss?|dfGY{k>yV!Q-+BiNzZ3}VrlECV`f#S2Bb&!6XqS}crGtiUz2PO-Dm0S2O`Xm1p19N{y{8ZB}h7e(YgFV-58b2VKnw+P{6FD4N zMnUOIVu*RaJRBwbYic^5bdTD?LzLcPZ5ksO&SyKOtI~gc7~Qwh|4*6i(pSrnx8YEaPe9}8J)Q9odRKWnQH=wP{RN@z|;+-`StQ#`R;#T{F%)rTp8v)?vO^u%c504S3<~6`=Wl($S-Ed z)LL_q@o=#CN=pKR9$~>>=a*6t^(Y*O_@$!cp}!!s@=@_GGUtq?LF-q#i~5`QvX-VT z3BR3gQx4oE63t`)3LakWbYzx^)7uF`Z}6vHQybp2w5DC`XV(*T!UlNGE>}v>>=}9APH}l#owXuTxu~K@nB)!MQO=jgh_P=SI5c z-(Qa96XxOpCa}weWPh`TWV2;#dp1^>zr}oPi_9)) z`zc1^vKlN^8tF8<Y-uxk!z0V4^ z3@=0;Iu!BbN$YH=wb}dIaqe^Sw@)7PcN!J7m&>1mK*@eA%lDX6qjEI{*t6;hShwXr z_h~*gbhsP7JN5UOjMRV4-~ay2JenhGAgF$?%C@lu5+UuJX_W}3%Nz2g`}E}&W(S18 zznhZ4TG2*4DoW*YdK;DN<%cQmZ}xTK;)AGW-~DbZ31J;mm@jPBi=a!l0KC&v>Z$eo z`^_c6nsA6-*ee^UgPo^&RnaLHjk7_Zdkpm2I2d-d((glbwT*ui81`Xn^dM)BzSo7H z44>pitkk1IG!%pdoCo3Pxbdy>+}U6Ep}GnxzlzWA;fre%Y<#n_ZYp;Yjn;WNWPR-$ z&K`+ph9&j;$cLJND_Zg*eLFb{v|JPp&viOQRHv55Ds4Aj^lK(z@c*kaONK@+r1AtK zS{p)2OLUxm<4%7RUkG(N1ypH-M{4cd7ShIs(+ZlC4ZV?x{c;Vbv3i^B4oBb53)jge z;l=VoS$#@AadGYX9BhlmDk98-9Z)0b?M3U#aBZ#iVAJ1s0p z;u@<1^0|(%%D1xlFe+9RT>B!*P-ok&ss}yTb72h6-5-Burw{ov53JR&CVDVzhC-X- zT=hJJ{NE&h+#}n*NjV3(44eEzWDFw+>iK7K{PY`J1PA^Iil6>zPAL&%kN4!S9D%k( zH$ZeDHE5(N>fRlF+yi~RjA_Ox(t~V|$&YX^pUicKCch0uKAHJG!9e8bIo0|+X-Ikk zyPOmWvRQv;7(yo{+UjKEFU&u7jW&L5{{!G}5YT{HozGn@?S$zt!4l&1ZsJ7u+DGyP zp?U9$q5SrboNm{Qz6T4#eJK@iFYI3cTCc#;?kx?QJv zF_9Nq#m}elH&8qt0oTbo+;{fZ*M|9$p+ZtB!>)h6Xg#lc4IBbJ!z@RWe(P#61dL~k zQ;#!U0si?GAp!|4T6gO*R}af(Q@dw9US@8Zfd}6*mr8^<15_4H7?*WsJP^#tu8+W$ zejl;zgnM_rw*Dvx*UoPJ!8xSPFRX0&yzretj`}ny15ZrFHU4QGlWsJz8z7u7i6Nwp zGn0QV_TK`|5R{NSFw)oV7}>8Agv^U{yBNUWYC<%ACQNeK^N;*cIpW!qkZVuIt)-~N z*ZTHXt`Tid;!At7HSlbpos~K!xLh!9Jb-d zzt?jx5=-;$v*}LRoet>iWtqlL{I)8#zYun~LWg}sPPD~=26sL{-m z!WQgb$J!pnH6lDGt^McXG$xjggLHp<>g3NTXPPd76kU!zPQ~{|^yk^pgZO!eLBxu6 zx57^!5hD{M%-%Yus)-x&t&X!7$D3#e7mL|9}qQRT}8;+8DP zt~WgV@Mk7U=$3yxzosV{dW~e*2+nn4(wXg_-+J*R{g6w2eIU3NFBs20`!;`7cvfuJ zZgO~&Cc~41 zdLvB*mJTU@wh_dwb`Jx`k}k{lt1_(e@y+{+Ja{ajot1C7s5XXg-k-R1rdVtN;lB|aY_YR{*WlYq-&-fQ7Y$Hgb<#BwVxSa zjP6aW4QOZGSZ1N16`QCqS1$Ilg9DBeB zY`))2`jvkeo2@wQl1m|jz$S~dVZ&I_!s;K^ugIBAC`YhF_jIdrtWRwY>qzu zdfdy=C?9Ob5b(PCHn@L!mwj~NDM@j?ZJ2*O_V5tpW62EZ2=l?dzMKXw|Jn9m6^?l) z1#A?H+*V8*7sGItUM0W<>sM%A<7Hl5>bhjTTQH*kvH7_n*q%(DK(Ck`6;qW8wIiL{ zybkFbzGzAwzP-G6xh*?7KoGMyrNNs{wP(Y`+nQFCdO#A2^0t32e?t3^-(wfly-@9x z`gt?VYF-H%WHaM6gS#5>;$EW%rKp8B-W~M%SX<{X{=)F~`pGzXL9`bA6eKJ#da^HN z-uACBn8NNNK-s$r9B@wJz%RIImiVfd*7vCc1C$C6!Wat2)#Z$6bGriW9KF2Uos&3A;U1x?%eH{(yXV7L{YG^jn`yZ{34zdAszv!l1b8y0Q{2vJ9NoqFoxJD5YqUK zJ(0dj_i+F{4$%-YkK0(0R_3Kuc&IOF$jew2ThTGn-S!Q0Byc8$M(s)2vx80c|m zRF8E|0qG;mk`H=}_T!_GNA0Z5FuZM1JqebcmT6F``n{qJ^ze|hX&JYong)EJ*ueQ# zEXJ#%$~4~l&NbE`d${)VcU`ky&jal-YJJy(R8;?n5IUZ44)VW<3zQT&U=zoyihqy; zK#+e?I9WAKUiktoqg>mPQt2<=3`_7XRbV1>pp{K%<-14bm2ts02+Ol)BCtj^Js=IH zQqBfj&9r>WKAXs%$;-`WJe8ij;(1oNw@m_0X9DR#tNgXX&~?a&p`Iag@3>?hVxO>- z>FD-V0h5{yF}^~U+W^sElnEa#M4gtz$DT=y_x zz*gDOTg!M|E$+Jm{cA5pj4Pe)hPO^*o~&yPD)gtPnjtr^i17)88hl*GkYD+BYJ`wf zp=Oc9dHJaeb&iQ{7$yvj6xMp`ayaeQr`eK+Rk-@F6SD|V;$r%t*-JeroL0e*udJ9JQVd&HPvLWOD$gkJrpJxeS|qu7Y@Fd9Z)!oBW>> zq^vY~`7KL7G46wB9?QaJsRL&SB#fnt32-a~+m4%pY`NtD5o0!6ZaD|ZVyhsvEzg(B zq&`6`MKl|b{C1)qo8CB; z0RL4TsnSLL#}IR-7`Jl7daHl<;_W5w_BYxr#Hi&b^BzLirdDq&^B_kmAKfmBGR~Q- z76yMYcdtPgenK+6^Z=7RYwWDE4zp=@iD=fLf+J(Z)%MwGb}Ul4mKD~5IwF+aFG%9n zsTxOOHyJ?5n$QqBW=y~K%}DK1{UB#euS{Udyl5NFpw~9HMF)RBt-esDy2g&p zzMAAZk-ouu`eO@SsIjrf`LhIIX+OuMKGobFC|`@fX!5rM%+r0tqh00QE0H7#dT(Yw zXx&ho-26YcXvy%xWl@e88!wL~Y(#>Jn(m`u$rzRn2LeOlkII^bQW;vOPy)2Y64MLD zam>+&8JkAujiqF0yQF_b$XVg7vT3c?jA6R7_;{j+T5uoet%K1^z{F?KEs&FsmEPD4 zxI75<=+3(8{HnBKa|&hkO}*2tI?*lAZ33H`!u;-LUHk- z?Ik0my5nb~XYaJT`C7@kJW~rm5ioD`>+m9!<&g zrQ%SoBB!VI)9Zf)z|U$%;YR{o&xgz4p$!+h_veee-5MO3p+BwWMO12AvTIMfP64XZb)^ z`MajJuf2b;JJC61-XD9z{|NQd`#m5yL7Mr4wWb!j>Ci0h0ni}!g_GEI;$nw8nCkdV zc?c@C_m(nbq~n7{F4prnBDpeB?WVcpiKcY!_B*wzcx-uYOm~>dGSRb~>`Mz@+5xPP zGG3&usEjhP&OKBw6H8$xzW)@&bImMB-+uRq6T* zJ-9Q=#0TBMBs02_8k_()GX@0G6`^1H`IPfW@N%+LX^AGpmh0h{WXnyk%HCu;@_%u| zZ$=T51jeO6p3TQY_1|61*m%P3+gL*Y`Wt_j&mAb!z1{a$9d=`*H$>l5Hmtq@2d0vR z9;6U<6@ERHB0HNSnXcxHIhX|1u(<1e62?z1j!dOH%J~JIFJo@TkYTS|5+xghT9kClf!)*J=F=EvIuN>^NC8q0?P{ zuOodZLK``&=Ga^FS)X7lGxw;DP=u0_Neo%rmj>}8#|>GwW|_)+p3>8>#Ik>Tf)Z{I zCCiOieyJcj0>1iD9rcxF^|ANgr!4{S^X+b7p67F4WuObcd=ifxG^tO?+f|I791aw- zLHW0sn_mc5oaG8T!Pm>1>cS3*Ou16L=g4C+%GuiDm^81LJdqOz)oX^Ao9m(~{f}*i` zcj{k}TfV9MRG;Tp@7vvl*@&{%=z)>FsJH^zP~2Z~p6NW7-XKfYI^?^R2QebO&PNA% z`>(8Cfo89(-~S3lxBI)&XwTe$_?&0M0{}n@8h`* zCa3yWh&Gr?*+fnL7vK;kGYBdN%0>i6F z7O~U6UH%@ee;5Lu8@h5J~K^frK~Sh4ELDxg?gYmldw93d@$VT5)@g6W-otPF>-Q5IVDAB;$7>UBL)Y} zO|+~t(I10XDu)O+wq?}shKqW~`(5YX<>W#(=4e(Qoup&NDkWS#G92S-&x-%&A3~V) z3#2IoLAAK9h%qD)h-dlj(6^Iz})2zeQeN4g%1l)mofq!0~70Geujb@_?povt(BY^-$Q578@0b`(=N#3Frl9T6X>V!(iSMa~5=&t_QcH zglUQobAwCLjyUl6jdnKdZhx6pRsuCV>V|XWSOPLhB3s+5-aTg{!Ty_sVMLMJ6Zax{ zfw$QOq8;&>u3wiyo(JihW8Tk9VeFjCh+=ftY6JaO3;PZzj8Q1_87#h}Xb@|GI8iy>eFvSO9ikZ|Q!{m93{ND&ubZOlC zbf^tQoN2u76LL)WH%YffqYCrYE~g)aJ8uttZ{l2k)e!zGQY*3kmqPT{jc1kO6MO! zzZNLf+nOgUXRQyRiz8gqFSmJcuw%e$!go0i!P|!QXEb2fw}ROWA5~vM6Q4~Gzey3% z`sfdTT0PVV%DL`w+nC*wU|r!@i9=zH@|7(F}j%!vJY7L_=|1ddHH= zPL#pazon$_kA&~)6ChEYABG>z7`4jibrs@*MZjzVhQDfWV|f0emmQo4bQz6Zx5*}9 ze@?>YJrwHSzYLzDpGRX}*?(>$Oy*%>#yTZ`(?ZG2{TD?1t{uE^6h(FB=<~}lqhE#r(L^i#D z?0#eu;^=pC0Bx_%C%peZ6MoAO^MB%9jf5P9nCqIF4iS*4g`l_I#}*UZRzJop9XDLO z4e;{90aLyU@Re{T!u4|Ya@Km4*HvVH-6aSxTZ<~P^;u@>gRxD)4_tJ?oVbA5RXu*j zChfw}kA>+mAi90G3iqG|%exSIlue$PKk}zhD&HeW#g{ z?KZPXs!>C_(RDmwI_+M9O+62*P>04<)X0DjdyR98eJ{R`n7+}tJ9{4}%(ac$U*5O46kl-2$jUemaKYcwgGr){S}1S zWjOE5k?K~AmtRO_bGv)tAq<0mU4~@Sl=Vmrwfwc~bSjN&^Qh#fI^JoK?@=MY7L=dg z`L2580_&8YUaV&gXzBgds42VLN+=o`z|P!u_pl17-~t5n-UFJXV^T{FOHunvK`6fA z)O&44(P)bCfAA~J*`LyxZ8?=`U&3zAdJw;@{#LHqRH*WEl_7}CHt3IkUYb6QqvEyb zN%q;r-}QTv;B(^{6NFjb;oItdUdjG!44z5a*?__suH^fE!W7IB*3Y@672& zr)g}bWmcSv!CqK3lKNyx*yY&0YYdwiRqQO}qvMBXB(4yetuB<+2+tVdldXAp5K_T) zm%Gx>>q}zaY+Q)D6JHU3IL{cVdWY(Mm{TMhKLjqdx8oy+mWsC@ibR#*8BO&jx-cvV z0fsvqf_M!QD(y6p7rNiD-RV^H1&~f zikHCN=pJp6;oi@^d1p_uksb{{ZqISG+vO`U5BdHLIYow$?LDGA86nHAG+05)7cK0W z>8B|S9tP>|M-E3tZMO?>MJ>fkZb)#&FJwqlocC9l)&X~a5t`7PhceyauDFXo$W=u= zy?k*r@qtqxMign|{KjSDJ6#5R!OfErxKMDdavKh$MycD%EBv+UHubbe5qx9*)|+-O zj}Ep8vk>T#KrHh%c0%n;Jon3ddkLUR?%mPQsf-@)iqr!n-J0%37T{YlElu&PCY7uRB2nd2s5$(rM|kL}j~rqt z#kBs`d1H2;Zca%dbyOV2Un|DvZgu_vQt}pmNYPbslr9*ghYN!hKDuBC1q2aIIO#w1 z_SQL3{?8Gbb|I4`@KK7;VCKUsp9^1q zlA`%)q^hdDBn|#}G{oGHQDRr1w>9SbxNhpz(=?TE>m~)z3Hnd`s_(T}aPvw;yHR^OxeQB){3*$AUY-Ucv?b$!=eQOzI`7N54NY z=(kV@=1$EHEckX(F^}SmKv>Z24iBV%P5U*T`7-bagmy3*%#QM#e-?ia3)>IVdVQN36%ut-clgvb!eOcIJ#slACZr?*4Z`Yh|>yg;JwR2M}#O@Y!)jxEfMXR)h{Uyy~4Pc`8@MeEWbCXC)M zsvo0|ftf|uzt9o3irCtb5g$W;f&0os4I@{oYW4F{h?s5|XXq3VWVD0WKU_Fl@onSA zBM$A{q7Kka2e1l!w(}-a*``$)k774FP8Xs3`Ir3f=rarh>r(^Q%YXWZ`nlCu*tgXP zY&h_Al&4PR|7f2T92j1KQa(WiGBuuy`yrsz5am(+@Fs!5fs-)L?eg(4gG3*a3p}`BG!5g7MZgh%6ZaQi^LQeT> z4|dUkE{vmf%(pTR?GLwq{|uptb~pe04pH;o9#Lj`a373rhhdzOz>DHnuBvVkx8NKe zPGjm` zydBxW_zy0(9}#ysLe@9EOU?`G7N@xX(-!1Oiz%zy$Z6l9=kah6WGXgqHbuc9T zvMJ*WVS!0;?r!Xd6Ce&qn4Y$su<+z|ZNEdww^AC~Hl}m_$N~9G+M$T0aJYsn?IO_5 zBCErXL}O>mnttPg^PUKJPqHW3Pl-kwZ2aKVsDZBa!ov49HyXo&HN~d;@?Q7#$;pr4 znK4({(L-RrnewH7ruICxoeZii?^C#vCYmV~xb}33*V`o=xUqT-sG_m^SY$n~NcSCK z`lHunOH`folZbF&uS4lq?UzLbJMV~Jr^p(XPrUnDRo{?d7}IaRBib4?U6tsy!|9pk zGdY+>*>ISiX&vL-30fH-yQ{GUU}10XAd1kXf1Z+AT>V*pcr6$<(p@tCYn76JV6^8lVE3h*X%FnfZIsCHN>t~0C1|2p>*A=o+DII8QNNFghKOIGr(5?9 z1h+?@-CJd&EdN=IFLJ3tFsGwEx0Z#s1=1h>z3MUEaW~_?O{*TK7CGygvmf1`Mq4ex zsxsk`ceTYJ7MvagVbxx|R}^E@?Ks{X%(v8L_l`t=9$5TpXYJvscZ+Lz#N^%XoWHFQ z$e#5+`PRseRfn7JF!X|LIsRk^*000csuK2B_Hefn+5};jRYWgwG|m5lAF5e;T(#aU zf!Z%#d=HNR7mNK|$+#_NY<;%->A&D8^41Hjeyi*$yjx?4pT$O@tQAy;%VYoA`n|gk z?ZB&lkhQzw)`jprI}%2J-L{IKbTZYz>DY)rZ-wTXb^pm>IE|~0_1ex*EQ_r{VXzom zUWM+vB=4=nLG%`OdumMrJ9{hZ%&+MLBV!w!M*(t4x?mtF^=+g~cVF4kwGTRsbr5zI z=y_O3gv}&o&XjUK%paDU464j!1y$S+qlRRE6gDMI5=FxPb%56eb`lBPo0C`(BsmOT z3k3^j%D~D<=VYQ9Yh3qYe>5xq(sgq8!1FlGAc@Wz8@G$~70;SI40V$M$Ah1QbGl z1Mm4pMEYNGXtA;4v1Mz#E50ggwXORN$!|#Ik`He{@ge8f^Cd z^C0@>rwTwN(qk_$-nCa&h&CX&6__u7F9gD!LF=d^UQW1k$F=2%!XDK+auGfx>kP7@-1`;5_EcC#1q3 zZTL{}9d8j*FRIWRe^%uZEOG6B)~ane^SU6;pXZL{-G?m>!tjC~@vcE6+D z6t(y*IFiivq>uZ)O!8tty&3M10uM{X{VHN66KN^kJ5eOb7U(p*S~%c;^ZVo@F8U5z z9bS#Q-p418x$OXS*!R2b@57W%H}k&$a=)fM3ng}cY<7H89h*K7Ta-~wlhv{tn>4Bv ziaM44Y*&45po1)|{%U-i0~VJwXW*4aFN_l?C$&%KUaER>bSv^PZCDS&-`kQAy0C9P zi=m%_@NRR5TuvHPPI-NQ8Ch`7=Vj85KlGaqHqQaJb*roLF8>by_x=%c=g#6Ij)euA z@4`bHF=p<@36T%O*_h%*>%T{lmrIexfGEd7PerDDlEo5Hfm}q{(AaZa)vomzNJ|t1 zZ@(+@i6-Z@@ejjTtnb>(tk-Z;l5amr8!)^B;|RV|b(6BPZ)zxi@={W_faw-TisqZ` zPgOGIgZ7iu7y(TDSi9_hhN;Z|@Sd|&>8cvPYmz%W|3FRu6(kS&E6bX48@}~E+zx5@*Jt$4Eh;ei)El2y^6AiKb;E;NMf!KX3KlIP3+U%aHn#-EB zPU2gSSRG{@yO2K4OeRUNBYKTxbkE{3rFI36GGqOEtS6r6G^{zK@jhr|r?phcpSrs7Q4Os>NTaF<0FPj zkPzJ&_xsX+(eO!)x>q}fQ^%9)&>SF0wqqCRL%R2uK=1qI&pz*=D%~;xz@~_5RZqvw z;%6bu$nQy?7GiznJ^~mjDUP_qo-1a(GJIkuqRcB_cdlC40zo*t9VCH0G~i{lGmov^ zrsw}XCX^LAc-#LL&>dIg1UsM^>}lr{FZ{8|^3RlinN5BgIHA3orw*~fdCw(zCLzCF zDqt9NP#c9`0rN1oYAs}F)|((sv88v)$`U_(4&(EX$xl4E+ZpVN@b$rQY1aI$PdZ2f?mv0}^lNDUjjC9{WQYeq{g9!TvX9A_#9c`=7InDd_!E>4DFJ{&`)}6rH zetye;QT_nHl&QB}|4HM+#&V#Yh96gWlh=9HfQp#T*Btp#VV4VIw+wyA|-b1>FF57(3HF)*ZbkZuL#5wt+1IR4)^+P&O0m3s(0xb8<@`R49Ib zjBwVJ5+@;+ZMonDt95@MNlXwBwh_3_1(FX|Xjj)MCp3mXZhV07kLOMfKtvp}VVBSr z*`7Jmr97gZ-Ndj4!H1xVvA-adgr0hYQeZD@{*^U+r{2O{EriDze8c7snCUu4$Q(7j zV&Xe&p|$u(9tABVhDM;?2igMAvV&58fWzxvIn&WRUtHIVgFK-*y^ll`+()UMt`9%k z1rSaam1>L^C??6@cP5Oqd!XM2u~mG3YhEceAI9@e#FO5w0&tucu^Q~8C}j(n2*FbM zRJEA0#)2Bgf*i>XM&7jFRrcnmu1gM!Vr+<~sj7=8)&D;lz5*<&p!=JUE@@GJLZm}d zx&)-9K^hbg6oe%NcG+DT0cj9HDFLNJL^>8EmhO(-C6``$X}*2m_y5f^=lbjJj(6T6C27`j1NP z&I|=pJFlWUcf7|%IDGLSeo0_|^(Li`EkaD%rcC0m4^p^O1jF)4JTm~pDF0nsOEQnJ zZoS7{vU+VWh-vpX2)wp|3IN$)f^oUN%O4;-KHiZ2QmOS$RoR-IfnyeNC&Fgf37uLu9g_H5_o_9E? zU)Mgn<&W1m4>WDaYEq$(C6aQe%>peM9D~BD)P>!xiL(1!7;cE>Qq>|kZ#H(n8`~>9 z8MmHye%`oYqV-B`a@;l0?D$9I$=~slXECcM(IDvxpl!{IksHT;hOM|({91CafE@iQ z`+Dw=*ZqpT*@W4DOgC-p-p(v&IO&}?xw2U%^ZL{RXX$?p5QSKu>dJXpEQr zMv8Kz?nNnk{Ks-ck@7=ipw0BDk zw{MAWM6XL$7Std%0+5Sekfqo+hO&p}QVfts(EzSKY}K@XIGB`V9^_H|Z|6c0Vv#iP z88s0fx>63^2T8*}5c zFC4U>*|M;IeLIY>EBZiEljE|5re0a-n;!X+V$B8uPi@o!B-I zTDw{>Zlfu?&d_R?+c4&=oD+0DnOI!4lj9Q0aT3UXlmm`N=Y*k&_>4~)Z&`K@pwZI+aK@$Z#y!J*Y)A~AbwXE<^6WjuHENZmPV))%M{YJ8nJWv zE0XZ8)5j|UCEee)KqVT1-#|Pi8lV`t!0r-%jc+k>-^^opzFmL}y@@=U`{6I4)~))#twvI8??5jF7ruUz z6$a+Su53oH-5qLjA!mIL7AzK4f3G5c=H&el0U=CB4v!ak&ReN^9bkjANKeT#k-zmA ziL>Trn-BGvhez>#0`Ze>#ikuhw&sdX^aT{k^f_JZg70+)UW2s=zYfqRr+si>1u#Q6 zg@*{A=Ws{fcXRk6U*@(hPIn&YYk$xcy<$}8;@LP~oaAcJJGc1v8!L6gZhN4A;y0Pq z2Y9+iFO}&9!gYScO|h)dZhefHy#?M6L(mu~Srbs6_d7%8OPsX?AH=v_OPAtRW@EL# z`h1sTHs~EY zJIrdi^74eNw!<8pM3F|BNy(DUztOT8+VWLq>L4Ux$_O z>lrI1$MEm)`)4~PG!Pwsyv^SK`>bK<6VtZd0X0bH^HHl&O%@)0zF(j45J<+_gY;Y4 zulASpFTX66^}m&=R<0f}G5byF52e7r++kbij1yp{7<%=XR0mbu`%gWi@N`*3G^!;- z$8yEnjmZpE*Xt3B>?f8U5KEq!+8}x*KvMQ&Pb+Q8|l&@%5 zKlzirW_lpZ^dwC-ty~bj!`8I54NR4kE!~hHlMNu9n23D$wY7GEo!X1}Gky5CFi@yB z@itmsPlMK7rM{Lh8xzC#N)*y)S%ph z%+kgxuO{h^uJ5dW?@cup^L5ok?=lWBM|44O)b869Y*sQG< zd-KhMa+n!}lODVe!ZVC~2<)mMf9xExXu=!$mxSB{4L+heuO-HOG0Gv>&1NK%TN-=xWa}h4{if%qkvKhLjE(n?FYfTY~;7I>t@m$ zMAHiD)N-V}WN#e5BJ?O8d>|()Qcpe7`P3~YA;C;hNq1B`E@EcM^2$p8(!D@TYnwoV zC~#!_(fxOSp1ylAEQVj5atgh~oTN-F9_)~Z2ddin=ReF-s`Pl=&=kTnou=iaU9@lO z?*(NFKhq@EG{Sbqc_!wxg!nqI4#fuYx{%>l)46GHm(GDq2EH|Y;BS*D_3DIal~Q|9 zwUtQNMok2O^_4~pIMnbdr6TFv6Jw6EXrt~o0GDllj919Y3n@EOv1YC1=6lBXYF^oG zCYJ@!Jv7rJ3aqGkwI#PU;>s}tOHh5GhTe927-b!RR0vmUTFma4Yr{r5 z?Z49O)R?yKT-4~~4KaVV7A5`h6c9{CNiGI|GES(h_^2dR3MB|lb(g0ZSg54_jzr9(o-$na_YW9XIXZS!#?#YOI@-V9nT7> zAd%$J77%N@6lp&>R$Wqy+6BWESH=?_NW?5^(h=5zWc4|vt*tb%qo>_-=3sAyT5Wi3 zoptw-4v-BDi)AkGF$kBC&&GPW)_8tcT*1F($lUw&|V=3Kf93o18 zBTF4#JsfTO@%X;tHz_eA?CFGc+-2?Hz0c40ISS_a2hIM9i;Ww`QluxpD(2}VNaoq( zwi6zE*XK+&EHj;)<0x81w)tF8IHv2qNlAqMPx70;&IejnZ%!kadBRnw2j8&hxfK7Y z=*)1O;+ntsQ^_M9c18E(=ZWG|%C9MZ`b<vvLLBd!Gze_1iMLjy36aK8fW^l2p8D_2eVLK+$7UAMFsqqbAp^=^ zC`!bh76gMn!X^xolra<;D3 zTW0kQ4N1gyXox;oz3K9Io|%vFQ(p6&&QG)gwgTcGEoDZY7Jywt6&VnUx&XQ&BtFyC zJNYTT$3t~x!pGLr5K;AJ#&+bVvkE*!$KBI=2LV6WH09eKoghQbTJeJD=Z*31Naty| zZd9mIxoTHB&)RZ{4n%+4DCXaPNsMF5NN@GI?-rtOuX=Ae2+j>hZ+qvF4q>+rd9Cz) zcS_@TBigqPwAYv)iN_$B{5!sJEE2Eh;#xEX)-?60is(Rp6G^%?3S(@)RiDh=3IJ78 zsWdnAV_-8gn{#t+w}3SmMfuGg-<=(|^#_8xk&oZ3&s(4GnMA-|$~#_vUy%mz{Bz*6 z{(u#%o!!6E;hjEyGNycgnKmfCVi^0duj_n=n?4a8{vsCc8~(9-wNXdHg6lf!N9$kB z5xp0&H)n7D(5|YeNjo;zYxCCa9P59;GLAFuH0n!KFD0hDjJtc#*L8a>i>t>%hqos< z%-QkUo%`4^A~@T5;*;mN`w1opCN<@}EPufhjEdk3CJ;%(~Ej@L82nsKoICi*nv?uh52 zXAbZF>*tq$d;8^;Im0KIk|ZVMBPG@N($MGW=&;bG3VwgS&lR(d z0r|y1nyc2~!*4q@(>~Mlv62|2D-bpYyzd35vK5(m8l&47e0O4yuSGYNht|==*1C0hWSh8YB z*OMeo*w^Cd$^=h;#&lj9{`--bOmbR%)T_?H$F##D3YeBuWoMmvQQiBE8{oq`5Pqzv zA?#DwpPBXk2nCc$BRSnV`qB1Hu^1qdC^%Z5M6xqyB0N0us(-nm?kkDhLbS$kT|cMm zC&k`51L6JSy>7=lwlAGmZ{gf7u3r9hv3~pItkZI)>?ccqxN7~)spXpc!n2mTS8o1j z(bf2@&jc8PjF5Wlli05$r&c&kiHgM-A)5WNxg%7=8GY~t*lv79iDSc_D%5V{l-V*Gt3x^?FKnk-(B=C-}tH0 z4M@ly<9b&6IHtSt=(y2{eUiB^{4x^PD@*oC(G-$@)7bS6KielX!<{D8vUlnHQOCh0 zioK05g?&UUsO1K5l`}ee-&Qfi-c*@T&m3-ZzjF4fq>V){)b_v0p6Ls3n~Ci{MEqd& z@%%y}CljMFJk-yLW&$PomRYVX7UIO|Bys`K-OwOcx&hyH?1CNc64fgfBe`g{2XI}o z2N}VC4A~daLTeq~OQKBJPC{JM!~2)p0{LUiS+b(KSFTm^S%>cmj(%XA9Fvb5e0o7@ z>}!ewOmc<-QCUUns>70w-YSZjUH!Hfejo$($=r03Q|2{Q=r6@$7(dOnXkYl%n>0n) z%Jl9P`L-uaSFlpn{ivA~%hV2#o$&C&Bc1Yp;o>`ekWnyhz>&BCpE~++n}9o4h-P>J ze1uYL!L@3N1lOWVBla~2HAQcz+}}#WGU}W*CIi=CG!EV*xU95TeuciC5MZEDn_-;|=O zctuB*H}eeioCd0{AOB-U8e0fp^9AgGm(lqG&Z^w^hd{-y`yIEZLrTR_jRJk6kG_MA z0M7dz@|}qCTw_CeUnZ=FsV~zNz%i%u1}Qv7?CSMBv*w)rPb7#MYpCZ-b6F?hdWbog z-jG}SD~^3!R3R68)tC*UmfIUr>fL%h?5M;xjN{uNfQ%U-GPDM&`A>ui{V+y8^Y5QGm24JK^yFACo-uA2d6r@wDG=gN3ws&nBVm`{sB=3N^UJvda`dl&G#ROo)a9mDO=)= zsY^zPj4x;fMrmUnY-O9N0}=iSCnCuJi_;ROA-x8brZPJ&G?G9a9E5;>E&R&zrY#Dt z+-2MJI(10GVuFb-TN7{XGO!r@yjFe;=A_dQh*=PFtW0bfCt7I#^GBH|+5W+nhFcWO z=Cj|3@bDFqDzB9rGjjAy1{x$fbfr*W=D;+?loOyaR!i;{2DO4%*Bmg?2w-^r`|w~5|n*SS5( zIqGk+!MYUXK#cQVb9*!vpt9AWfPnoPS7!^Kr1qnHr7$V}V(*|bxOjdUbM*$NlDn1W zpPa;#BQ^o0EP;YaYFDj5!-yKLR=$6hF1mo6V~p(<#`#H%V^H9#9V?cq2VyQevJHaJn=Sw+27IW^?gBpMKhz0 zS0B{OUfgf~U)c8^wnDeS_OIbk_vyfLzYHZ;m;Gk2%ZM_1m?XrFV;D}{ve&zi4YILw zg@q>ya*!MbF>{cANbYa1-tSq0u=Y1JCsxOS&t>Dh4LPDD_t#fRds?BaTLt(j!K;+) zfP;JCd=DXCIF zn}!=5KkAe4e5f`yw)rxgfip z7t_jT>(|;GSK@`By^)L!KRl=JGof)aXW~6^0KXTI3WMnI%?R1(|3RG8YP5lL#I`e6 zv4OPah2I~tlmOn5E1S!V9`tA<+&4&wgD>McCQjih!*hR`(sx(~vd7PD{pI?MIB~_7 z-@@srHVejo5;;%*bSdojCqU#jTAE=SzI{iajP~SUmIw-|mxzi5-WhW+O9qjb-W5S@ z|DDTmPz=_li}ONXUA}vlAmz9?t3{s*=y&qi=5jq^Y*Cufl1v2*qX8QQk$v@R*Bi># z-;kxxeBGS9(mFh-JmIS!IvOq6ZM2SNc_ZO|dMqLXxP70VLUHCH4!w!_TbqC+j^K-sPhE zF=`G!-Mg5#9v*7Qi?nIOyP3Bd&Y!R`JN#T-iT&8J*rt748oC{^;Q}qoaCvvjCs}x5 za})7@Oufb6&C8Y-l3jYZBo2grvaIlbm!mHICcr=WQk%~dn$;njxTeJO@)RZ9V@5OV z^78cgM~zby>wlQHIOat2KZMmh(QNTx%kdC1Dpmn0kB{h=))bw5BHnnN;$zA%ECurdCR_9(Yfw~IG@ zsm*eIjcs#}e_UqKOrd`nK}ABgQ{8@V9{Ut4SA}f*a+>8@sGT;FmX4JD-o5-8)V>W6 zHw)JLaoPN^6!y#L#*T0bS&IXbDdZ_X?AG)7GC05~`zG@~Qgkt)A!wO8;wn-hSs&(q z#f)|YEzEU|15UoOmpZE;m%7IW1xSp?vyevdBK{a&o{ZH;`!Cv`P)SE%gOiWUu9eWIno8 z7_Hrp(pGfXM?V=3j_5kRtGY6n$zSz0&K~pO{9_4nu%st z(He*M0p>A$dKX!u_itT}c+4_QZ7nlR?JP4vMe|u3Vc-2-9Gyy%Lz}pUNaTrkyHS{TDV_^&-FW8gR)Y@Ja zG}w8=%v>3zls(-UWPmKPE<(DHG<~=!jf_1m`zo?)QDH0X_iH?@r$8`&MQee9eNSSg z8WN)@uX$uC7pYYg2b}!U>old!UiRz2Qi+Q_TW@VlDn+ZFfqhAGWvt)@d+QU>iNW$1 z9~V3Ho7Qeqb+D46<8(aXIo6|<&3Sw8wJ9JfBT!*-a^X!Of?DR(Kcb|bE4>==e;aLn zBT8b>V)ztb??sjq@jRq|fr6TBf4{P0NiOSNK)_4{_k9A+{r`r`%6*U1dQ-`On#saH zW_v1kXQ%zmx0k_#ewxBesg~0)orBcnqISc`To=Ry{A1k6@9KF$#uMwloEhV-555xU zSJDoe9Oei1=6lu_Z<8+q1*ZAr5H$Wq?3UAyq4#-z#vyuX<{LI8<DF@<}A)_+5Pgz zd*;NMm>&{d5UsSl4TTcQPOKFTN9@eInL!3U&fSCk{!m#@HC=YpHW-@WhkeNW~jIDIe#qr|C@g|plXwUJS`$q8^9EjiSQu#(T zj``1puQ|EXwdJGSqCaf8wVjX+>)j|7JQ#gYdg};8)IDye_Wn*S=}zr~o!WalwG2D8 zlsmPoJGD=!rrm#4%qWA~5Chv5hsZsG^Kfa`a9xdK1#WTrl`Ck`J=Xyd@2kLi?tS-- zaoWrpL%NH9xo}L)3`7x`y6)+hvRFa3?CJ5j!3N!Uxe96(SF;Bkz5VF-2)RpyK4nU? z-l#8~l!j5swXw;y5z4hma>D~S;Q?H5>=Ss^!8$Pb5p0}d_ypR!UY68t!4+Gj%7nqb z6+aG06b+_%t>O@S1G#^7A-{`OpB;&+&aHw6DW?#BUtJKV`G~_u;%Uzt`+RS1T}07A z!4$HMj9H7s2A)`NI@eX|-`>o#4GRN}aO7$udvFyx@EV%4bBG03!c|a>?01hX1ABdy zZr^yFk~Rb~*eY!hVb3M}d0Yc7Wx=djO8CP$_goD_Yl=GNB>(fv-I?t}ud^0itJdK^ z=&Is>!8*BbzUbNWGC^N)<&o<*&_OsR8S0YPdiGTG(7q%!9=6AGRtyv^Wf_kZq2AI+ z|G_-fU&!q7NAA>b*yUKCd*|UDwatf?U&?cCZP^V<6ZSXK$JyMq&|MND{U-Xo>F~$H)M;|% zDUOpc!!60YQ?gG8DvL7eZjIYQl7_+**?ec#0>Na@TU_5kO z9Bw7o_pRoL4w7rE8YZV;wb!T45Io%#_(A zp2H+E%psW+9q}rO!zbQ8w6Z0n27;lf{ivVhvL)mOrJPe|3!6 zJSq|hbf(8RGv)u?CNP{}^ApZ4$j}dZ^F(^{Dtq%hd-L{t^Voaya(eUZ-zTZJb_XQT z<~f`)W;tm`_)?w}-)_R4)iu@c_6@n24f#dsxf%EIqwIgt*F-$OqL!?_Ctl;b|*><$*L=i#{>Hw0*(sK$@yWp9CN|9#a2J-iUJp*!(g@ zp}v)Mcj$9F;=^wllHDO9@Uhx#Ce0aBNUO$cfcL$#uOY3!UISQWZK%&)g|w!<1~AUr zP@PSOwAQ``*pY%&(RCEi>k5+KN9{<>gL<-S58_~(I9Tw1|Hc~3Ao<9DV9xM~&o`aP znw3+~nsRgvJo#tJ#Y5g|Kh{SgEjgfw1LBS3e{+Kc5xyB(6aZ&- zt}Ke3S^?r|p+rI*#mY1g=ZNWYO*Ubc5SHQaCvz8Awea%d zXez`qvIgW>uF1ISNB%mPB4~KN|6bFeN@5xGCxZU%vr}>8D17K42Lave z`bI*b0#|%-4%)~&P}D=og~Ko+t0D`HqO2j%WujST`v~YV4-P&-ml<&o30;0oxl0k{ z%t3l__I)QjzaLE z5Jf12D++-|A(&B!bQHn@g_wDWRl8!o#O4gZ0PQe92Mp5=!*swn+F=|Wu-tZ7u2VbA zVfXWm=l8+8HBjCneM`OeO7Nkxe3z^CH6Uj&;#_zc(&j=zqSSsVZE-uzi@DTXE052! zW*(hv68vs|ZNcbfSF7u`WYSo~gsgcfn=IHfDk+?PF3xI5Z@_sPJe475*C4R9<1GIB zee3nqZ~NQAl62VdPmvZ20!33gF9|Ot)a8+UaIad%#$nxOf=P*T3y8vy*7?;n2N(x9Gc?LbnC7PUXiX!?C!r_Z zw=WlCj0Tlk_*zym{kDJlrq#M5u=dlb8{y6r({z~~W%kvxt%4a%U_bIs z?K~rY1!Co?2obFY1tHshCIri{nIhubX3Qz`gUea_RVR{M$S%LKbe&l)m==VsVKzOv z*=79h*J?5`;yHFw6Zt);j`VVF1xFR5Bm3hgHQ>D5C6b%npiNgAv+)t);FmX>j+)=3{6}qTD2RYN}$}Qi_f<|ENkKfGNH#Z%~=?}Lz~{KtmRiGu0&AnY??*Q zZ3xQW1WgF-11Wn=Qn7$jYjRG*1E)E*=kSVM3G;HO!UClqY|q^f6_DBFAr*L8xUYYWYS4D;$$PAggnRK}c|5 zz8iWC@%7uIg0h?Ywoad=&(MU-(1gu@(1gy=gwGsz>=2<&)eZuUDSXF`j1-oO^0U)Dedd;-7j9|=EF9Kauu4s&fp&G8-x(EhW+!%?2y9KDvf*}}!JNWz+@1JLU4^OZ(1~(U zfe9f;eF6jxtASvx!@|{19c?7XVy$GDTO<4^#`LV}8Cv7~>NeNQZDQtTAZPmt3-~rXZ=e93ea=_{A zBiJW2mbvw-AE=@JNlR7ApcUM=^t1g))AvoP^0HV&ZxgX%QNpZDb!*|~P`P^yqQ9wa z)1&-R`}apNb*l@O8z0bra)cU~=&tkMrv}sE8W=~V7bl+66E84tmR_9LPpfNSoR-W^ zf~L3fX?_pihbH;)mb*T9r?)Zr_3kOHOmI{Ptg{_Si^A|91W=wUP+w=`-5M0)1s4IS zehGIYx3nEMhVgt|3B>}aGZbhB?eI2kr^T=|Vy=8#QH@zYGh&T@95@K>^<2#3JNQL1Alp1=lqN{-yxQ<6rI(2LLY|9%36)IQhe<3RIs{R$3L zKi9`@-l6v#C8`p6`pT8OSKh24nx(uecHjJq@n+PID|2(Sf2DGS7-l`7Ntdey z4U>-1q)d{6_O+{3dd`gVcT!4qPAwCeZYU!MwBD;L_rE*m*IUj)4;cFdnTeegRcWs<#EusUjwO_%`lfAuPiaGKP%oAMnPfz-nqBb|+#M6%4Sr0D!hoP=yxL$s*9 zu{d;6u?XO%?E(dJnJAe#=`N~EaZagA@l2`zN-Zs8SwpJ7P1(--^CQZQ`m|0XguRsK z#At3*y*7-!RO-aY11G0YGE>;hn^&iq!VfG?7*+TCJfUv&f3-Q$ZDXrIo-o)h1XkJZ zAcMj%qA=ztj1;O0OnxvEz6b>y>JHk9zOD?w+qlH@h2p%_cH3Yo-zq|10G=-Z-WUcjx7Ka-nk2%jFZD-1EsI+}tqav^V9n&sA+H#6|TM2BI&~S%by%7^|@^DA@l5hRc7pb|^%Z z=n&PlD)Z-DPdE)8Oqv7_K3Ur*cf5`pe;*R{{My3}d$q5@dS_|MS z8u^r^OyYBCYiI!AKLf4hBGKvzw}eMWxk>5F&+Y9u`v$(Q55r;LqeF+^Fy@Y1d&(;? z*)HbSZ&*5xp}qoZkndvBaxP(lcrs;qw^eVHo^LE1(`6G)6A0~uq@A|+6H^I23QZeo z@BfN-e;O<_dFNqtSFe79#6Jz@o4m7YpY|-i1BcYKw$CY}J_NU4!umQF@KJk@5By1i z3Y0Bu_=p4o06e6ARiJ%=j0V6*c;HVCRA583fQTO`P{d^u_6)lZXEM*;isJpB@$H3s zet(il0#E1^@g%**-!&nkAjJo(5;gOi2s3QifBgz45(raMqi0}zaUYCn#TnihyN+XC z^iU9H$n)rIX!u;BrsfWj_4G~wxvzwNC6|!OyHNKLzV&NfJYmAY@B1dc!Jfmn4}|8- z{nFY_548sgrl>ST&9X%Tlij!itKEbGYqlxJ!p&Vj+vm&co!p;9Ycbv;DgM)k!MpN-GXiT$30~@vp#<F&$q;8aRc!+Lq&rtXv)bdcXz28$n$1k>XqI+n z`{xxeorKC_SZg~H zfvRFVcc;0P4}m2Jv^(&DKKaZUPOL)LflWOx99=ihgCvycS8L1w$sTpv+HL5^e=e0d z;Mc4ZP`{R_KOAg;qE#h*;bvozvN){5D8=<@!fGOBL?T}9rQ_E!<@rslX_ZaID)eoO z=BZ8(G}wTtRqgbB{>;jvUul6NWAE35yGK*6>L}w}w@>Buo-_5-_;G+#e8h6f4zIK! z>^+aRfXpl-@K*8zTaD4~QJ&FXe}UPRymA~@Bq!b>iHV+^7n?ah6T=BEWoO}VPRPgDG&ZxD3Idu~TPNsF4D`kn?2NTAU2R+W4Q*Sx5azGT&A(ZZk!}!Xw*x!N zP|QD^?A5RKfH$=<>mK?9Ep|kRY2Nk)`2&9`U^8(`1$KGQ`oNzJf4G2$kjBZWP#*Na zX4)1HVt`Hife>d3~(sO!bz=7!E!WkM>8@(1RN9GBT+UIT7PaGI~E#8u^m8Dgjve+@Z zc{sTnE20K|gKUpvFFFfbC-v z+74k=pJA3XO5I^O{xF=moWYgBMeag07#1cM8aC}Ce^qstS>O6{*uA zZ|h2%orDK;muWklT0N|mGyt!c2KvF~E6Mko!Z!&N&$Mr|vm7i}{5O@>KG52I*J4dn zJCM2N2m{hK0;F!$jicfHe&UIa_eDi6rsQDvy7Y8gh~YBrt{xGt^VESPoBBUw2B2>9 zpz40be?r}IWq4tSt3f)DFkvL*{N-3PXpoNWQW>osM28LtzpkV++yE+e(R1hgJA4)s zX>UbmxDNc&HL~7UD?SML4!^K_dNCvy9KZQN0kgeUo(6PJsG?sA^=sNpD4&Vl|FAPh z+WPXM*rQjAjf%rh&YoOZh&rc?a`VrRflv`qe{6~C)$!Qqs1{dzVnhgp`|>2&bF(0( zM{6Pk^6Yqvt8-MVutzI41mb*glI*m}WwBcD_PMh4#mQLDsFqE9qCft{J5gmvD(J`0 zDD|1#f2Vl^>&NONa@vj-ULSsMij+r1x22pKjoDez&@aWGdW~6BvvXd$O>=2DbOwI; ze-$|RZq(^{B9Ri#e;B2IZg@|r&!p8&qN_-I*E;A^DMbGZcBb)?`%GjPJPXfa2P)lR zY{z7N8$`11{xZNcCHqRe2yo37Xo{-1^e~*B^U58j!*n0Aj>%LHGcJ)_dO28d>_3%% zHUs4@;y?@2Eg^@Ucz%-nwto`%c;{C>e@QihCs1ssEkEkFy+|PcPEdYS^}cAJ><)gu z)^B#wks5-N#_x}35dJ~bS_DxAA)RCG%MVaq!d|k}vaB?$2GIo6d`+@h&Y9IREVG&a z0`b?f5<4?PJ8eQbZ9+Rs9#R+KM@@uwersPArePf>rbgpM`G$5bgmf;1c7ocMe<3I@ ze6NQ4vbOhFMb3JcDVd}6LOOr7FH4}jP^;FCupabF&c`;9X>?bogqa@~l{Ri<#47-@;wDnBIHeWy$A@wz?m@io* zy9eM7B~~Pbx2tG|`Z6}Gks(NQe>PncQ_Bu$8)-FK;E*Waqfz$=zUOvTfa83p{EKo_s86qTiqVE39H}b>6K`MC7>!_6 zm5?;2*K)<^5u6Nv`y$q8#33y3_76PpHli#CMsT`pUQAP^3I(!lcRn)We?UZBdf{z% z+8E=KUjtDG{-cC|sF3;qN)VVC2&MsoIe=HsYrdY}pQhu$2j}8}qm+IJ+?!P(--Y5L z@h+5l7mB|NCEJA(?Lw(`p@h3^vF$l;*U=a!=3saz3=j&#guv+Akvb?07=mr3G%I8G6@r5s&xLe9!z@j%8M(S0yiKmt9(OzF;NVHO z1MAJ*bz0#ydW+fU{P={TZviAGdCntwj1|GC<@6y9`vwr9YQaUOq6aPk<{?dbDv);;h z6i}mcc=UfZ?zjIfFf-rV@GK_#K|ubW1!i*X)cofmqnt@WTRE0jThrx*#+P}-Z?TjbDdMRA3; ziz`Me6gu-rfB#TCnrHLD%1Hwqdg-)9erchv%YC#c>TK)f;k_=fTMO|yo!#Q)$5!5G zhtk9OXNB^zucm-c8ov9`1yy~nv+mj%L+g^AxXH!463H^beda%pp(8J5=YA#Hu|jqq za&k1kNt*gQ^`bnT5$LeH{~oX>$(U7ao8HswK7j|le|(p#iE8VQ@6hSb?CASyHNdc5 zcp{U@nNxbWfeQU_vaygXedS@YF}Q$g+Yk?u9T&Nf8_9s< zzIvjy1+^m&V}|p(2UjV`dLC7<(VP9JJlL<1e<;N28p6j1K-7qh2nQRcfQ9;6i~3q! z)w}?VjrHFb!Cx0`)c2LN_A7X>)5+kGRPat;D|2rv74`lF*7OWh^7u|VB{;Je#@q)> z?}erJ!7O@V7Jaap{C3!kAEo)JEE5{Ab3uG^c)ApQuJDjU>+modR(43nkV|S`!! zVFS^iul<6e1n`*S=6PO6Wa0w0PR6#a-oqaV0GqD9-LhVPXY1Xy9wT($q6-NcAP2Bx z8nfV6)W_$K)sD~ahnJUoP}sQ&Dc`+Ne?e*Rxg#{xqcA0>krgC8>B5(F1O9$Z%((H;c!Yjq%nI0)~4Kv=H}(p2^dW$#QzXu@Fs{Gj`Xe>buk zkniV|K^U}H>(a*f!XD1{jZUgp5bu4EemrZ@u9(#}G6w}LaBM&oH;vthz_Cnxj9RVe=G`QN&7u2LM{=fkbg@o(S-K9*89Ou59Oyg?Tc#@ zmbSUaMj&xeaae|;nej{ZCLkepD4RwSVnraE#%OA7RBzyzy^)8J*W`t%di33~R~?X6UXkf56&qNR{5v zJgkNnyoapO2SgRR@uC_vi(Mz@x@tdkO1A&%=$rm`LBtzarQrz$7hU2#O z)2_*ceL7Q9fIwlwq%JPAe-@Yd2$$K6s}$lSRGcuW9d?V<1m!713^$+aP}`RbkjZ1E1JVfM~tmZyv)4-K6GG`uTo#5J@xP@FZwdc z7aE?Wr>Us3d!xsjYtox(c2vj#ns6Z4N!-`|7TN*u+X6Uv|3ORYr*?~upe2?d687XJz^N@R_t#kid z1F_g2K*$Dfw0I*$f4~XN=oZPlYX!{EVgT$I!)xe8qw9lhJeD$52f|D1 z(V5U3YI)|5?3*n4nMj56i>$5{oki%?2 z?)my|QB37)rRN`cc0%*ZENSSV6gwZs>i@7)f~jclq|YQ@Acy7kPUxo7J1?s42bauz z>vluEXAv_af25ouP#=)`BwQvX6D#HU3QxwbeMlGO!sum6vsg~-IgKad-WifftgLRK z=RL6*mg(10sC^O`&&lU0jmM$i4%b9ErG_RBwZmVboHBc&=;;?YbN!zy??pi7i7x&= zI@+Q}Z5i|yHHTC*hgN_?D!_!jMNc2PV)0$EgswDrf37qHt~B_rG=#2+c&>?`@Ldz% zUz{{h4CjcgO{9K;1d<(&pwMHZA7CxQnj55-R8 z#ZHLDP6~4&fyS#FPf;5ls0}vMh8=1{3AF)5Z4jb1I>k^MTu*bA{X2&Ek_>a3dW%Lv z5=TN4e?>zQMX4YVA_#;K0@-=`G^m%nb^IT(ST!iH^1`Uhl}f-U)cU zlZbb;kv=NbHbFrR*_ zkSlNE?s>-5t?z2G_>r?)UqZn1jKq@~&$Ed@X6au@CgBC;l5n?v0P`a23&C7!-n)yB zqzB&o2i^}3yc>G73eUBY9M`p9|04PA^Xy`z)Jgm8RQ1n4+p;EBeu^dK@}Xw0PVdzP ze}<=aRRj7x116oF7W|3q4o5k_0Lcqcn8w=fsYu7Te5#1e%%kN z?`U7R&)o7B51<}epBh?kO4*W4-ja>Wrf$hz4y#{oU-YL>0Y{FS(aLMVZZ11z3+R@oVn-BA9K#k zHFM1!6MZYDedavpfv?X4$<70X&I4J`0~O9+KMC&Y>od0)Lx1tf8C;3(TY0x}%DHiB zyWv579!PYah1YG#h~I5F=oGgrssu!%-~IDIB|L!%+$5Fk72SjH179u6C*cEBf9IW$ zTh|*w&%iIybH5f|{RgBFw|5!DYo?88l)P7VzD5G8|rc6fV%z}D6FFK<;RP$_3RCZWq z57%VKLYW1r^g&JWOTak!uM{O^e-;&vpLU;=$zDb=^TjZm;7aR0k=7-a*2S0BC6m^r z_)nEt@rWNzDsd@K|A91GU`vb##)6k_ z(wA;{m(^r1$iZtg1Y-gKm1m#e`XJf^a@tg zAGk)k74sxrkpauVp4YJAiM-)#J;a}VGIUSE`iP9)rO>>3X;51q!^TkWg4=l+3$QZ4 z2V{(z4|sK3V7Ut4L#^FhJg{=es3rW?k+{7l1$`?DpC$#x6p6LgFgc#bGGR37paGp; zQNP(-&ea$&F9GPJ*SAZcf60Tr8BEdA#y;+Ce)qG2%DxRcd{nn>q_yk0z*ErINVbzo zl;rfr0s|(L0Q|r2x|=`~nN_Ika_?C(+TZ<^j}waPv{71cRQJ{smzPzgqKf^M$G6uw ze>v;9d}-9SHYd7QQ5>xM5B!E&j#NjsDFu-Oz^em*=mFsPS>*~xNUz8Ng#R49TnurX z0x$RlqU2yqmw=}c*8Avx#n`1{>|8OnmVNTSktdCOs3!xik&PhR6pJ4Gp<-!BaMiNi z6#V!TB=1(NYa>G_e~A7f@3fCsD~JiR_w+77(Tm|Smh_Gb|2`c5{vQ8662He|O8Bas zmG$%-+bG3Kb!~uSf#b_eJM<#~Y{YD^jG9&GYFR2%!^bpn0YlzsI$7@j`(BaBcV+^sFOdD|l_ z?z!+IEZKQL1Qs{=`)msD<6feTu1CF<&GI*qeSzQ2P#UP?n~w+4H{XJC!!yaj{6E}+T? z9o0G&BV3_Rf0pbbJ(x#+?WJ4m3D5-F9l~$~k!Zh5Ek3QOO>6!1Jj_2-15i)__?V`E0Ue$eJ@B8|$byVtm8e442xv%|R^~Ce5 zIn{LZPl3=60w0gVdm(tji}65NZSHSwBj5~Uf9u$gtHMWDSyEdZyOVh0aRG9bsO$*v zYt3WO&sAwF)BLY@mrQ@r4681ZH|#~KqP^wd}>vk`<O%u7Q*H8X|<1SYeRqo3uyV^??IyT;4Q>f+)Wats!G>)A!pq|lCsP~t( zB=s-r`mHGKp((BnvAY5MM+TmFKF=o$UL1K9txkY${*S^Y+?dp;*_Ik93AQ@9f1{O1 zXmDNWS{PT70dH_MTE8wot5yosS7v%$ww5L_;p(_VZg=xxTBG>V>Y(K2%}7hzo&Gt1 zVi{6A(GfeHyJqSlVHM_}-a50TGIlaE9tH`4PjrWP`D;$EDkXd6(Y)n!B zhyLMXNMm?vLL^m6!H_U7T~U~5TBg}ug3o62%sX7n|FSD z`M%NGDy=9r+uDK5hlq+ee_Rv*$-Lj0R0<4C!Lrgk$p=t+7Yay0bsAu_NcXh`JO%Gx zr*AZ`2_=db^}U;#!y(O21Qwfe%cwL1p1LhkBJEz2KRf4Wy?F-u3@?+Z$>cZRC7#8z zOW{2FNbJWD+Ff&ev$kWfD0=hki+7-j!H^zXUa_EK=RLVZ@4wDGj%t;?H`U&cQFm1o;SjaKnR z8#=8#`GI!Cb@V|3w?KwTinn_LJ1jio+p<$0U`6XyArFz6zSjBYi>j^ba#L|Gp>jD~ z6nUSuo?rd=JhPxUe_LqFV!tvU+;SqRrbCW%XDaGkL<==ID?WB&%m=2#>iA<^j#cGv z@b0zG59{-O=^RMPybY1Ghy9wrYKiOZkBj^XG3-SUS_6DEQ+LLU?(D&;9<-7=b5=)p zBe-IrFK+9KMA-^)3xGeOEvV)^23Lz=ziGG3)0Wu3S84FQe^!>2ko%dK{8NHLLKEm- zG`MsaKA`Igi!_)ChTOQi4s)G=ptR^$yG}527&xQRN#E#wB@Q=wuqB6S)>2H~CUK_-1XgFxqk>MKo#p<>*H=hvFF+ zQFu%$vKm%*p5N2C-`TlOjKHSeSp1K@ePXiaf61gm%_^Is{)O)ab((DJQ8ZP@T7ZS* z_eS=>8C*_%J873UO3&uI?3@ll9a{i;%K}!9h~gIxaJ+x3SU;yUrrAnR`#2fO%b>Gx zJt+E^C{^y8{JQjh9#YK7X;N;qq>Vy}Vcj?w9yLo$SVo8kwM;6V=g`LNd}FQnv@~#l ze_z?VFAqgOfpGPS0$)HE#WK*hZ0W7w^M}K(9Rk5ASv9Yv_miw01 z=GD33CP{k)x?Ya=iLR)=dpYmNuxoTde-LjgS4K}+<}At>JT97Gp>?8{0l3OZwqdV~ zV$|BBdLzC@$HOgJamZw4ck+C*&iv{S8CNeI^gCN?e`Ab& z2`hbRrP+Vi7Az$(&f5EH)`^v5&C(9Oo_U&La0>Zv(mq-f zsY*R$J#Kur_Z5Rua}4e#Ss6iq|dusBo|IKHowlQ7tuBcVihL=W1^=%n% zWlw~>R?n;Di+)VzzzLFte;zw7TvS>>aHe~Qerr1SUQG{6c5S3Zk z`XbDeo>qj`WhbzVu&Uu;o86z(G8N2v&7}+T4mP2`uTnd=n73RO{1A=pe`PJ(PblS` za?z^`11DxtFD&H3R)0+Z>}K|%yys(RAD=fxkk^K2UIg?7W~>{GaH{k5yT7WS2a|wI zCs}&eKP+VM==?<4re8gE``H~t9fBMU{kUHHux)CT&Q&OYMT=EJ;! zZwvJ=&#YDNc6~MbhAip^WJ%3ArpPDzojCZgtP;&4HK*^D)||2je?G0^0zEyYQkXN; zrCjBH9*^D_`{DyhI>vS>(sbOqZ@fHM?G&*+sVJ7kogwz;&Wz6z3UcHi05+Dq*}%Jf zD`^1F(mt2?fm-p4y#b)&Yu)Z<7X}hLwYQJcX#xWoot8clvpt08v zuC8Ohi2X${MYq39e*)1wg3feoB7|0y#)F1x+A204$$zh#O8G!wvfwU|E3?&Eg3Y_Hu|)gF}IP~`dS(MO(f zwsJgPRyHqM4I4j_bUBjD`0F;)&l?rpn_m#!9e*tN%^-2mWx;1~xaUk}k`G&68wrf7 zFgG?;ZR#YRf5Pr}CIC}3I<2dG0P*1}>+j61QB42yYnhf8lL|enEStEBI4ysv5}r}> z0MU!q?TUCVItLa>!8GSzlru(3hOe%*Pd;5ux(2aOYU_1)D{ir!i?u7JU~tLaZpE}; zjV9-=Ed|RlI7v3_M(li5ZGxZmvO&d);OFpeU)SDdui*~!2Pc(P z`t_9Uf1rZ9M|T-M(LL(MVe+Z_H3H|W%v4(>yj_lugV+6~%P2t@u3XIvl1Q81nm0S1 zQdXwCuS-5!=do+h47p^E6NKV1r?PJDf7^*2@hn&zJ}5?n#Q#D@+Q*JioaS8-in`eY zm@XmiObhB`JhToYr?h*wbbcQB1=UnzesQ@4e`O+Rc8Z}3ocOjh>qADZN*3dCf4;?! zmLzK?+Mx~l(sVc85kq5_w2M@4Lo_b>?YZ@ztzr8$n&}4h;^OS|r|o=M8nWVIw>!T> zcVdSJNUIafe{4+^?g!HsoKs4q40WC)KXzupy}!ywZsu7yBC=hAmLmjbZH^k0m#;fH zf4qbKNTL_Pjq9a$VN|)zpKf&VLMKR4AqkP!A}(Fk9#E1Yn92&$yCw)s*FgwrVK_WKc`DY1CD@Z^hz{d`5u%z_EJcA+)c?a zSWj*O7@_S3|xN6a@!xj#B)7a3=#`wV}QD~9Ce;zszA z?66t(*sSFTgA-esMA2>gAW4>@$|QS0Su30N*BYA(6ngnjxQ9Z~%-OC<#^2vQe`*(g zYNwS6*YXWBsCRb^kp6rfXo6kNar|1{Kac*6D_)wrEsW$`^!{8zQW$?oD=2+E+V4)~ z>Th^+H#U3U?Ye+=l~s&x(@aW>#2mU_vCA(tp`3rEYejcAM~7}ma#Q+r+!-OzZAEnw zFITl3!0g{vP0J`9T89qUW&iQ}f2JE$b+cgYd0kcX5B&$v>VEW?2J+s=;!aFH0qgxV z9s?uvOwIVyl~>&4#DD+*A7FS~55gJPo4z>g*bYEWnQ=Cha{VT@YiPiSd{roifxc*b z;dle`wGA6MiEI-AKM)Rwgau84WUNzz6kZE%I$q$f_LE{iR6kj2a0Z~ae_>QTNaQcC zIP?$4x7`})Y&s!?Q`34F0?1DpsflB3MY}BdeC>H+6h@+qYKBVip3PB5-hvDd%4(> z7G#WUz}GU6{jFTODLEODh4KO@+Y+m=a%!`rC*gb?Y zqIH;3Wx{rCJEjHSEF{wi=ZbbP6vuAR$JS4x9>#h45jft3O}IjjZh3{aOiW*cOLO#@ zH}xVGY@))g`GQ3mzrp^!Tk&CjYh?l`&YJ1}`-T*%e-Z;3(skEo4u2vzbn_@KJIIqS zl>U@qQDv_~lFNc~2U9w1WNMSILj_p_xbErJlheIbz&Fz(MvMn|rlhy0^afo+u ze&I)6+|=oNYdflj-!iStJ<0NJ&8de*?!*kyk8e(`y+c?>J|pg>ssol&ru;Pi^&jZ! zDEea(e|g4mL~j={(W1S08+MXe_mVW>NuVUT-p52e?-aen-*U=KM|yEfQlMDT6dczLQZe-~Aaap-DTSYFGn02(E>c%2E{oy8sr zbldCMyy>!;dB>o8TZJbezGvjRTJObqxoU8^O0s|?rb5zu5~4~iNV^Qafb(6zqsG8W z8MI?~A3!c;Jhd9s+A1m_pGFK%t7r*vub}II(yn6s1FR--eXPUFM*^YbzgeG(XP*I#0(bF3if zTgxvzu8p#o@Czx>Lpy1(>>o4i(OK&xf7kEBfbw7+FL{-^-lI_b)3q#_-qg^s=Bp+b z)XcRLE4(Q+h$Vjr&5T_tV%uW!PXXsx!vPN(A5*Yc2CTy~(7M%?90l~SrgA!XwOoj< zrXprv=9KO85^QJ|&e7rNpY!WX)?tPRCp?)XpH;XoHIRslBv2nzm8V5wZEH`S*FCBHMZHo>`n+|6 zPd$-S_XiDklWE$DC4XxeU+9Y|e^%nl7rrNAI~1Yg+;57C&l`q(n=PDF>YML;EF?uf z;RU^&1m?4mb(B#PFK31h&TYRIAZw!N{JHLT*G9Ca%rxWAfAJ=77D8|uOnTc!d8Q41t#M2YD(5+kMSY`zYa~eJMb4Ss>u? zMDzl?wikv9A23DkVyTO9e-3Mx%ao_7gxlWR{a43Y4cG8rKJ&pGzJ3t*b=GiBjEvBc0R40@=wtA617ItL2-xX;T zpSKbXX-)Qe>F*OZ@$XVf{Rvs5wV)hisBZ%yhaYDV*#29i)At@{fBa6StZ+qtB}O5? z>hIK37RH^=)>7Z0qbZwAkQIUhq&j@KSjenE9=SX_{F1;M^>i@&=lI+2=eq9%?9SOG z6{{sWNQtVub%N(gDlfwGAqrv`ykBEvJ_vw3$NA^Mk6GZ$)<=N zTE0KiR$(?%#F%P1CdLS~H>Sh1Umh@!XgLb@X z{~dXmP$D^1f179(;=l)>>B<+#h$$2S18fS4n55oR%YWmTySO_W+|%Ct?U?%kLDxRQ zZ1PaU`jYngbvXckKGT&L+O#WTVbTTsEcY88viL>u1Hz{ums27Mu z9(8(0Rf<3+9M4wG%mzKyX6B{})$aru+Y=G(sT@Zhe_PbdEmVyB-EYiWDjkg^CKrgL z7D)4t5mGu)#^GBObbm?K)7SG@{bDd3!6@sW-=CTj?8GiuCQs+F&frh_J24Me5j(kX z^8?h$$G&(CjFB7gacc0m)Qh�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

D=I19CP$(e^FiK@0$W-#gEt?VDZo2zo%}$n5 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 Date: Sat, 21 Mar 2026 11:04:34 +0100 Subject: [PATCH 17/29] Renamed "nansen.internal.setup.checkRequiredMathworksProducts" to "nansen.internal.dependencies.checkRequiredMathworksProducts" --- .../checkRequiredMathworksProducts.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename code/+nansen/+internal/{+setup => +dependencies}/checkRequiredMathworksProducts.m (85%) diff --git a/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m b/code/+nansen/+internal/+dependencies/checkRequiredMathworksProducts.m similarity index 85% rename from code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m rename to code/+nansen/+internal/+dependencies/checkRequiredMathworksProducts.m index c0cbeae4..37d9945c 100644 --- a/code/+nansen/+internal/+setup/checkRequiredMathworksProducts.m +++ b/code/+nansen/+internal/+dependencies/checkRequiredMathworksProducts.m @@ -1,13 +1,13 @@ function checkRequiredMathworksProducts(mode, options) %checkRequiredMathworksProducts Check for required MathWorks products. % -% nansen.internal.setup.checkRequiredMathworksProducts() checks if the +% nansen.internal.dependencies.checkRequiredMathworksProducts() checks if the % required MathWorks products for core NANSEN are installed. % -% nansen.internal.setup.checkRequiredMathworksProducts(mode) uses the +% nansen.internal.dependencies.checkRequiredMathworksProducts(mode) uses the % specified mode ("warning" or "error") for reporting missing products. % -% nansen.internal.setup.checkRequiredMathworksProducts(mode, Name, Value) +% nansen.internal.dependencies.checkRequiredMathworksProducts(mode, Name, Value) % accepts additional options for module-aware checking. % % Name-Value Arguments: From d3cdbbde15099db8da93c94b9dc14955e18a526e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 11:11:57 +0100 Subject: [PATCH 18/29] Add suppressWarning helper to silence warnings Add nansen.common.suppressWarning.m: a small utility that turns off a specified MATLAB warning and returns an onCleanup object which restores the previous warning state when the cleanup object is cleared. The function validates warningId as a char and enables scoped suppression of warnings --- code/+nansen/+common/suppressWarning.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 code/+nansen/+common/suppressWarning.m diff --git a/code/+nansen/+common/suppressWarning.m b/code/+nansen/+common/suppressWarning.m new file mode 100644 index 00000000..314533f9 --- /dev/null +++ b/code/+nansen/+common/suppressWarning.m @@ -0,0 +1,14 @@ +function warningCleanupObj = suppressWarning(warningId) +% suppressWarning - Temporarily suppress warning with given warning id +% +% Example usage: +% +% warningIdentifier = 'MATLAB:callback:error'; +% warningCleanup = nansen.common.suppressWarning(warningIdentifier); %#ok + + arguments + warningId (1,:) char + end + warnState = warning('off', warningId); + warningCleanupObj = onCleanup(@() warning(warnState)); +end From 3e8b538cb9a1eb2dc51b0cffa5409f067c9384e1 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 11:12:51 +0100 Subject: [PATCH 19/29] add contents/readme files for affected namespaces --- code/+nansen/+config/+addons/Contents.m | 16 +++++++++++++++ code/+nansen/+config/+addons/README.md | 20 +++++++++++++++++++ .../+internal/+dependencies/Contents.m | 13 ++++++++++++ .../+nansen/+internal/+dependencies/README.md | 20 +++++++++++++++++++ code/+nansen/+internal/+setup/Contents.m | 12 +++++++++++ code/+nansen/+internal/+setup/README.md | 9 +++++++++ 6 files changed, 90 insertions(+) create mode 100644 code/+nansen/+config/+addons/Contents.m create mode 100644 code/+nansen/+config/+addons/README.md create mode 100644 code/+nansen/+internal/+dependencies/Contents.m create mode 100644 code/+nansen/+internal/+dependencies/README.md create mode 100644 code/+nansen/+internal/+setup/Contents.m create mode 100644 code/+nansen/+internal/+setup/README.md diff --git a/code/+nansen/+config/+addons/Contents.m b/code/+nansen/+config/+addons/Contents.m new file mode 100644 index 00000000..fc972a40 --- /dev/null +++ b/code/+nansen/+config/+addons/Contents.m @@ -0,0 +1,16 @@ +% Overview of nansen.config.addons namespace +% Managed addon installation and configuration for NANSEN. +% +% This package contains the stateful addon-management layer. It tracks +% managed addons, persists enriched addon records, installs and updates +% community toolboxes, and provides addon-management UI components. +% +% Files +% AddonPreferences - Preferences for addon management. +% +% Classes +% AddonManager - Track, install, update, and activate managed addons. +% AddonManagerUI - UI table for addon management. +% AddonManagerApp - App wrapper for the addon manager UI. +% +% See also nansen.internal.dependencies diff --git a/code/+nansen/+config/+addons/README.md b/code/+nansen/+config/+addons/README.md new file mode 100644 index 00000000..b662aab9 --- /dev/null +++ b/code/+nansen/+config/+addons/README.md @@ -0,0 +1,20 @@ +# `nansen.config.addons` + +This namespace contains the stateful addon-management layer for NANSEN. + +Its responsibilities are: + +- persist enriched addon records in `AddonList` +- install, update, and locate managed addons +- activate addons for the current MATLAB session +- provide addon-management UI + +It consumes resolved dependency information from +`nansen.internal.dependencies`, but it owns installation side effects and +persisted addon state. + +Main entry points: + +- `AddonManager` +- `AddonManagerUI` +- `AddonManagerApp` diff --git a/code/+nansen/+internal/+dependencies/Contents.m b/code/+nansen/+internal/+dependencies/Contents.m new file mode 100644 index 00000000..ed23ec6e --- /dev/null +++ b/code/+nansen/+internal/+dependencies/Contents.m @@ -0,0 +1,13 @@ +% Overview for nansen.internal.dependencies namespace. +% Dependency manifest utilities for NANSEN. +% +% This package is the stateless dependency layer. It reads dependency +% manifests, resolves dependencies across scopes, and computes dependency +% status for the current MATLAB session. +% +% Functions +% readManifest - Parse a dependencies.nansen.json file. +% resolveRequirements - Resolve, deduplicate, and filter dependencies. +% checkInstallationStatus - Compute IsInstalled and IsOnPath status. +% getRequiredMathworksProducts - List required MathWorks products. +% checkRequiredMathworksProducts - Warn or error on missing MathWorks products. diff --git a/code/+nansen/+internal/+dependencies/README.md b/code/+nansen/+internal/+dependencies/README.md new file mode 100644 index 00000000..c9df8c87 --- /dev/null +++ b/code/+nansen/+internal/+dependencies/README.md @@ -0,0 +1,20 @@ +# `nansen.internal.dependencies` + +This namespace contains the stateless dependency layer for NANSEN. + +Its responsibilities are: + +- read dependency manifests +- resolve dependencies across core and module scopes +- deduplicate and filter dependency requirements +- compute dependency status for the current MATLAB session + +It should not own installation side effects, UI, or persisted addon state. + +Functions: + +- `nansen.internal.dependencies.readManifest` +- `nansen.internal.dependencies.resolveRequirements` +- `nansen.internal.dependencies.checkInstallationStatus` +- `nansen.internal.dependencies.getRequiredMathworksProducts` +- `nansen.internal.dependencies.checkRequiredMathworksProducts` diff --git a/code/+nansen/+internal/+setup/Contents.m b/code/+nansen/+internal/+setup/Contents.m new file mode 100644 index 00000000..d29f39f9 --- /dev/null +++ b/code/+nansen/+internal/+setup/Contents.m @@ -0,0 +1,12 @@ +% Overview of nansen.internal.setup namespace +% Environment setup utilities for NANSEN. +% +% This package contains setup-time helpers for preparing the MATLAB +% environment, userpath, Java class path, and other runtime prerequisites. +% +% Functions +% resolveEmptyUserpath - Resolve missing MATLAB userpath. +% addYamlJarToJavaClassPath - Add YAML jar to Java class path. +% addUiwidgetsJarToJavaClassPath - Add Widgets Toolbox jar to Java path. +% isUiwidgetsOnJavapath - Check Widgets Toolbox Java path setup. +% checkWidgetsToolboxVersion - Check Widgets Toolbox version. diff --git a/code/+nansen/+internal/+setup/README.md b/code/+nansen/+internal/+setup/README.md new file mode 100644 index 00000000..90d9127c --- /dev/null +++ b/code/+nansen/+internal/+setup/README.md @@ -0,0 +1,9 @@ +# `nansen.internal.setup` + +This namespace environment setup helpers for NANSEN. + +Its responsibilities are: + +- resolve setup prerequisites such as `userpath` +- configure Java class path dependencies +- host setup-time environment utilities From 932d97f05c0e2ad3371e18c0ed794e188a946d07 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 11:13:11 +0100 Subject: [PATCH 20/29] Remove stale/unused functions --- code/+nansen/+internal/+setup/installAddons.m | 17 ----------------- .../+nansen/+internal/+setup/listDependencies.m | 15 --------------- 2 files changed, 32 deletions(-) delete mode 100644 code/+nansen/+internal/+setup/installAddons.m delete mode 100644 code/+nansen/+internal/+setup/listDependencies.m diff --git a/code/+nansen/+internal/+setup/installAddons.m b/code/+nansen/+internal/+setup/installAddons.m deleted file mode 100644 index 2d002fc1..00000000 --- a/code/+nansen/+internal/+setup/installAddons.m +++ /dev/null @@ -1,17 +0,0 @@ -function installAddons() -% installAddons - Install addons using nansen's addon manager - - addonManager = nansen.AddonManager(); - - for i = 1:numel(addonManager.AddonList) - S = addonManager.AddonList(i); - if ~S.IsInstalled - fprintf('Downloading %s...', S.Name) - addonManager.downloadAddon(S.Name) - addonManager.addAddonToMatlabPath(S.Name) - fprintf('Finished.\n') - end - end - - addonManager.saveAddonList() -end diff --git a/code/+nansen/+internal/+setup/listDependencies.m b/code/+nansen/+internal/+setup/listDependencies.m deleted file mode 100644 index 73b623ee..00000000 --- a/code/+nansen/+internal/+setup/listDependencies.m +++ /dev/null @@ -1,15 +0,0 @@ -function dependencies = listDependencies(flag) -%listDependencies - List the dependencies for NANSEN - - % if nargin < 1; flag = 'required'; end - % flag = validatestring(flag, {'required', 'all'}, 1); - - % Todo: - % Deprecate? - % Generate this table from the requirements.txt file - - rootPath = fullfile(nansen.toolboxdir, 'resources', 'dependencies'); - jsonStr = fileread( fullfile(rootPath, 'fex_submissions.json') ); - - dependencies = struct2table( jsondecode(jsonStr) ); -end From cd64cee37302fba0dbf4b7a99eef23665a87659a Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:24:02 +0100 Subject: [PATCH 21/29] Create createCommandWindowWebLink.m --- .../+internal/+utility/createCommandWindowWebLink.m | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 code/+nansen/+internal/+utility/createCommandWindowWebLink.m diff --git a/code/+nansen/+internal/+utility/createCommandWindowWebLink.m b/code/+nansen/+internal/+utility/createCommandWindowWebLink.m new file mode 100644 index 00000000..21ac1ce5 --- /dev/null +++ b/code/+nansen/+internal/+utility/createCommandWindowWebLink.m @@ -0,0 +1,9 @@ +function linkStr = createCommandWindowWebLink(url, title) + + arguments + url (1,:) char + title (1,:) char + end + + linkStr = sprintf('%s', url, title); +end From f607bd42a030a7b2031019e3e93a73ce922b0a20 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:28:48 +0100 Subject: [PATCH 22/29] Update loadProject.m --- code/+nansen/+app/+tutorial/loadProject.m | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/+nansen/+app/+tutorial/loadProject.m b/code/+nansen/+app/+tutorial/loadProject.m index 8a14e676..26c24750 100644 --- a/code/+nansen/+app/+tutorial/loadProject.m +++ b/code/+nansen/+app/+tutorial/loadProject.m @@ -35,22 +35,26 @@ error('User canceled.') end +% We need the addonmanager to ensure all tutorial dependencies are installed +addonManager = nansen.AddonManager(); + if startsWith(S(selection), 'Allen Brain Observatory') - addonManager = nansen.AddonManager(); names = {addonManager.AddonList.Name}; S = addonManager.AddonList(strcmp(names, "Brain Observatory Toolbox")); if ~S.IsInstalled fprintf('Downloading %s...', S.Name) addonManager.downloadAddon(S.Name) - addonManager.addAddonToMatlabPath(S.Name) fprintf('Finished.\n') end + elseif startsWith(S(selection), 'Nansen - Two-photon Quickstart') warnState = warning('off', 'MATLAB:RMDIR:RemovedFromPath'); warnCleanup = onCleanup(@() warning(warnState)); + disp('Installing two-photon addons...') - nansen.internal.setup.installAddons() + addonManager.installMissingAddons('nansen.module.ophys.twophoton') + % Some users had problems where Yaml was not added to java path nansen.internal.setup.addYamlJarToJavaClassPath end From c992058f7cd261eba63b0529eb542239257d079a Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:28:57 +0100 Subject: [PATCH 23/29] Update checkInstallationStatus.m --- .../+dependencies/checkInstallationStatus.m | 138 ++++++++++++++++-- 1 file changed, 125 insertions(+), 13 deletions(-) diff --git a/code/+nansen/+internal/+dependencies/checkInstallationStatus.m b/code/+nansen/+internal/+dependencies/checkInstallationStatus.m index 6d8f317d..f7aa9fd4 100644 --- a/code/+nansen/+internal/+dependencies/checkInstallationStatus.m +++ b/code/+nansen/+internal/+dependencies/checkInstallationStatus.m @@ -1,22 +1,26 @@ -function statusResults = checkInstallationStatus(resolvedRequirements) -%checkInstallationStatus Check install state of resolved requirements. +function statusResults = checkInstallationStatus(resolvedRequirements, trackedAddons) +%checkInstallationStatus Check install and path state of resolved requirements. % % statusResults = nansen.internal.dependencies.checkInstallationStatus(resolvedRequirements) -% takes the output of resolveRequirements and populates the IsInstalled -% field for each entry. +% populates the IsInstalled and IsOnPath fields for each dependency. +% +% statusResults = nansen.internal.dependencies.checkInstallationStatus( ... +% resolvedRequirements, trackedAddons) +% uses tracked addon records from AddonManager for richer status checks. % % Input: % resolvedRequirements - struct array from readManifest or % resolveRequirements. +% trackedAddons - optional AddonManager addon records. % % Output: -% statusResults - same struct array with IsInstalled populated: -% - MathWorks products: checked via ver() -% - Community toolboxes: checked via InstallCheck field -% (a function/class name tested with exist()) +% statusResults - same struct array with fields populated: +% - IsInstalled: dependency is installed/tracked +% - IsOnPath: dependency is available on MATLAB's search path arguments resolvedRequirements (1,:) struct + trackedAddons (1,:) struct = struct.empty(1, 0) end statusResults = resolvedRequirements; @@ -25,18 +29,126 @@ return end - % Cache installed MathWorks products (call ver() once) versionInfo = ver(); installedProductNames = string({versionInfo.Name}); + installedAddonTable = getInstalledAddonsTable(); for i = 1:numel(statusResults) entry = statusResults(i); + trackedEntry = getTrackedAddonEntry(entry, trackedAddons); + if entry.DependencyType == "mathworks-product" - statusResults(i).IsInstalled = any(entry.Name == installedProductNames); - elseif isfield(entry, 'InstallCheck') && strlength(entry.InstallCheck) > 0 - statusResults(i).IsInstalled = ~isempty( which(entry.InstallCheck) ); + isInstalled = any(entry.Name == installedProductNames); + isOnPath = isInstalled; + else + isOnPath = isDependencyOnPath(entry); + isInstalled = isOnPath || isTrackedAddonInstalled(trackedEntry, installedAddonTable); + end + + statusResults(i).IsInstalled = isInstalled; + statusResults(i).IsOnPath = isOnPath; + end +end + +function tf = isDependencyOnPath(entry) +%isDependencyOnPath Check if a dependency is available in the current session. + tf = false; + if isfield(entry, 'InstallCheck') && strlength(string(entry.InstallCheck)) > 0 + checkName = char(entry.InstallCheck); + try + answer = which(checkName); + catch ME + warning('NANSEN:Dependencies:InstallCheckFailed', ... + 'Failed to evaluate InstallCheck "%s": %s', checkName, ME.message) + return + end + + if isempty(answer) || strcmp(answer, 'Not on MATLAB path') + tf = false; + elseif isfile(answer) + tf = true; else - statusResults(i).IsInstalled = false; + % Our install check should be pointing to a file + tf = false; + warning('NANSEN:Dependencies:InstallCheckUnexpectedWhichOutput', ... + 'InstallCheck "%s" resolved to unexpected output: %s', ... + checkName, answer) end end end + +function trackedEntry = getTrackedAddonEntry(entry, trackedAddons) +%getTrackedAddonEntry Find a matching tracked addon entry by dependency name. + trackedEntry = struct.empty(1, 0); + + if isempty(trackedAddons) || ~isfield(entry, 'Name') || ~isfield(trackedAddons, 'Name') + return + end + + trackedNames = string({trackedAddons.Name}); + matchIndex = find(trackedNames == string(entry.Name), 1, 'first'); + if ~isempty(matchIndex) + trackedEntry = trackedAddons(matchIndex); + end +end + +function tf = isTrackedAddonInstalled(trackedEntry, installedAddonTable) +%isTrackedAddonInstalled Determine whether a tracked addon is installed. + tf = false; + if isempty(trackedEntry) + return + end + + installationType = string(getStructFieldOrDefault(trackedEntry, 'InstallationType', "")); + filePath = string(getStructFieldOrDefault(trackedEntry, 'FilePath', "")); + addonName = string(getStructFieldOrDefault(trackedEntry, 'Name', "")); + toolboxIdentifier = string(getStructFieldOrDefault(trackedEntry, 'ToolboxIdentifier', "")); + + switch installationType + case "folder" + tf = strlength(filePath) > 0 && isfolder(filePath); + case "mltbx" + tf = isInstalledToolboxAddon(addonName, toolboxIdentifier, installedAddonTable); + otherwise + if strlength(filePath) > 0 + tf = isfolder(filePath); + elseif strlength(toolboxIdentifier) > 0 || strlength(addonName) > 0 + tf = isInstalledToolboxAddon(addonName, toolboxIdentifier, installedAddonTable); + elseif isfield(trackedEntry, 'IsInstalled') + tf = logical(trackedEntry.IsInstalled); + end + end +end + +function tf = isInstalledToolboxAddon(addonName, toolboxIdentifier, installedAddonTable) +%isInstalledToolboxAddon Check if an addon is installed through MATLAB's addon system. + tf = false; + if isempty(installedAddonTable) + return + end + + variableNames = string(installedAddonTable.Properties.VariableNames); + if strlength(toolboxIdentifier) > 0 && ismember("Identifier", variableNames) + tf = any(string(installedAddonTable.Identifier) == toolboxIdentifier); + elseif strlength(addonName) > 0 && ismember("Name", variableNames) + tf = any(string(installedAddonTable.Name) == addonName); + end +end + +function addonsTable = getInstalledAddonsTable() +%getInstalledAddonsTable Return installed MATLAB addons or an empty table. + try + addonsTable = matlab.addons.installedAddons(); + catch + addonsTable = table(); + end +end + +function value = getStructFieldOrDefault(S, fieldName, defaultValue) +%getStructFieldOrDefault Read struct field if present, otherwise return default. + if isfield(S, fieldName) + value = S.(fieldName); + else + value = defaultValue; + end +end From a2a09b8d422ac179001262d3128785e8df7633db Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:29:09 +0100 Subject: [PATCH 24/29] Update nansen_install.m --- nansen_install.m | 54 ++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/nansen_install.m b/nansen_install.m index 41a694eb..30b3704b 100644 --- a/nansen_install.m +++ b/nansen_install.m @@ -10,6 +10,8 @@ function nansen_install(options) arguments options.SavePath (1,1) logical = true + options.Modules (1,:) string = string.empty + options.Update (1,1) logical = false end nansenProjectFolder = fileparts(mfilename('fullpath')); % Path to nansen codebase @@ -20,38 +22,46 @@ function nansen_install(options) error('NANSEN:Setup:CodeFolderNotFound', ... 'Could not find folder with code for Nansen') end - + % Check that userpath is not empty (can happen on linux platforms) if isempty(userpath) nansen.internal.setup.resolveEmptyUserpath() end - - warnState = warning('off', 'MATLAB:javaclasspath:jarAlreadySpecified'); - warningCleanup = onCleanup(@(state) warning(warnState)); + + % Supress a warning which is not relevant for users + warningIdentifier = 'MATLAB:javaclasspath:jarAlreadySpecified'; + warningCleanup = nansen.common.suppressWarning(warningIdentifier); %#ok + + % Get the AddonManager singleton + addonManager = nansen.AddonManager(); - % Use MatBox to install dependencies/requirements - downloadAndInstallMatBox(); + % We need MatBox first to install other dependencies + addonManager.downloadAndInstallMatBox() + + % Install core requirements + addonManager.installMissingAddons(); - requirementsInstallationFolder = fullfile(userpath, 'NANSEN', 'Requirements'); - matbox.installRequirements(nansenProjectFolder, 'u', ... - 'InstallationLocation', requirementsInstallationFolder) + if options.Update + addonManager.updateAddons(options.Modules); + else + numAddonsInstalled = addonManager.installMissingAddons(options.Modules); + if numAddonsInstalled == 0 + disp([ ... + 'All dependencies are installed. ', ... + 'Use nansen_install(Update=true) to update dependencies.']) + end + end - % Add NANSEN toolbox folder to path if it was not added already + % Add NANSEN toolbox folder to path if it was not added already if ~contains(path(), nansenToolboxFolder) addpath(genpath(nansenToolboxFolder)) - savepath() end if options.SavePath - savepath() - end -end - -function downloadAndInstallMatBox() - if ~exist('+matbox/installRequirements', 'file') - sourceFile = 'https://raw.githubusercontent.com/ehennestad/matbox-actions/refs/heads/main/install-matbox/installMatBox.m'; - filePath = websave('installMatBox.m', sourceFile); - installMatBox('commit') - rehash() - delete(filePath); + status = savepath(); + if status ~= 0 + warning('NANSEN:Setup:SavePathFailed', ... + ['Could not save the MATLAB path. NANSEN is available for this session, ', ... + 'but you may need to save the path manually.']) + end end end From 1c6e6dcb4e9bc9fb072b8394e5291231c13c5865 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:29:12 +0100 Subject: [PATCH 25/29] Update install.m --- code/wrappers/+nansen/+wrapper/+flowreg/install.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/wrappers/+nansen/+wrapper/+flowreg/install.m b/code/wrappers/+nansen/+wrapper/+flowreg/install.m index 27c0601a..8d82b6c2 100644 --- a/code/wrappers/+nansen/+wrapper/+flowreg/install.m +++ b/code/wrappers/+nansen/+wrapper/+flowreg/install.m @@ -3,7 +3,7 @@ flowregdir = fileparts( which('set_path') ); [~, dirname] = fileparts(flowregdir); -assert( strcmp(dirname, 'flow_registration'), ... +assert( contains(dirname, 'flow_registration'), ... 'Could not locate the directory containing the flow_registration toolbox') addpath(fullfile(flowregdir, 'core')); From 38f8be8ff6280196fff856a7bd772bea4b42d8e1 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:29:17 +0100 Subject: [PATCH 26/29] Update dependencies.nansen.json --- .../+module/+ophys/+twophoton/dependencies.nansen.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json index 7eadccc2..03bc79dd 100644 --- a/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json +++ b/code/modules/+nansen/+module/+ophys/+twophoton/dependencies.nansen.json @@ -100,18 +100,22 @@ { "name": "NoRMCorre", "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.normcorre", "requirementLevel": "optional", "source": "https://github.com/ehennestad/NoRMCorre", - "docsSource": "https://github.com/flatironinstitute/NoRMCorre" + "docsSource": "https://github.com/flatironinstitute/NoRMCorre", "description": "Non-rigid motion correction for calcium imaging data", "installCheck": "normcorre_batch" }, { "name": "Flow Registration", "dependencyType": "community-toolbox", + "scope": "workflow", + "scopeId": "nansen.module.ophys.twophoton.workflow.flowreg", "requirementLevel": "optional", "source": "https://github.com/phflot/flow_registration", - "docsSource": "https://github.com/phflot/flow_registration" + "docsSource": "https://github.com/phflot/flow_registration", "description": "Optical flow based motion correction for calcium imaging data", "setupHook": "nansen.wrapper.flowreg.install", "installCheck": "OF_Options" From 4b00f5ef777a3b744b1b5d5b834450f68fbdef5c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 15:29:39 +0100 Subject: [PATCH 27/29] Update resolveRequirements.m --- .../+dependencies/resolveRequirements.m | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/code/+nansen/+internal/+dependencies/resolveRequirements.m b/code/+nansen/+internal/+dependencies/resolveRequirements.m index 68a519d1..f27d1175 100644 --- a/code/+nansen/+internal/+dependencies/resolveRequirements.m +++ b/code/+nansen/+internal/+dependencies/resolveRequirements.m @@ -17,10 +17,15 @@ % Empty means all levels. % MissingOnly (logical) - Return only missing dependencies. % Default: false. +% TrackedAddons (struct array) - Optional tracked addon records from +% AddonManager. Used for richer install/path status checks. % % Output: % resolvedRequirements - struct array with all schema fields plus: -% .IsInstalled (logical) - whether the dependency is present +% .IsInstalled (logical) - whether the dependency is tracked as +% installed or otherwise known to be present +% .IsOnPath (logical) - whether the dependency is currently +% available on MATLAB's search path arguments options.IncludeCore (1,1) logical = true @@ -29,6 +34,7 @@ options.DependencyTypes (1,:) string = string.empty options.RequirementLevels (1,:) string = string.empty options.MissingOnly (1,1) logical = false + options.TrackedAddons (1,:) struct = struct.empty(1, 0) end manifestPaths = collectManifestPaths(options.IncludeCore, options.SelectedModules); @@ -43,7 +49,7 @@ % Check installation status resolvedRequirements = nansen.internal.dependencies.checkInstallationStatus( ... - resolvedRequirements); + resolvedRequirements, options.TrackedAddons); % Apply filters resolvedRequirements = applyFilters(resolvedRequirements, ... @@ -61,16 +67,26 @@ end end - % Module manifests — ModuleManager tracks RequirementManifestPath + % Module manifests if ~isempty(selectedModules) - moduleManager = nansen.config.module.ModuleManager(); - moduleTable = moduleManager.listModules(); - if ismember("RequirementManifestPath", moduleTable.Properties.VariableNames) - modulePackages = string(moduleTable.PackageName); - selectedMask = ismember(modulePackages, selectedModules); - moduleManifestPaths = string(moduleTable.RequirementManifestPath(selectedMask)); - moduleManifestPaths = moduleManifestPaths(strlength(moduleManifestPaths) > 0); - manifestPaths = [manifestPaths, moduleManifestPaths(:)']; + + for i = 1:numel(selectedModules) + + currentModulePath = utility.path.packagename2pathstr(selectedModules(i)); + + moduleInfo = what(currentModulePath); + if isempty(moduleInfo) + warning('NANSEN:Dependencies:ModuleNotFound', ... + 'No module with name "%s" on MATLAB''s search path', selectedModules(i)) + continue + elseif numel(moduleInfo) > 1 + warning('NANSEN:Dependencies:MultipleModulesFound', ... + 'Multiple modules with name "%s" was found on MATLAB''s search path', selectedModules(i)) + end + currentModuleManifestPath = fullfile(moduleInfo(1).path, 'dependencies.nansen.json'); + if isfile(currentModuleManifestPath) + manifestPaths = [manifestPaths, currentModuleManifestPath]; %#ok + end end end From eca1e51f1b82725773cc710557513f9ee283a9b8 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 22 Mar 2026 18:30:05 +0100 Subject: [PATCH 28/29] Update AddonManager and add AddonManagerTest --- .../+addons/@AddonManager/AddonManager.m | 1074 +++++++++-------- .../+dependencies/resolveRequirements.m | 10 +- tests/+nansen/+fixture/AddonManagerFixture.m | 89 ++ .../test_core_dependencies.nansen.json | 38 + .../test_module_dependencies.nansen.json | 42 + tests/+nansen/+unittest/AddonManagerTest.m | 331 +++++ 6 files changed, 1106 insertions(+), 478 deletions(-) create mode 100644 tests/+nansen/+fixture/AddonManagerFixture.m create mode 100644 tests/+nansen/+fixture/manifests/test_core_dependencies.nansen.json create mode 100644 tests/+nansen/+fixture/manifests/test_module_dependencies.nansen.json create mode 100644 tests/+nansen/+unittest/AddonManagerTest.m diff --git a/code/+nansen/+config/+addons/@AddonManager/AddonManager.m b/code/+nansen/+config/+addons/@AddonManager/AddonManager.m index c0179a3f..a433b9a9 100644 --- a/code/+nansen/+config/+addons/@AddonManager/AddonManager.m +++ b/code/+nansen/+config/+addons/@AddonManager/AddonManager.m @@ -1,633 +1,753 @@ classdef AddonManager < handle -%AddonManager A simple addon manager for managing a custom list of addons - % Provides an interface for downloading and adding addons/toolboxes - % to the matlab path. Addons are specified in a separate function - % and this class provides several methods for managing these addons. - - % TODOS: - % [X] Save addon list - % [x] System for adding addons to path on startup - % [ ] Make another class for addons. - % [v] Rename to addon manager - % [ ] Add option for setting a custom installation dir - % [ ] File with list of addons should be saved based on which software - % it belongs to. Either use subclassing, or make a way to use access - % a settings file by a keyword or something similar. - % [ ] Better warning/resolving when addons are duplicated... - - % [v] Use matlab.addons.install(filename) for matlab toolbox files. - % [Ā ] Provide table with addons to install as input... - - % QUESTIONS: - % - Use gitmodules?? - % - Implement better git functionality, i.e version tracking - - % NOTES: - % addons = matlab.addons.installedAddons - % S = matlab.addons.toolbox.installedToolboxes Does not show Mathworks toolboxes - - properties % Preferences - InstallationDir char = '' % Path where addons should be installed - UseGit logical = false % Whether to use git for downloads and updates - end +%AddonManager Manages community toolbox dependencies for NANSEN. +% Tracks installed addons, delegates download/install to matbox, +% and manages MATLAB path additions per session. properties - AddonList struct = struct() % List of addons (table or struct array) + % InstallationFolder - Folder to install Add-Ons (dependencies) for NANSEN + InstallationFolder (1,1) string = missing end properties (SetAccess = private) - AddonDefinitionsPath + % ManifestFilePath - Filepath for JSON manifest storing info and + % installation status about Add-Ons managed by NANSEN + ManifestFilePath (1,1) string + end + + properties (Dependent) + % ManagedAddons - Table listing information about managed Add-Ons + ManagedAddons table + end + + properties (SetAccess=private, Hidden) + AddonList struct = struct() % ManagedAddons end properties (Hidden) IsDirty = false end - + properties (Constant, Hidden) - - % A list of fields that are relevant for each addon entry - % Todo: make into a separate class... - addonFields = {... - 'Name', ... % Name of addon - 'IsRequired', ... % Whether addon is required or optional - 'IsInstalled', ... - 'DateInstalled', ... - 'FilePath', ... - 'WebSource', ... - 'WebUrl', ... - 'DownloadUrl', ... - 'HasSetupFile', ... - 'SetupFileName', ... - 'FunctionName', ... - 'AddToPathOnInit', ... - 'IsDoubleInstalled'} + DefaultAddonEntry = struct( ... + 'Name', '', ... + 'Description', "", ... + 'IsRequired', false, ... + 'IsInstalled', false, ... + 'IsOnPath', false, ... + 'DateInstalled', NaT, ... + 'FilePath', '', ... + 'Source', '', ... + 'DocsSource', '', ... + 'SetupFunctionName', '', ... + 'InstallCheck', '', ... + 'InstallationType', '', ... + 'ToolboxIdentifier', '', ... + 'AddToPathOnInit', false, ... + 'HasMultipleInstancesOnPath', false) end - - methods (Access = ?nansen.internal.user.NansenUserSession) - - function obj = AddonManager(preferenceDirectory) - %AddonManager Construct an instance of this class - - % Create a addon manager instance. Provide methods for - % installing addons - if nargin < 1; preferenceDirectory = ''; end - - % Assign the path to the directory where addons are saved - obj.InstallationDir = obj.getDefaultInstallationDir(); - - % Get path where list of previously installed addons are saved - obj.AddonDefinitionsPath = obj.getPathForAddonList(preferenceDirectory); - - % Load addon list (list is initialized if it does not exist) - obj.loadAddonList() - % Add previously installed addons to path if they are not already there. - obj.updateSearchPath() - - % Check if there are multiple versions of addons on the matlab - % search path. + methods (Access = private) % Constructor (private -> singleton) + function obj = AddonManager(installationFolder, manifestFilePath) + arguments + installationFolder (1,1) string + manifestFilePath (1,1) string + end + obj.InstallationFolder = installationFolder; + obj.ManifestFilePath = manifestFilePath; + obj.loadAddonManifest() + obj.ensureAddonDependenciesOnPath() obj.checkAddonDuplication() end end - - methods - - function listAddons(obj) - %listAddons Display a table of addons - - T = struct2table(obj.AddonList); - - % Add a column with index numbers. - numberColumn = table((1:size(T,1))', 'VariableNames', {'Num'}); - T = [numberColumn T]; - - % Display table - disp(T) - end - - function loadAddonList(obj) - % loadAddonList Load list (csv or xml) with required/supported addons - - % Load list - if isfile(obj.AddonDefinitionsPath) - S = load(obj.AddonDefinitionsPath); - addonList = S.AddonList; - else - addonList = obj.initializeAddonList(); % init to empty struct + + methods (Static, Hidden) % Get singleton instance + function obj = instance(mode, installationFolder, manifestFilePath) + %instance Get the singleton AddonManager instance. + % + % obj = AddonManager.instance() returns the singleton instance, + % creating it with default paths if needed. + % + % obj = AddonManager.instance("reset") resets the singleton. + % + % obj = AddonManager.instance("reset", installationFolder, manifestFilePath) + % resets the singleton with custom paths (useful for testing). + arguments + mode (1,1) string {mustBeMember(mode, ["normal", "reset"])} = "normal" + installationFolder (1,1) string = ... + nansen.config.addons.AddonManager.getDefaultInstallationDir() + manifestFilePath (1,1) string = ... + nansen.config.addons.AddonManager.getPathForAddonManifest() end - - addonList = obj.updateAddonList(addonList); - - % Assign to AddonList property - obj.AddonList = addonList; + persistent singletonInstance + if isempty(singletonInstance) || ~isvalid(singletonInstance) || mode == "reset" + singletonInstance = nansen.config.addons.AddonManager( ... + installationFolder, manifestFilePath); + end + obj = singletonInstance; end - - function saveAddonList(obj) - %saveAddonList Sve the list of addons to file. - - S = struct; - S.type = 'Nansen Configuration: List of Installed Addons'; - S.description = 'This file lists all the addons that have been installed through NANSEN'; - - S.AddonList = obj.AddonList; - save(obj.AddonDefinitionsPath, '-struct', 'S') - - jsonFilePath = strrep(obj.AddonDefinitionsPath, '.mat', '.json'); - utility.filewrite(jsonFilePath, jsonencode(S, 'PrettyPrint', true)) + end + + methods % Public + + % Open the Add-On Manifest in MATLABs editor + function openManifest(obj) + edit( obj.ManifestFilePath ) end - - function S = updateAddonList(~, S) - %updateAddonList Compare current with default - % (in case defaults have been updated) - - % %todo: rename - - % Get package list - defaultAddonList = nansen.config.addons.getDefaultAddonList(); - - %numAddons = numel(defaultAddonList); - - defaultAddonNames = {defaultAddonList.Name}; - currentAddonNames = {S.Name}; - - isNew = ~ismember(defaultAddonNames, currentAddonNames); - - newAddons = find(isNew); - fieldNames = fieldnames(defaultAddonList); - - % If some addons are present in default addon list and not in - % current addon list, add from default to current. - for iAddon = newAddons - appendIdx = numel(S) + 1; - - for jField = 1:numel(fieldNames) - thisField = fieldNames{jField}; - S(appendIdx).(thisField) = defaultAddonList(iAddon).(thisField); + + % Change current directory to the Add-On installation folder + function cdInstallationFolder(obj) + cd(obj.InstallationFolder) + end + + function numAddonsInstalled = installMissingAddons(obj, modules) + % installMissingAddons - Install add-ons that are not installed. + arguments + obj (1,1) nansen.config.addons.AddonManager + modules (1,:) string = string.empty + end + + obj.refreshManagedAddons("SelectedModules", modules); + addonEntries = obj.getManagedAddonsForModules(modules); + + numAddonsInstalled = 0; + for i = 1:numel(addonEntries) + addonEntry = addonEntries(i); + if ~addonEntry.IsInstalled + obj.downloadAddon(addonEntry.Name) + numAddonsInstalled = numAddonsInstalled + 1; end - - % Check if addon is found on matlab's path and update - % IsInstalled flag - if ismember(exist(S(appendIdx).FunctionName), [2,8]) - S(appendIdx).IsInstalled = true; - S(appendIdx).DateInstalled = char(datetime("now")); %todo: format? - else - S(appendIdx).IsInstalled = false; - S(appendIdx).DateInstalled = 'N/A'; + end + obj.saveAddonList() + + if ~nargout + clear numAddonsInstalled + end + end + + function updateAddons(obj, modules) + % updateAddons - Update tracked installed addons. + arguments + obj (1,1) nansen.config.addons.AddonManager + modules (1,:) string = string.empty + end + + obj.refreshManagedAddons("SelectedModules", modules); + addonEntries = obj.getManagedAddonsForModules(modules); + + for i = 1:numel(addonEntries) + addonEntry = addonEntries(i); + if addonEntry.IsInstalled + obj.downloadAddon(addonEntry.Name, true) end - - % Set this flag to false. This should change if an addon is - % installed, but not saved to the matlab search path. - S(appendIdx).AddToPathOnInit = false; end - - % Update package and download url links - for i = 1:numel(S) - thisName = S(i).Name; - isMatch = strcmp(thisName, defaultAddonNames); - if ~any(isMatch); return; end - - S(i).DownloadUrl = defaultAddonList(isMatch).DownloadUrl; - S(i).WebUrl = defaultAddonList(isMatch).WebUrl; - S(i).SetupFileName = defaultAddonList(isMatch).SetupFileName; + obj.saveAddonList() + end + + function saveAddonList(obj) + %saveAddonList Save the addon list as JSON. + savedData = struct(); + savedData.type = 'Nansen Configuration: List of Installed Addons'; + savedData.description = 'Installed addons tracked by NANSEN AddonManager'; + savedData.AddonList = obj.AddonList; + jsonText = jsonencode(savedData, 'PrettyPrint', true); + nansenDirectory = fileparts(obj.ManifestFilePath); + if ~isfolder(nansenDirectory); mkdir(nansenDirectory); end + fileIdentifier = fopen(obj.ManifestFilePath, 'w'); + assert(fileIdentifier ~= -1, ... + 'NANSEN:AddonManager:SaveFailed', ... + 'Could not open addon manifest for writing: %s', ... + obj.ManifestFilePath) + closeFile = onCleanup(@() fclose(fileIdentifier)); + fwrite(fileIdentifier, jsonText, 'char'); + + obj.markClean() + end + + function refreshManagedAddons(obj, options) + %refreshManagedAddons Sync addon list with resolved dependencies. + arguments + obj + options.SelectedModules (1,:) string = string.empty + options.ManifestPaths (1,:) string = string.empty end + + resolveOptions = { ... + "DependencyTypes", "community-toolbox", ... + "SelectedModules", options.SelectedModules, ... + "TrackedAddons", obj.AddonList}; + if ~isempty(options.ManifestPaths) + resolveOptions = [resolveOptions, ... + {"ManifestPaths"}, {options.ManifestPaths}]; + end + resolvedRequirements = nansen.internal.dependencies.resolveRequirements( ... + resolveOptions{:}); + + obj.mergeRequirementsIntoAddonList(resolvedRequirements); + obj.checkAddonDuplication() end - - function tf = browseAddonPath(obj, addonName) - + + % Open UI dialog for user to locate Add-On + function tf = locateAddonPath(obj, addonName) + %locateAddonPath Manually locate an addon folder on disk. tf = false; addonIdx = obj.getAddonIndex(addonName); - - % Open path dialog to locate folderpath for addon pkgInstallationDir = uigetdir(); - if pkgInstallationDir == 0 return end - obj.AddonList(addonIdx).IsInstalled = true; - obj.AddonList(addonIdx).DateInstalled = string(datetime("now")); + obj.AddonList(addonIdx).DateInstalled = char(datetime("now")); obj.AddonList(addonIdx).FilePath = pkgInstallationDir; - - % Addon is added using this addon manager. Addon should - % therefore be added to the Matlab search path when this - % class is initialized. (assume it should not permanently be - % saved to the search path) + obj.AddonList(addonIdx).InstallationType = 'folder'; + obj.AddonList(addonIdx).ToolboxIdentifier = ''; obj.AddonList(addonIdx).AddToPathOnInit = true; - + obj.addAddonToMatlabPath(addonIdx) + obj.AddonList(addonIdx).IsOnPath = true; + obj.saveAddonList(); tf = true; end - + + % Download (and install) specified Add-On function downloadAddon(obj, addonIdx, updateFlag, throwErrorIfFails) - %downloadAddon Download addon to a specified addon folder - + %downloadAddon Install an addon via matbox. if nargin < 3; updateFlag = false; end if nargin < 4; throwErrorIfFails = false; end - - if isa(updateFlag, 'char') && strcmp(updateFlag, 'update') + if ischar(updateFlag) && strcmp(updateFlag, 'update') updateFlag = true; end - - % Get addon entry from the given addon index + addonIdx = obj.getAddonIndex(addonIdx); addonEntry = obj.AddonList(addonIdx); - - % Create a temporary path for storing the downloaded file. - fileType = obj.getFileTypeFromUrl(addonEntry); - tempFilepath = [tempname, fileType]; - - % Download the file containing the addon toolbox + sourceUri = string(addonEntry.Source); + try - tempFilepath = websave(tempFilepath, addonEntry.DownloadUrl); - fileCleanupObj = onCleanup( @(fname) delete(tempFilepath) ); + installResult = obj.installViaMatbox( ... + sourceUri, updateFlag); catch ME if throwErrorIfFails rethrow(ME) + else + warning('NANSEN:AddonManager:InstallFailed', ... + 'Failed to install %s: %s', addonEntry.Name, ME.message) + return end end - - if updateFlag && ~isempty(addonEntry.FilePath) - pkgInstallationDir = addonEntry.FilePath; - %rootDir = utility.path.getAncestorDir(pkgInstallationDir); - - % Delete current version - if isfolder(pkgInstallationDir) - if contains(path, pkgInstallationDir) - rmpath(genpath(pkgInstallationDir)) - end - try - rmdir(pkgInstallationDir, 's') - catch - warning('Could not remove old installation... Please report') - end - end - else - - switch addonEntry.Type - case 'General' - subfolderPath = 'general_toolboxes'; - case 'Neuroscience' - subfolderPath = 'neuroscience_toolboxes'; - end - - % Create a pathstring for the installation directory - rootDir = fullfile(obj.InstallationDir, subfolderPath); - pkgInstallationDir = fullfile(rootDir, addonEntry.Name); - end - - switch fileType - case '.zip' - unzip(tempFilepath, pkgInstallationDir); - case '.mltbx' - obj.installMatlabToolbox(tempFilepath) % Todo: pass updateFlag - end - - % Delete the temp zip file - clear fileCleanupObj - - % Fix github unzipped directory... - if strcmp(addonEntry.Source, 'Github') - renamedDir = obj.restructureUnzippedGithubRepo(pkgInstallationDir); - pkgInstallationDir = renamedDir; - end - obj.AddonList(addonIdx).FilePath = pkgInstallationDir; - - % Addon is added using this addon manager. Addon should - % therefore be added to the Matlab search path when this - % class is initialized. (assume it should not permanently be - % saved to the search path) + obj.AddonList(addonIdx).FilePath = obj.getCharOrEmpty(installResult.FilePath); + obj.AddonList(addonIdx).InstallationType = char(installResult.InstallationType); + obj.AddonList(addonIdx).ToolboxIdentifier = char(installResult.ToolboxIdentifier); obj.AddonList(addonIdx).AddToPathOnInit = true; + obj.AddonList(addonIdx).IsInstalled = true; + obj.AddonList(addonIdx).IsOnPath = true; + obj.AddonList(addonIdx).DateInstalled = char(datetime("now")); + obj.addAddonToMatlabPath(addonIdx) obj.markDirty() - addpath(genpath(pkgInstallationDir)) + % Run named setup function if specified (matbox only runs setup.m) try - % Run setup of package if it has a setup function. - if ~isempty(obj.AddonList(addonIdx).SetupFileName) - setupFcn = str2func(obj.AddonList(addonIdx).SetupFileName); - setupFcn() + if ~isempty(addonEntry.SetupFunctionName) + feval(addonEntry.SetupFunctionName) end catch MECause - rmpath(genpath(pkgInstallationDir)) - rmdir(pkgInstallationDir, "s") if throwErrorIfFails - ME = MException("Nansen:AddonInstallFailed", 'Setup of the toolbox %s failed.', addonEntry.Name); + ME = MException("Nansen:AddonInstallFailed", ... + 'Setup of the toolbox %s failed.', addonEntry.Name); ME = ME.addCause(MECause); - disp(getReport(MECause, 'extended')) throw(ME) else warning('Setup of the toolbox %s failed with the following error:', addonEntry.Name) disp(getReport(MECause, 'extended')) end end - - obj.AddonList(addonIdx).IsInstalled = true; - obj.AddonList(addonIdx).DateInstalled = char(datetime("now")); end - - function updateSearchPath(obj) - %updateSearchPath Add addons to the search path in the current matlab session - - for i = 1:numel(obj.AddonList) - % Only add those who have filepath assigned (those are added from this interface) - if obj.AddonList(i).AddToPathOnInit - obj.addAddonToMatlabPath(i) - end + + % Check if specified Add-On is installed + function tf = isAddonInstalled(obj, addonName) + %isAddonInstalled Check if addon is tracked as installed. + + tf = false; + if any(strcmp({obj.AddonList.Name}, addonName)) + addonIndex = obj.getAddonIndex(addonName); + tf = obj.AddonList(addonIndex).IsInstalled; end end - - function addAddonToMatlabPath(obj, addonIdx) - - addonIdx = obj.getAddonIndex(addonIdx); - pathList = genpath(obj.AddonList(addonIdx).FilePath); - - % Remove all .git subfolders from this list - pathListCell = strsplit(pathList, pathsep); - keep = ~contains(pathListCell, '.git'); - pathListCell = pathListCell(keep); - pathListNoGit = strjoin(pathListCell, pathsep); - % Add all remaining folders to path. - addpath(pathListNoGit); - end - - function addAllToMatlabPath(obj) - + function ensureAddonDependenciesOnPath(obj) + %ensureAddonDependenciesOnPath Activate all tracked installed addons. for i = 1:numel(obj.AddonList) - - % Only add those who have filepath assigned (those are added from this interface) - if ~isempty(obj.AddonList(i).FilePath) + if obj.AddonList(i).IsInstalled obj.addAddonToMatlabPath(i) + obj.AddonList(i).IsOnPath = obj.isAddonOnPath(obj.AddonList(i)); end end end - + function restoreAddToPathOnInitFlags(obj) - + %restoreAddToPathOnInitFlags Clear session path flags after permanent save. for i = 1:numel(obj.AddonList) - - % Only add those who have filepath assigned (those are added from this interface) if obj.AddonList(i).IsInstalled if obj.AddonList(i).AddToPathOnInit obj.AddonList(i).AddToPathOnInit = false; end end end - obj.saveAddonList() end - - function checkAddonDuplication(obj) - for i = 1:numel(obj.AddonList) - - pathStr = which( obj.AddonList(i).FunctionName, '-all'); - - if isa(pathStr, 'cell') && numel(pathStr) > 1 - obj.AddonList(i).IsDoubleInstalled = true; - end - end - end - - % Not implemented yet. Future todo - function runAddonSetup(obj, addonIdx) - - end - - function TF = isAddonInstalled(obj, addonName) - % isAddonInstalled - Check if addon is installed - TF = any(strcmp({obj.AddonList.Name}, addonName)); - - % Todo/Question: - % Should we look for whether name of package is present? - % Or, look for a function in the package and check if it is - % on path...? - end - - % Not implemented (Not urgent): - function TF = isAddonUpToDate(obj) - %isAddonRecent - % Check if version is latest...? - end - function markDirty(obj) obj.IsDirty = true; end - + function markClean(obj) obj.IsDirty = false; end end - methods (Access = protected) - - function addonIdx = getAddonIndex(obj, addonIdx) - %getAddonIndex Get index (number) of addon in list given addon name - - if isa(addonIdx, 'char') - addonIdx = strcmpi({obj.AddonList.Name}, addonIdx); + methods % Set/get + function managedAddons = get.ManagedAddons(obj) + T = struct2table(obj.AddonList); + numberColumn = table((1:size(T,1))', 'VariableNames', {'Num'}); + managedAddons = [numberColumn T]; + + % Enrich name with link to online documentation if present + for i = 1:height(managedAddons) + if ~isempty(managedAddons{i, 'DocsSource'}{1}) + name = nansen.internal.utility.createCommandWindowWebLink(... + managedAddons{i, 'DocsSource'}{1}, managedAddons{i, 'Name'}{1}); + managedAddons{i, 'Name'} = {name}; + end end - - if isempty(addonIdx) - error('Something went wrong, addon was not found in list.') + + managedAddons = removevars(managedAddons, ... + ["Source", "DocsSource", "SetupFunctionName", "InstallCheck", ... + "ToolboxIdentifier","AddToPathOnInit", "HasMultipleInstancesOnPath"]); + managedAddons.Name = string(managedAddons.Name); + managedAddons.Description = string(managedAddons.Description); + managedAddons = movevars(managedAddons, "IsOnPath", "After", "IsInstalled"); + managedAddons = movevars(managedAddons, "Description", "After", "IsOnPath"); + end + + function addonEntries = getManagedAddonsForModules(obj, modules) + %getManagedAddonsForModules Return managed addons relevant for selected modules. + arguments + obj (1,1) nansen.config.addons.AddonManager + modules (1,:) string = string.empty end + + resolvedRequirements = nansen.internal.dependencies.resolveRequirements( ... + "DependencyTypes", "community-toolbox", ... + "SelectedModules", modules, ... + "TrackedAddons", obj.AddonList); + addonNames = string({resolvedRequirements.Name}); + isMatch = ismember(string({obj.AddonList.Name}), addonNames); + addonEntries = obj.AddonList(isMatch); end end - - methods (Hidden, Access = protected) - - function pathStr = getPathForAddonList(obj, prefDir) - %getPathForAddonList Get path where local addon list is saved. - - if nargin < 2 || isempty(prefDir) - prefDir = fullfile(nansen.prefdir, 'settings'); + + methods (Hidden) + function downloadAndInstallMatBox(obj) + installResult = obj.createInstallResult("", "folder", ""); + wasInstalledNow = false; + + if ~exist('+matbox/installRequirements', 'file') + sourceFile = 'https://raw.githubusercontent.com/ehennestad/matbox-actions/refs/heads/main/install-matbox/installMatBox.m'; + filePath = websave('installMatBox.m', sourceFile); + [installationFolder, installationMethod] = installMatBox('commit'); + installResult = obj.createInstallResult(installationFolder, installationMethod, ""); + wasInstalledNow = true; + rehash() + delete(filePath); + else + matboxFunctionPath = which('matbox.VersionNumber'); + if ~isempty(matboxFunctionPath) + matboxRootFolder = fileparts(fileparts(matboxFunctionPath)); + installResult = obj.createInstallResult(matboxRootFolder, "folder", ""); + end + end + + addonIdx = obj.getAddonIndex('MatBox'); + addonEntry = obj.AddonList(addonIdx); + + hasChanges = false; + filePath = obj.getCharOrEmpty(installResult.FilePath); + installationType = obj.getCharOrEmpty(installResult.InstallationType); + + if ~addonEntry.IsInstalled + obj.AddonList(addonIdx).IsInstalled = true; + hasChanges = true; + end + if ~addonEntry.IsOnPath + obj.AddonList(addonIdx).IsOnPath = true; + hasChanges = true; + end + if ~isempty(filePath) && ~strcmp(addonEntry.FilePath, filePath) + obj.AddonList(addonIdx).FilePath = filePath; + hasChanges = true; + end + if ~isempty(installationType) && ~strcmp(addonEntry.InstallationType, installationType) + obj.AddonList(addonIdx).InstallationType = installationType; + hasChanges = true; + end + if ~strcmp(addonEntry.ToolboxIdentifier, '') + obj.AddonList(addonIdx).ToolboxIdentifier = ''; + hasChanges = true; + end + if wasInstalledNow && ~addonEntry.AddToPathOnInit + obj.AddonList(addonIdx).AddToPathOnInit = true; + hasChanges = true; + end + if ~addonEntry.IsInstalled || ... + (ischar(addonEntry.DateInstalled) && strcmp(addonEntry.DateInstalled, 'N/A')) + obj.AddonList(addonIdx).DateInstalled = char(datetime("now")); + hasChanges = true; end - if ~isfolder(prefDir); mkdir(prefDir); end - pathStr = fullfile(prefDir, 'installed_addons.mat'); + if hasChanges + obj.markDirty() + obj.saveAddonList() + end end - - function fileType = getFileTypeFromUrl(obj, addonEntry) - %getFileTypeFromUrl Get filetype from the url download entry. - downloadUrl = addonEntry.DownloadUrl; - - % Todo: Does this generalize well? - switch addonEntry.Source - - case 'FileExchange' - [~, fileType, ~] = fileparts(downloadUrl); - fileType = strcat('.', fileType); - case 'Github' - [~, ~, fileType] = fileparts(downloadUrl); + + function viewFullAddonListAsTable(obj) + disp( struct2table(obj.AddonList) ) + end + end + + methods (Access = private) + + function loadAddonManifest(obj) + %loadAddonManifest - Load addon manifest from file. + wasMigrated = false; + if isfile(obj.ManifestFilePath) + jsonText = fileread(obj.ManifestFilePath); + savedData = jsondecode(jsonText); + addonList = savedData.AddonList; + if iscell(addonList) + addonList = [addonList{:}]; + end + else + [addonList, wasMigrated] = obj.tryMigrateFromLegacyLocation(); + end + obj.AddonList = addonList; + + if wasMigrated + obj.saveAddonList() end end - - % Following functions are not implemented - function downloadGithubAddon(obj, addonName) - + + function mergeRequirementsIntoAddonList(obj, resolvedRequirements) + % mergeRequirementsIntoAddonList - Sync addon list with resolved dependencies. + if nargin < 2 + resolvedRequirements = nansen.internal.dependencies.resolveRequirements( ... + "DependencyTypes", "community-toolbox"); + end + + if isempty(resolvedRequirements) + return + end + + resolvedNames = string({resolvedRequirements.Name}); + currentAddonNames = string({obj.AddonList.Name}); + + for idx = 1:numel(resolvedRequirements) + entry = resolvedRequirements(idx); + addonIdx = find(currentAddonNames == resolvedNames(idx), 1); + + if isempty(addonIdx) + addonIdx = numel(obj.AddonList) + 1; + obj.AddonList(addonIdx) = obj.createAddonEntry(entry); + currentAddonNames(end+1) = resolvedNames(idx); %#ok + end + + obj.AddonList(addonIdx).Name = char(entry.Name); + obj.AddonList(addonIdx).IsRequired = entry.RequirementLevel == "required"; + obj.AddonList(addonIdx).Description = char(entry.Description); + obj.AddonList(addonIdx).Source = char(entry.Source); + obj.AddonList(addonIdx).DocsSource = char(entry.DocsSource); + obj.AddonList(addonIdx).SetupFunctionName = char(entry.SetupHook); + obj.AddonList(addonIdx).InstallCheck = char(entry.InstallCheck); + obj.AddonList(addonIdx).IsInstalled = entry.IsInstalled; + obj.AddonList(addonIdx).IsOnPath = entry.IsOnPath; + + if obj.AddonList(addonIdx).IsInstalled && strcmp(obj.AddonList(addonIdx).DateInstalled, 'N/A') + obj.AddonList(addonIdx).DateInstalled = char(datetime("now")); + end + end end - - function downloadMatlabAddon(obj, addonName) - + + function checkAddonDuplication(obj) + %checkAddonDuplication Detect addons with multiple path locations. + for i = 1:numel(obj.AddonList) + probeName = obj.AddonList(i).InstallCheck; + obj.AddonList(i).HasMultipleInstancesOnPath = false; + if isempty(probeName); continue; end + pathStr = which(probeName, '-all'); + if isa(pathStr, 'cell') && numel(pathStr) > 1 + obj.AddonList(i).HasMultipleInstancesOnPath = true; + end + end end - function installGithubAddon(obj, addonName) - + function addAddonToMatlabPath(obj, addonIdx) + %addAddonToMatlabPath Activate an installed addon for this MATLAB session. + addonIdx = obj.getAddonIndex(addonIdx); + addonEntry = obj.AddonList(addonIdx); + installationType = string(addonEntry.InstallationType); + + if installationType == "mltbx" + obj.enableToolboxAddon(addonEntry) + return + end + + addonFilePath = addonEntry.FilePath; + if isempty(addonFilePath) || ~isfolder(addonFilePath) + return + end + pathList = genpath(addonFilePath); + pathListCell = strsplit(pathList, pathsep); + keep = ~contains(pathListCell, '.git'); + pathListCell = pathListCell(keep); + pathListNoGit = strjoin(pathListCell, pathsep); + addpath(pathListNoGit); end - - function installMatlabAddon(obj, addonName) - + + function addonIdx = getAddonIndex(obj, addonIdx) + %getAddonIndex Get index of addon by name or pass through numeric index. + if ischar(addonIdx) || isstring(addonIdx) + addonIdx = find(strcmpi({obj.AddonList.Name}, addonIdx)); + end + if isempty(addonIdx) + error('NANSEN:AddonManager:NotFound', ... + 'Addon was not found in list.') + end end - - function installMatlabToolbox(obj, fileName) - - % Will install to the default matlab toolbox/addon directory. - newAddon = matlab.addons.install(fileName); - -% NEWADDON is a table of strings with these fields: -% Name - Name of the installed add-on -% Version - Version of the installed add-on -% Enabled - Whether the add-on is enabled -% Identifier - Unique identifier of the installed add-on - + + function installResult = installViaMatbox(obj, sourceUri, doUpdate) + %installViaMatbox Delegate installation to matbox based on URI type. + + installResult = matbox.setup.installFromSourceUri( ... + sourceUri, ... + "InstallationLocation", obj.InstallationFolder, ... + "AddToPath", true, ... + "Update", doUpdate, ... + "Verbose", true, ... + "AgreeToLicense", true); + + assert( isfield(installResult, 'FilePath') && ... + isfield(installResult, 'InstallationType') && ... + isfield(installResult, 'ToolboxIdentifier')) end end - - methods (Hidden) - - function showAddonFiletype(obj) - %showAddonFiletype Show the filetype of the downloaded addon files - % - % Method for testing/verification - - for i = 1:numel(obj.AddonList) - thisAddon = obj.AddonList(i); - fileType = obj.getFileTypeFromUrl(thisAddon); - - fprintf('%s : %s\n', thisAddon.Name, fileType) + + methods (Access = private) + function addonEntry = createAddonEntry(obj, entry) + addonEntry = obj.getDefaultAddonEntry(); + + addonEntry.Name = char(entry.Name); + addonEntry.IsRequired = entry.RequirementLevel == "required"; + addonEntry.IsInstalled = entry.IsInstalled; + addonEntry.IsOnPath = entry.IsOnPath; + addonEntry.DateInstalled = 'N/A'; + addonEntry.FilePath = ''; + addonEntry.Description = char(entry.Description); + addonEntry.Source = char(entry.Source); + addonEntry.DocsSource = char(entry.DocsSource); + addonEntry.SetupFunctionName = char(entry.SetupHook); + addonEntry.InstallCheck = char(entry.InstallCheck); + addonEntry.InstallationType = ''; + addonEntry.ToolboxIdentifier = ''; + addonEntry.AddToPathOnInit = false; + addonEntry.HasMultipleInstancesOnPath = false; + + if entry.IsInstalled + addonEntry.DateInstalled = char(datetime("now")); + end + end + + function tf = isAddonOnPath(~, addonEntry) + tf = false; + if ~isempty(addonEntry.InstallCheck) + tf = ~isempty(which(addonEntry.InstallCheck)); + end + end + + function enableToolboxAddon(~, addonEntry) + if ~isempty(addonEntry.InstallCheck) && ~isempty(which(addonEntry.InstallCheck)) + return + end + if ~isempty(addonEntry.ToolboxIdentifier) + try + matlab.addons.enableAddon(addonEntry.ToolboxIdentifier) + return + catch + end + end + if ~isempty(addonEntry.Name) + matlab.addons.enableAddon(addonEntry.Name) end end end - methods (Static) - function checkIfAddonsAreOnPath() - - import nansen.config.addons.AddonManager + methods (Static, Hidden) + function pathStr = getDefaultInstallationDir() + %getDefaultInstallationDir Get default addon installation directory. + nansen.config.addons.AddonManager.ensureUserpathAvailable() + pathStr = fullfile(userpath, 'Nansen', 'Add-Ons'); + end + function checkIfAddonsAreOnPath() % Todo: Needs improvement, not urgent + %checkIfAddonsAreOnPath Prompt user to add missing addon folders to path. + import nansen.config.addons.AddonManager addonDir = AddonManager.getDefaultInstallationDir(); - - % Get all subfolders two levels down subfolders = utility.path.listSubDir(addonDir, '', {}, 2); - isOnPath = true(size(subfolders)); - if ~isempty(subfolders) for i = 1:numel(subfolders) if ~contains(path, subfolders{i}) - isOnPath(i)=false; + isOnPath(i) = false; end end end - if any(~isOnPath) subfoldersNotOnPath = subfolders(~isOnPath); [~, addonNames] = fileparts(subfoldersNotOnPath); - - msg = sprintf("The following add-ons where not present on the MATLAB path: \n\n%sĀ \n\nDo you want to add them now?", strjoin(addonNames, newline)); + msg = sprintf( ... + "The following add-ons were not present on the MATLAB path:\n\n%s\n\nDo you want to add them now?", ... + strjoin(addonNames, newline)); answer = questdlg(msg, 'Update MATLAB path?'); - - switch answer - case 'Yes' - for i = 1:numel(subfoldersNotOnPath) - addpath(genpath(subfoldersNotOnPath{i})) - end - savepath() + if strcmp(answer, 'Yes') + for i = 1:numel(subfoldersNotOnPath) + addpath(genpath(subfoldersNotOnPath{i})) + end + savepath() end end end end - - methods (Static) + + methods (Static, Access = private) + function addonEntry = getDefaultAddonEntry() + addonEntry = nansen.config.addons.AddonManager.DefaultAddonEntry; + end - function S = initializeAddonList() + function addonEntry = initializeAddonList() %initializeAddonList Create an empty struct with addon fields. - - names = nansen.config.addons.AddonManager.addonFields; - values = repmat({{}}, size(names)); - - structInit = [names; values]; - - S = struct(structInit{:}); + addonEntry = nansen.config.addons.AddonManager.DefaultAddonEntry; + addonEntry(1) = []; end - function pathStr = getDefaultInstallationDir() - %getDefaultInstallationDir Get path to default directory for - % installing addons - - % Assign installation directory. - % QTodo: get "userpath" from preferences? - pathStr = fullfile(userpath, 'Nansen', 'Add-Ons'); + function ensureUserpathAvailable() + if isempty(userpath) + nansen.internal.setup.resolveEmptyUserpath() + end end - function folderPath = restructureUnzippedGithubRepo(folderPath) - %restructureUnzippedGithubRepo Move the folder of a github addon. - % - - % Github packages unzips to a new folder within the created - % folder. Move it up one level. Also, remove the '-master' from - % foldername. - - rootDir = fileparts(folderPath); - - % Find the repository folder - L = dir(folderPath); - L = L(~strncmp({L.name}, '.', 1)); + function newAddonList = migrateLegacyAddonList(oldAddonList) + %migrateLegacyAddonList Remap legacy addon struct fields to new names. + % Handles old addon lists that have DownloadUrl, WebUrl, + % SetupFileName, FunctionName fields. - if numel(L) > 1 - % This is unexpected, there should only be one folder. - return - end + import nansen.config.addons.AddonManager - % Move folder up one level - oldDir = fullfile(folderPath, L.name); - newDir = fullfile(rootDir, L.name); - movefile(oldDir, newDir) - rmdir(folderPath) + newAddonList = AddonManager.initializeAddonList(); + if isempty(oldAddonList); return; end + + if isfield(oldAddonList, 'DownloadUrl') && ~isfield(oldAddonList, 'Source') - % Remove the master postfix from foldername - if contains(L.name, '-master') - newName = strrep(L.name, '-master', ''); - elseif contains(L.name, '-main') - newName = strrep(L.name, '-main', ''); + for i = 1:numel(oldAddonList) + newAddonList(i) = AddonManager.getDefaultAddonEntry(); + + newAddonList(i).Name = oldAddonList(i).Name; + newAddonList(i).Description = oldAddonList(i).Description; + newAddonList(i).Source = oldAddonList(i).DownloadUrl; + newAddonList(i).DocsSource = oldAddonList(i).WebUrl; + newAddonList(i).SetupFunctionName = oldAddonList(i).SetupFileName; + newAddonList(i).InstallCheck = oldAddonList(i).FunctionName; + newAddonList(i).IsInstalled = oldAddonList(i).IsInstalled; + newAddonList(i).DateInstalled = oldAddonList(i).DateInstalled; + newAddonList(i).FilePath = oldAddonList(i).FilePath; + + if ~isempty(oldAddonList(i).FilePath) && isfolder(oldAddonList(i).FilePath) + newAddonList(i).InstallationType = 'folder'; + end + end else - folderPath = fullfile(rootDir, L.name); - return + newAddonList = oldAddonList; end - - % Rename folder to remove main/master tag - renamedDir = fullfile(rootDir, newName); - if isfolder(renamedDir) - rmdir(renamedDir, 's') + end + + function [addonList, wasMigrated] = tryMigrateFromLegacyLocation() + %tryMigrateFromLegacyLocation Migrate addon list from legacy .mat location. + wasMigrated = false; + legacyMatPath = fullfile(prefdir, 'Nansen', 'default', 'settings', 'installed_addons.mat'); + if isfile(legacyMatPath) + loadedData = load(legacyMatPath); + addonList = loadedData.AddonList; + addonList = nansen.config.addons.AddonManager.migrateLegacyAddonList(addonList); + wasMigrated = true; + else + addonList = nansen.config.addons.AddonManager.initializeAddonList(); end - movefile(newDir, renamedDir) - folderPath = renamedDir; end - end - methods (Static, Access = private) function pathStr = getDefaultInstallationDirLegacy() - % Note: This method will be removed in a future version (todo). + % Note: This method will be removed in a future version. pathStr = fullfile(nansen.rootpath, 'external'); end end - methods (Access = ?nansen.internal.user.NansenUserSession) - % Note: This method will be removed in a future version (todo). + methods (Static, Access = private) + + function pathStr = getPathForAddonManifest() + %getPathForAddonManifest Get path where local addon list is saved. + nansen.config.addons.AddonManager.ensureUserpathAvailable() + nansenDirectory = fullfile(userpath, 'Nansen'); + if ~isfolder(nansenDirectory); mkdir(nansenDirectory); end + pathStr = fullfile(nansenDirectory, 'installed_addons.json'); + end + + function installResult = createInstallResult(filePath, installationType, toolboxIdentifier) + if nargin < 3 + toolboxIdentifier = ""; + end + + filePath = string(filePath); + installationType = string(installationType); + toolboxIdentifier = string(toolboxIdentifier); + + if isempty(filePath) || any(ismissing(filePath)) + filePath = ""; + end + if isempty(installationType) || any(ismissing(installationType)) + installationType = "folder"; + end + if isempty(toolboxIdentifier) || any(ismissing(toolboxIdentifier)) + toolboxIdentifier = ""; + end + + installResult = struct( ... + 'FilePath', filePath, ... + 'InstallationType', installationType, ... + 'ToolboxIdentifier', toolboxIdentifier); + end + + function value = getCharOrEmpty(stringValue) + stringValue = string(stringValue); + if isempty(stringValue) || any(ismissing(stringValue)) + value = ''; + else + value = char(stringValue); + end + end + end + + methods (Hidden) % For backwards compatibility. Will be removed in future moveExternalToolboxes(obj) % Method in separate file end - methods (Static, Access = ?nansen.internal.user.NansenUserSession) + methods (Static, Hidden) % For backwards compatibility. Will be removed in future function tf = existExternalToolboxInRepository() - % Note: This method will be removed in a future version (todo). + % Note: This method will be removed in a future version. rootDir = fullfile(nansen.rootpath, 'external'); tf = isfolder(fullfile(rootDir, 'general_toolboxes')) || ... isfolder(fullfile(rootDir, 'neuroscience_toolboxes')); diff --git a/code/+nansen/+internal/+dependencies/resolveRequirements.m b/code/+nansen/+internal/+dependencies/resolveRequirements.m index f27d1175..23deb316 100644 --- a/code/+nansen/+internal/+dependencies/resolveRequirements.m +++ b/code/+nansen/+internal/+dependencies/resolveRequirements.m @@ -19,6 +19,9 @@ % Default: false. % TrackedAddons (struct array) - Optional tracked addon records from % AddonManager. Used for richer install/path status checks. +% ManifestPaths (string array) - Explicit manifest file paths. +% When provided, skips automatic manifest discovery and uses +% only the given paths. Useful for testing. % % Output: % resolvedRequirements - struct array with all schema fields plus: @@ -35,9 +38,14 @@ options.RequirementLevels (1,:) string = string.empty options.MissingOnly (1,1) logical = false options.TrackedAddons (1,:) struct = struct.empty(1, 0) + options.ManifestPaths (1,:) string = string.empty end - manifestPaths = collectManifestPaths(options.IncludeCore, options.SelectedModules); + if isempty(options.ManifestPaths) + manifestPaths = collectManifestPaths(options.IncludeCore, options.SelectedModules); + else + manifestPaths = options.ManifestPaths; + end allDependencies = readAllDependencies(manifestPaths); % Filter by scope inclusion diff --git a/tests/+nansen/+fixture/AddonManagerFixture.m b/tests/+nansen/+fixture/AddonManagerFixture.m new file mode 100644 index 00000000..8cd09a80 --- /dev/null +++ b/tests/+nansen/+fixture/AddonManagerFixture.m @@ -0,0 +1,89 @@ +classdef AddonManagerFixture < matlab.unittest.fixtures.Fixture +%AddonManagerFixture Fixture for creating an isolated AddonManager for testing. +% +% Creates a singleton AddonManager backed by a temporary installation +% folder and manifest file. The constructor only loads persisted state +% (no manifest discovery), then the fixture calls refreshManagedAddons +% with explicit test manifest paths. +% +% On teardown, resets the singleton so subsequent tests get a fresh +% instance. +% +% By default, the fixture resolves dependencies from the test manifests +% shipped in tests/+nansen/+fixture/manifests/. Pass custom +% DependencyManifestPaths to override. +% +% Example: +% fixture = testCase.applyFixture(nansen.fixture.AddonManagerFixture); +% manager = fixture.AddonManager; + + properties (SetAccess = private) + % InstallationFolder - Temporary folder for addon installation + InstallationFolder (1,1) string + + % ManifestFilePath - Temporary path for the installed_addons.json + ManifestFilePath (1,1) string + + % AddonManager - The singleton instance created by this fixture + AddonManager + end + + properties (Access = private) + DependencyManifestPaths (1,:) string + end + + methods + function fixture = AddonManagerFixture(options) + %AddonManagerFixture Create a fixture with optional custom manifests. + arguments + options.DependencyManifestPaths (1,:) string = string.empty + end + fixture.DependencyManifestPaths = options.DependencyManifestPaths; + end + end + + methods + function setup(fixture) + import matlab.unittest.fixtures.TemporaryFolderFixture + temporaryFolderFixture = fixture.applyFixture(TemporaryFolderFixture); + fixture.InstallationFolder = fullfile(temporaryFolderFixture.Folder, 'Add-Ons'); + mkdir(fixture.InstallationFolder); + fixture.ManifestFilePath = fullfile( ... + temporaryFolderFixture.Folder, 'installed_addons.json'); + + dependencyManifestPaths = fixture.DependencyManifestPaths; + if isempty(dependencyManifestPaths) + dependencyManifestPaths = fixture.getDefaultTestManifestPaths(); + end + + % Create singleton with clean state (no manifest discovery) + fixture.AddonManager = nansen.config.addons.AddonManager.instance( ... + "reset", fixture.InstallationFolder, fixture.ManifestFilePath); + + % Populate from test manifests only + fixture.AddonManager.refreshManagedAddons( ... + "ManifestPaths", dependencyManifestPaths); + + fixture.addTeardown(@() nansen.config.addons.AddonManager.instance("reset")); + end + end + + methods (Access = protected) + function isCompatibleResult = isCompatible(fixture, other) + %isCompatible Two fixtures are compatible if they use the same manifest paths. + isCompatibleResult = isequal( ... + fixture.DependencyManifestPaths, other.DependencyManifestPaths); + end + end + + methods (Static, Access = private) + function manifestPaths = getDefaultTestManifestPaths() + %getDefaultTestManifestPaths Return paths to the bundled test manifests. + manifestDirectory = fullfile( ... + fileparts(mfilename('fullpath')), 'manifests'); + manifestPaths = string({ ... + fullfile(manifestDirectory, 'test_core_dependencies.nansen.json'), ... + fullfile(manifestDirectory, 'test_module_dependencies.nansen.json') }); + end + end +end diff --git a/tests/+nansen/+fixture/manifests/test_core_dependencies.nansen.json b/tests/+nansen/+fixture/manifests/test_core_dependencies.nansen.json new file mode 100644 index 00000000..86efd05f --- /dev/null +++ b/tests/+nansen/+fixture/manifests/test_core_dependencies.nansen.json @@ -0,0 +1,38 @@ +{ + "_schema_id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev/schemas/dependencies.nansen.json", + "_schema_version": "1.0", + "_type": "NANSEN Dependency Manifest", + "scope": "core", + "scopeId": "core", + "dependencies": [ + { + "name": "TestToolboxA", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "https://github.com/test-org/TestToolboxA", + "description": "Required core community toolbox for testing", + "installCheck": "TestToolboxACheck" + }, + { + "name": "TestToolboxB", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "fex://99999-test-toolbox-b", + "description": "Optional core community toolbox for testing", + "installCheck": "TestToolboxBCheck", + "reason": "Enables optional test feature" + }, + { + "name": "Image Processing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "required", + "reason": "Required MathWorks product for testing" + }, + { + "name": "Parallel Computing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Optional MathWorks product for testing" + } + ] +} diff --git a/tests/+nansen/+fixture/manifests/test_module_dependencies.nansen.json b/tests/+nansen/+fixture/manifests/test_module_dependencies.nansen.json new file mode 100644 index 00000000..c7b67bbb --- /dev/null +++ b/tests/+nansen/+fixture/manifests/test_module_dependencies.nansen.json @@ -0,0 +1,42 @@ +{ + "_schema_id": "https://raw.githubusercontent.com/VervaekeLab/NANSEN/dev/schemas/dependencies.nansen.json", + "_schema_version": "1.0", + "_type": "NANSEN Dependency Manifest", + "scope": "module", + "scopeId": "test.module.alpha", + "dependencies": [ + { + "name": "TestToolboxC", + "dependencyType": "community-toolbox", + "requirementLevel": "required", + "source": "https://github.com/test-org/TestToolboxC", + "description": "Required module community toolbox for testing", + "installCheck": "TestToolboxCCheck" + }, + { + "name": "TestToolboxA", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "source": "https://github.com/test-org/TestToolboxA", + "description": "Duplicate of core dependency at module scope (optional here)", + "installCheck": "TestToolboxACheck" + }, + { + "name": "TestWorkflowTool", + "dependencyType": "community-toolbox", + "requirementLevel": "optional", + "scope": "workflow", + "scopeId": "test.module.alpha.workflow.beta", + "source": "https://github.com/test-org/TestWorkflowTool", + "description": "Workflow-scoped community toolbox for testing", + "installCheck": "TestWorkflowToolCheck", + "reason": "Needed for beta workflow" + }, + { + "name": "Signal Processing Toolbox", + "dependencyType": "mathworks-product", + "requirementLevel": "optional", + "reason": "Optional MathWorks product at module scope" + } + ] +} diff --git a/tests/+nansen/+unittest/AddonManagerTest.m b/tests/+nansen/+unittest/AddonManagerTest.m new file mode 100644 index 00000000..d447d61a --- /dev/null +++ b/tests/+nansen/+unittest/AddonManagerTest.m @@ -0,0 +1,331 @@ +classdef AddonManagerTest < matlab.unittest.TestCase +%AddonManagerTest Tests for the AddonManager singleton. +% +% Tests initialization, manifest loading, dependency refresh, +% installation status tracking, merge/deduplication, and edge cases +% using isolated test manifests. + + properties (Access = private) + Fixture + end + + properties (Constant, Access = private) + TestManifestDirectory = fullfile( ... + fileparts(fileparts(mfilename('fullpath'))), ... + '+fixture', 'manifests') + CoreManifestPath (1,1) string = fullfile( ... + fileparts(fileparts(mfilename('fullpath'))), ... + '+fixture', 'manifests', 'test_core_dependencies.nansen.json') + ModuleManifestPath (1,1) string = fullfile( ... + fileparts(fileparts(mfilename('fullpath'))), ... + '+fixture', 'manifests', 'test_module_dependencies.nansen.json') + end + + methods (TestMethodSetup) + function applyAddonManagerFixture(testCase) + testCase.Fixture = testCase.applyFixture( ... + nansen.fixture.AddonManagerFixture); + end + end + + % --- Initialization & manifest loading --- + + methods (Test) + function createWithEmptyManifest(testCase) + %createWithEmptyManifest Singleton starts with addon list from test manifests. + manager = testCase.Fixture.AddonManager; + testCase.verifyNotEmpty(manager, ... + 'AddonManager instance should be created') + testCase.verifyClass(manager, ... + 'nansen.config.addons.AddonManager') + end + + function installationFolderIsTemporary(testCase) + %installationFolderIsTemporary Installation folder points to temp dir. + manager = testCase.Fixture.AddonManager; + testCase.verifyTrue( ... + contains(manager.InstallationFolder, tempdir) || ... + contains(manager.InstallationFolder, "tmp"), ... + 'Installation folder should be in a temporary location') + end + + function persistAndReloadManifest(testCase) + %persistAndReloadManifest Save, reset, and reload round-trip. + manager = testCase.Fixture.AddonManager; + manager.saveAddonList(); + testCase.verifyTrue(isfile(testCase.Fixture.ManifestFilePath), ... + 'Manifest file should exist after save') + + originalAddonNames = string({manager.AddonList.Name}); + + % Reset with same storage paths to reload persisted data + reloadedManager = nansen.config.addons.AddonManager.instance( ... + "reset", ... + testCase.Fixture.InstallationFolder, ... + testCase.Fixture.ManifestFilePath); + % Refresh from same test manifests + reloadedManager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath]); + reloadedAddonNames = string({reloadedManager.AddonList.Name}); + + testCase.verifyEqual(sort(reloadedAddonNames), sort(originalAddonNames), ... + 'Addon names should survive save/reload round-trip') + end + end + + % --- Refresh from test manifests --- + + methods (Test) + function refreshFromCoreManifest(testCase) + %refreshFromCoreManifest Core test manifest resolves expected entries. + manager = testCase.Fixture.AddonManager; + addonNames = string({manager.AddonList.Name}); + + testCase.verifyTrue(ismember("TestToolboxA", addonNames), ... + 'TestToolboxA should be in addon list') + testCase.verifyTrue(ismember("TestToolboxB", addonNames), ... + 'TestToolboxB should be in addon list') + end + + function coreAddonHasCorrectSource(testCase) + %coreAddonHasCorrectSource Community toolbox source is preserved. + manager = testCase.Fixture.AddonManager; + addonIndex = find(strcmp({manager.AddonList.Name}, 'TestToolboxA')); + testCase.assumeNotEmpty(addonIndex, 'TestToolboxA not found') + + testCase.verifyEqual(string(manager.AddonList(addonIndex).Source), ... + "https://github.com/test-org/TestToolboxA") + end + + function requiredFlagIsSet(testCase) + %requiredFlagIsSet Required addon has IsRequired=true. + manager = testCase.Fixture.AddonManager; + addonIndex = find(strcmp({manager.AddonList.Name}, 'TestToolboxA')); + testCase.assumeNotEmpty(addonIndex) + + testCase.verifyTrue(manager.AddonList(addonIndex).IsRequired, ... + 'TestToolboxA should be marked as required') + end + + function optionalFlagIsSet(testCase) + %optionalFlagIsSet Optional addon has IsRequired=false. + manager = testCase.Fixture.AddonManager; + addonIndex = find(strcmp({manager.AddonList.Name}, 'TestToolboxB')); + testCase.assumeNotEmpty(addonIndex) + + testCase.verifyFalse(manager.AddonList(addonIndex).IsRequired, ... + 'TestToolboxB should be marked as optional') + end + + function refreshWithModuleDependencies(testCase) + %refreshWithModuleDependencies Module deps appear after refresh with module selection. + manager = testCase.Fixture.AddonManager; + manager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath], ... + "SelectedModules", "test.module.alpha"); + + addonNames = string({manager.AddonList.Name}); + testCase.verifyTrue(ismember("TestToolboxC", addonNames), ... + 'TestToolboxC (module dep) should appear after refresh with module') + end + + function mathworksProductsExcludedFromAddonList(testCase) + %mathworksProductsExcludedFromAddonList MathWorks products are not in AddonList. + % refreshManagedAddons filters for community-toolbox only. + manager = testCase.Fixture.AddonManager; + addonNames = string({manager.AddonList.Name}); + + testCase.verifyFalse(ismember("Image Processing Toolbox", addonNames), ... + 'MathWorks products should not appear in AddonList') + testCase.verifyFalse(ismember("Parallel Computing Toolbox", addonNames), ... + 'MathWorks products should not appear in AddonList') + end + end + + % --- Deduplication and merge --- + + methods (Test) + function duplicateAcrossScopesMergesCorrectly(testCase) + %duplicateAcrossScopesMergesCorrectly Same dependency from core+module deduplicates. + manager = testCase.Fixture.AddonManager; + manager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath], ... + "SelectedModules", "test.module.alpha"); + + % TestToolboxA is in both core (required) and module (optional) + matchIndices = find(strcmp({manager.AddonList.Name}, 'TestToolboxA')); + testCase.verifyNumElements(matchIndices, 1, ... + 'TestToolboxA should appear exactly once after deduplication') + end + + function requiredWinsOverOptional(testCase) + %requiredWinsOverOptional Required level wins when same dep appears in multiple scopes. + manager = testCase.Fixture.AddonManager; + manager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath], ... + "SelectedModules", "test.module.alpha"); + + addonIndex = find(strcmp({manager.AddonList.Name}, 'TestToolboxA')); + testCase.assumeNotEmpty(addonIndex) + + testCase.verifyTrue(manager.AddonList(addonIndex).IsRequired, ... + 'TestToolboxA should be required (core=required wins over module=optional)') + end + + function existingAddonPreservesInstallState(testCase) + %existingAddonPreservesInstallState Installed addon stays installed after refresh. + % Seeds a manifest file with one addon marked as installed, + % creates a fresh singleton, and verifies the install state + % survives a refreshManagedAddons call. + import matlab.unittest.fixtures.TemporaryFolderFixture + temporaryFolderFixture = testCase.applyFixture(TemporaryFolderFixture); + installationFolder = fullfile(temporaryFolderFixture.Folder, 'Add-Ons'); + mkdir(installationFolder); + manifestFilePath = fullfile(temporaryFolderFixture.Folder, 'installed_addons.json'); + + % Create a fake installed addon folder + fakeAddonFolder = fullfile(installationFolder, 'TestToolboxA'); + mkdir(fakeAddonFolder); + testCase.addTeardown(@() rmpath(fakeAddonFolder)); + + % Write a pre-seeded manifest with one installed addon + defaultEntry = nansen.config.addons.AddonManager.DefaultAddonEntry; + addonEntry = defaultEntry; + addonEntry.Name = 'TestToolboxA'; + addonEntry.IsInstalled = true; + addonEntry.FilePath = char(fakeAddonFolder); + addonEntry.InstallationType = 'folder'; + addonEntry.Source = 'https://github.com/test-org/TestToolboxA'; + addonEntry.InstallCheck = 'TestToolboxACheck'; + savedData = struct( ... + 'type', 'Nansen Configuration: List of Installed Addons', ... + 'description', 'Test manifest', ... + 'AddonList', addonEntry); + jsonText = jsonencode(savedData, 'PrettyPrint', true); + fileIdentifier = fopen(manifestFilePath, 'w'); + fwrite(fileIdentifier, jsonText, 'char'); + fclose(fileIdentifier); + + % Create singleton from pre-seeded manifest (no discovery) + manager = nansen.config.addons.AddonManager.instance( ... + "reset", installationFolder, manifestFilePath); + % Refresh from test manifest — should preserve install state + manager.refreshManagedAddons( ... + "ManifestPaths", testCase.CoreManifestPath); + addonIndex = find(strcmp({manager.AddonList.Name}, 'TestToolboxA')); + testCase.assumeNotEmpty(addonIndex, 'TestToolboxA should be in list') + testCase.verifyTrue(manager.AddonList(addonIndex).IsInstalled, ... + 'Pre-seeded installation state should be preserved after refresh') + end + + function newDependencyAddedOnRefresh(testCase) + %newDependencyAddedOnRefresh A dependency not previously tracked appears after refresh. + manager = testCase.Fixture.AddonManager; + + % Initially only core manifest was used (default fixture) + addonNamesBefore = string({manager.AddonList.Name}); + testCase.verifyFalse(ismember("TestToolboxC", addonNamesBefore), ... + 'TestToolboxC should not be present before module refresh') + + % Refresh with module manifest + manager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath], ... + "SelectedModules", "test.module.alpha"); + + addonNamesAfter = string({manager.AddonList.Name}); + testCase.verifyTrue(ismember("TestToolboxC", addonNamesAfter), ... + 'TestToolboxC should appear after module refresh') + end + end + + % --- Installation status --- + + methods (Test) + function uninstalledAddonReportsFalse(testCase) + %uninstalledAddonReportsFalse isAddonInstalled returns false for missing addon. + manager = testCase.Fixture.AddonManager; + testCase.verifyFalse(manager.isAddonInstalled('TestToolboxA'), ... + 'TestToolboxA should not be installed in test environment') + end + + function isAddonInstalledReturnsFalseForUnknown(testCase) + %isAddonInstalledReturnsFalseForUnknown Unknown addon name returns false. + manager = testCase.Fixture.AddonManager; + testCase.verifyFalse(manager.isAddonInstalled('NonExistentToolbox'), ... + 'Unknown addon should return false') + end + + function saveAddonListCreatesValidJson(testCase) + %saveAddonListCreatesValidJson Saved manifest is valid JSON with expected structure. + manager = testCase.Fixture.AddonManager; + manager.saveAddonList(); + + jsonText = fileread(testCase.Fixture.ManifestFilePath); + savedData = jsondecode(jsonText); + + testCase.verifyTrue(isfield(savedData, 'AddonList'), ... + 'Saved data should have AddonList field') + testCase.verifyTrue(isfield(savedData, 'type'), ... + 'Saved data should have type field') + end + + function markDirtyAndClean(testCase) + %markDirtyAndClean IsDirty flag tracks unsaved changes. + manager = testCase.Fixture.AddonManager; + manager.markDirty(); + testCase.verifyTrue(manager.IsDirty, ... + 'Manager should be dirty after markDirty') + + manager.saveAddonList(); + testCase.verifyFalse(manager.IsDirty, ... + 'Manager should be clean after save') + end + end + + % --- Edge cases --- + + methods (Test) + function isAddonInstalledCaseInsensitive(testCase) + %isAddonInstalledCaseInsensitive Addon lookup by name is case-insensitive. + % isAddonInstalled uses case-sensitive strcmp for the name check, + % so this test documents the current behavior. + manager = testCase.Fixture.AddonManager; + testCase.assumeTrue(any(strcmp({manager.AddonList.Name}, 'TestToolboxA'))) + + % isAddonInstalled checks exact name match first, then uses + % getAddonIndex (case-insensitive). With exact name, lookup works. + resultExact = manager.isAddonInstalled('TestToolboxA'); + testCase.verifyFalse(resultExact, ... + 'TestToolboxA is not installed but name should be found') + end + + function downloadUnknownAddonThrowsError(testCase) + %downloadUnknownAddonThrowsError Unknown addon name causes error. + manager = testCase.Fixture.AddonManager; + testCase.verifyError( ... + @() manager.downloadAddon('CompletelyUnknownToolbox', false, true), ... + 'NANSEN:AddonManager:NotFound') + end + + function managedAddonsReturnsTable(testCase) + %managedAddonsReturnsTable ManagedAddons property returns a table. + manager = testCase.Fixture.AddonManager; + managedAddons = manager.ManagedAddons; + testCase.verifyClass(managedAddons, 'table') + testCase.verifyTrue(ismember('Name', managedAddons.Properties.VariableNames), ... + 'ManagedAddons table should have Name column') + end + + function workflowScopedDepsRequireWorkflowSelection(testCase) + %workflowScopedDepsRequireWorkflowSelection Workflow deps excluded without selection. + manager = testCase.Fixture.AddonManager; + manager.refreshManagedAddons( ... + "ManifestPaths", [testCase.CoreManifestPath, testCase.ModuleManifestPath], ... + "SelectedModules", "test.module.alpha"); + + addonNames = string({manager.AddonList.Name}); + testCase.verifyFalse(ismember("TestWorkflowTool", addonNames), ... + 'Workflow-scoped deps should not appear without SelectedWorkflows') + end + end +end From 3a48f19b1ad2cb2d6434fb22ef90ac0c5d418c8e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2026 17:35:46 +0000 Subject: [PATCH 29/29] Update GitHub badges --- .github/badges/code_issues.svg | 2 +- .github/badges/tests.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/badges/code_issues.svg b/.github/badges/code_issues.svg index a6d761ea..d259430f 100644 --- a/.github/badges/code_issues.svg +++ b/.github/badges/code_issues.svg @@ -1 +1 @@ -code issuescode issues17971797 \ No newline at end of file +code issuescode issues17791779 \ No newline at end of file diff --git a/.github/badges/tests.svg b/.github/badges/tests.svg index ed4f6ca1..41b70f07 100644 --- a/.github/badges/tests.svg +++ b/.github/badges/tests.svg @@ -1 +1 @@ -teststests112 passed112 passed \ No newline at end of file +teststests148 passed148 passed \ No newline at end of file