versao nrgocios
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-10-16 13:06:58 +02:00
parent 6a76aac80f
commit 2d23157e40
17260 changed files with 4150820 additions and 43 deletions
@@ -38,10 +38,13 @@ class ReferenceCatalogController extends Controller
}
if ($catalog === 'economic-activities') {
$rules['sector_id'] = ['nullable', 'integer', 'exists:sectors,id'];
$rules['origin'] = ['nullable', 'in:portal,cae'];
}
$data = $request->validate($rules);
$versionQuery = DB::table('reference_catalog_versions')->where('catalog_code', $catalog)->where('locale', 'pt-MZ');
$cae = $catalog === 'economic-activities' && ($data['origin'] ?? 'portal') === 'cae';
$versionQuery = DB::table('reference_catalog_versions')->where('catalog_code', $cae ? 'economic-activities-cae' : $catalog)->where('locale', 'pt-MZ');
if ($cae && ! app(\App\Services\EconomicReferenceCatalog::class)->available()) { $versionQuery->whereRaw('false'); }
if (isset($data['version'])) {
$versionQuery->where('version_no', $data['version'])->whereIn('status', ['published', 'retired']);
} else {
@@ -78,6 +81,10 @@ class ReferenceCatalogController extends Controller
$page = $query->orderBy('code')->orderBy('id')->paginate($data['per_page'] ?? 20)->withQueryString();
$items = collect($page->items())->map(fn (object $row): array => $this->present($catalog, (array) $row))->values();
if ($cae) {
$paths = app(\App\Services\EconomicReferenceCatalog::class)->activities()->keyBy('id');
$items = $items->map(fn ($row) => [...$row, 'level' => $paths[$row['id']]->level, 'path' => $paths[$row['id']]->path, 'source_version' => $paths[$row['id']]->source_version, 'edition' => 'not_determined', 'divergence' => '600/579 documentalmente aberta']);
}
return response()->json([
'data' => $items,
@@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers;
use App\Services\EconomicReferenceInstallation;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class EconomicReferenceController extends Controller
{
public function preview(Request $request, EconomicReferenceInstallation $service): JsonResponse|Response
{
$plan = $service->preview($request->user());
return $request->expectsJson() ? response()->json(['plan' => $plan]) : Inertia::render('management/economic-references', ['plan' => $plan]);
}
public function apply(Request $request, string $operation, EconomicReferenceInstallation $service): JsonResponse
{
return response()->json(['receipt' => $service->apply($request->user(), $operation, $request->all())]);
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
namespace App\Services;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/** Shared read contract. It deliberately has no dependency on the installation controller/service. */
class EconomicReferenceCatalog
{
public const LOT = 'lot-01';
public const SOURCE = 'economic-reference-lot-01';
public const MANIFEST_SHA256 = 'ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04';
public function manifest(): array
{
$file = database_path('data/economic-references-lot-01.json');
abort_unless(is_file($file) && hash_equals(self::MANIFEST_SHA256, hash_file('sha256', $file)), 422, 'Manifesto económico ausente ou diferente da revisão delimitada.');
$manifest = json_decode(file_get_contents($file), true, 512, JSON_THROW_ON_ERROR);
abort_unless(($manifest['lot'] ?? '') === self::LOT && count($manifest['activities'] ?? []) === 5
&& count($manifest['chains'] ?? []) === 5 && count($manifest['links'] ?? []) === 4, 422, 'Lote económico fora do âmbito.');
return $manifest;
}
public function schemaAvailable(): bool
{
return Schema::hasColumn('economic_activities', 'metadata');
}
public function publicationState(): string
{
$event = DB::table('audit_events')->where('source_system', self::SOURCE)->whereIn('action', ['publish', 'withdraw'])
->orderByDesc('occurred_at')->orderByDesc('id')->first(['action']);
return $event?->action === 'publish' ? 'published' : ($event ? 'withdrawn' : 'private');
}
public function available(): bool
{
if (! $this->schemaAvailable() || $this->publicationState() !== 'published') { return false; }
return DB::table('reference_catalog_versions')->where('id', $this->manifest()['catalog']['id'])->where('status', 'published')->exists();
}
public function constrain(Builder $query, string $kind): Builder
{
$manifest = $this->manifest();
if (in_array($kind, ['activity', 'chain'], true) && ! $this->available()) {
$query->whereNotIn('id', array_column($manifest[$kind === 'activity' ? 'activities' : 'chains'], 'id'));
}
return $query;
}
/** A withdrawn published reference can be retained verbatim, never introduced as a new choice. */
public function historicalTarget(string $kind, string $id): bool
{
if (! in_array($kind, ['activity', 'chain'], true) || ! $this->schemaAvailable()) { return false; }
$manifest = $this->manifest();
if (! in_array($id, array_column($manifest[$kind === 'activity' ? 'activities' : 'chains'], 'id'), true)) { return false; }
if (! DB::table('audit_events')->where('source_system', self::SOURCE)->where('action', 'publish')->exists()) { return false; }
return $kind === 'activity'
? DB::table('economic_activities')->where('id', $id)->where('status', 'published')->exists()
: DB::table('value_chains')->where('id', $id)->whereNull('deleted_at')->exists();
}
public function activities(array $historicalIds = []): Collection
{
$rows = DB::table('economic_activities')->where('status', 'published')->get();
$allowed = $this->constrain(DB::table('economic_activities')->where('status', 'published'), 'activity')->pluck('id')->all();
// A used published UUID may still be shown after withdrawal, together with its exact ancestors.
$byId = $rows->keyBy('id');
foreach ($historicalIds as $id) {
$seen = [];
while (isset($byId[$id]) && ! isset($seen[$id])) {
$allowed[] = $id; $seen[$id] = true; $id = $byId[$id]->parent_id;
}
}
$available = $this->available();
return $rows->filter(fn ($r) => in_array($r->id, $allowed, true))->map(function ($row) use ($byId, $available) {
$meta = property_exists($row, 'metadata') ? json_decode($row->metadata, true) : [];
$path = []; $current = $row; $seen = [];
while ($current && ! isset($seen[$current->id])) {
$seen[$current->id] = true;
array_unshift($path, ['id' => $current->id, 'code' => $current->code, 'label' => $current->label_pt_mz]);
$current = $current->parent_id ? ($byId[$current->parent_id] ?? null) : null;
}
$isLot = ($meta['lot'] ?? '') === self::LOT;
return (object) ['id' => $row->id, 'parent_id' => $row->parent_id, 'sector_id' => $row->sector_id,
'label_pt_mz' => $row->label_pt_mz, 'catalog_version_id' => $row->catalog_version_id, 'code' => $row->code,
'level' => $meta['level'] ?? null, 'path' => $path, 'display_label' => implode(' → ', array_column($path, 'code')).' — '.$row->label_pt_mz,
'source_version' => $meta['source_version'] ?? null, 'edition' => $meta['edition'] ?? null,
'historical_only' => $isLot && ! $available];
})->values();
}
public function validHierarchy(int $sectorId, ?string $subsectorId, ?string $activityId, bool $historical = false): bool
{
if (! $subsectorId || ! $activityId) { return false; }
$sector = DB::table('sectors')->where('id', $sectorId)->whereNull('deleted_at')->where('is_active', true)->exists();
$subsector = DB::table('economic_activities')->where('id', $subsectorId)->where('status', 'published')->first();
$activity = DB::table('economic_activities')->where('id', $activityId)->where('status', 'published')->first();
if (! $sector || ! $subsector || ! $activity || $activity->catalog_version_id !== $subsector->catalog_version_id) { return false; }
$manifest = $this->manifest();
if ($activity->catalog_version_id !== $manifest['catalog']['id']) {
$root = $subsector->parent_id ? DB::table('economic_activities')->where('id', $subsector->parent_id)->where('status', 'published')->first() : null;
return $root && (int) $root->sector_id === $sectorId && $activity->parent_id === $subsector->id;
}
if ((! $this->available() && ! $historical) || $sectorId !== (int) $manifest['existing']['sector']['id']
|| $subsector->code !== '01' || $activity->code !== '01120') { return false; }
$current = $activity; $codes = []; $seen = [];
while ($current && ! isset($seen[$current->id])) {
$seen[$current->id] = true; array_unshift($codes, $current->code);
$current = $current->parent_id ? DB::table('economic_activities')->where('id', $current->parent_id)->where('catalog_version_id', $activity->catalog_version_id)->where('status', 'published')->first() : null;
}
return $codes === ['A', '01', '011', '0112', '01120'] && (int) $subsector->sector_id === $sectorId && (int) $activity->sector_id === $sectorId;
}
}
@@ -0,0 +1,291 @@
<?php
namespace App\Services;
use App\Models\User;
use App\Services\Malware\MalwareScanner;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\HttpException;
/** Bounded authenticated extension. No generic seeding, arbitrary path or caller-supplied actor. */
class EconomicReferenceInstallation
{
public const MIGRATION = '2026_10_16_120000_extend_economic_reference_hierarchy';
public const OPERATIONS = ['schema', 'import', 'publish', 'withdraw'];
public function files(): array
{
return ['app/Services/EconomicReferenceCatalog.php', 'app/Services/EconomicReferenceInstallation.php',
'app/Http/Controllers/EconomicReferenceController.php', 'app/Services/OpportunityCanonicalContract.php',
'app/Services/OpportunityClassification.php', 'app/Services/ExistingBusinessClassification.php',
'app/Http/Controllers/Api/V1/ReferenceCatalogController.php', 'resources/js/components/opportunity-canonical-fields.tsx',
'resources/js/components/opportunity-classification.tsx', 'resources/js/pages/management/economic-references.tsx',
'routes/web.php', 'database/migrations/'.self::MIGRATION.'.php', 'database/data/economic-references-lot-01.json'];
}
public function fingerprint(): string
{
return hash('sha256', json_encode(array_map(fn ($p) => [$p, hash_file('sha256', base_path($p))], $this->files()), JSON_THROW_ON_ERROR));
}
private function directory(): string { return storage_path('app/private/investmoz-v2/economic-references/lot-01'); }
private function target(): array
{
return (array) DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port');
}
private function qa(array $target): bool
{
return app()->environment('testing') && str_ends_with($target['database'], '_test') && (int) $target['port'] === 55441
&& config('database.connections.pgsql.host') === '127.0.0.1' && ! config('database.connections.pgsql.url');
}
private function authorize(User $actor, bool $write = false, string $operation = ''): void
{
abort_unless($actor->hasVerifiedEmail() && $actor->can('manage-portal'), 403, 'Acesso reservado à gestão autorizada.');
if (! $write) { return; }
$access = app(PortalProfileAccess::class);
abort_if($access->has($actor, 'auditor'), 403, 'A restrição de Auditor permite apenas consulta.');
abort_unless($access->mfa($actor), 403, 'Conclua MFA nesta sessão para executar esta ação.');
if ($operation === 'schema') { app(PortalProfileInstallation::class)->authorize($actor, true); }
abort_unless(! app()->environment('testing') || $this->qa($this->target()), 403, 'Alvo QA isolado inválido.');
}
private function evidence(array $target, string $code, string $operation): array
{
if ($this->qa($target)) { return ['ready' => true, 'mode' => 'isolated_QA', 'date' => null]; }
if (app()->environment('testing')) { return ['ready' => false, 'mode' => 'invalid_QA', 'date' => null]; }
$path = $this->directory().'/readiness.json';
$proof = is_file($path) ? json_decode(file_get_contents($path), true) : [];
$date = strtotime($proof['verified_at'] ?? '');
$permission = $proof['active_authorization'] ?? [];
$ready = ! config('database.connections.pgsql.url') && in_array(config('database.connections.pgsql.host'), ['127.0.0.1', 'localhost'], true)
&& $target['database'] === 'investemoz' && (int) $target['port'] === 5432
&& ($proof['target']['database'] ?? '') === $target['database'] && (int) ($proof['target']['port'] ?? 0) === (int) $target['port']
&& ($proof['code_hash'] ?? '') === $code && ($proof['manifest_sha256'] ?? '') === EconomicReferenceCatalog::MANIFEST_SHA256
&& $date !== false && $date <= time() && $date >= time() - 86400
&& ($proof['restore_verified'] ?? false) && ($proof['files_verified'] ?? false)
&& ($proof['qa_passed'] ?? false) && ($proof['compatibility_verified'] ?? false)
&& str_ends_with($proof['restore_target']['database'] ?? '', '_test') && (int) ($proof['restore_target']['port'] ?? 0) === 55441
&& is_file($proof['dump_path'] ?? '') && is_file($proof['files_path'] ?? '')
&& hash_equals($proof['dump_sha256'] ?? '', hash_file('sha256', $proof['dump_path']))
&& hash_equals($proof['files_sha256'] ?? '', hash_file('sha256', $proof['files_path']))
&& ($permission['decision_record'] ?? '') !== '' && ($permission['code_hash'] ?? '') === $code
&& ($permission['manifest_sha256'] ?? '') === EconomicReferenceCatalog::MANIFEST_SHA256
&& in_array($operation, $permission['operations'] ?? [], true);
return ['ready' => $ready, 'mode' => 'active_requires_own_authorization_and_fresh_proof', 'date' => $proof['verified_at'] ?? null,
'proof_hash' => is_file($path) ? hash_file('sha256', $path) : null];
}
/** No source scan/write in preview. Paths are fixed, private and confined to this lot. */
private function sources(array $manifest): array
{
$root = realpath($this->directory()); $sources = [];
foreach ($manifest['sources'] as $entry) {
$path = $root ? realpath($root.DIRECTORY_SEPARATOR.$entry['relative_path']) : false;
$inside = $path && str_starts_with(strtolower(str_replace('\\', '/', $path)), strtolower(str_replace('\\', '/', $root)).'/');
$matches = $inside && is_file($path) && filesize($path) === $entry['bytes'] && hash_equals($entry['sha256'], hash_file('sha256', $path));
$sources[] = ['name' => $entry['name'], 'sha256' => $entry['sha256'], 'bytes' => $entry['bytes'], 'ready' => (bool) $matches];
}
return $sources;
}
private function referenceRows(array $manifest): array
{
$rows = [['table' => 'reference_catalog_versions', 'data' => $manifest['catalog']]];
foreach (['activities' => 'economic_activities', 'chains' => 'value_chains', 'links' => 'value_chain_links'] as $group => $table) {
foreach ($manifest[$group] as $row) { $rows[] = ['table' => $table, 'data' => $row]; }
}
return $rows;
}
private function createdHere(string $id): bool
{
return DB::table('audit_events')->where('source_system', EconomicReferenceCatalog::SOURCE)->where('action', 'import')
->whereRaw("after_data->'result'->'changed' @> ?::jsonb", [json_encode([$id])])->exists();
}
private function references(array $manifest, bool $schemaReady): array
{
$results = [];
foreach ($this->referenceRows($manifest) as $row) {
$expected = $row['data']; $table = $row['table'];
$current = DB::table($table)->where('id', $expected['id'])->first();
$conflict = false;
foreach ($expected as $key => $value) {
if (! $current || ($key === 'metadata' && ! $schemaReady)) { continue; }
if ($key === 'status') { $conflict = $conflict || ! in_array($current->$key, ['draft', 'published'], true); continue; }
if ($key === 'data_classification') { $conflict = $conflict || ! in_array($current->$key, ['internal', 'public'], true); continue; }
$actual = $key === 'metadata' ? json_decode($current->$key, true) : $current->$key;
if (OpportunityCanonicalValue::hash($actual) !== OpportunityCanonicalValue::hash($value)) { $conflict = true; }
}
$identity = DB::table($table)->where('id', '!=', $expected['id']);
if ($table === 'reference_catalog_versions') { $identity->where('catalog_code', $expected['catalog_code'])->where('version_no', $expected['version_no'])->where('locale', $expected['locale']); }
elseif ($table === 'economic_activities') { $identity->where('catalog_version_id', $expected['catalog_version_id'])->where('code', $expected['code']); }
else { $identity->where('source_system', $expected['source_system'])->where('external_id', $expected['external_id']); }
$conflict = $conflict || $identity->exists();
if ($table === 'value_chains') {
$conflict = $conflict || DB::table($table)->where('id', '!=', $expected['id'])->where('cluster_id', $expected['cluster_id'])->where('code', $expected['code'])->whereNull('deleted_at')->exists();
}
$results[] = ['table' => $table, 'id' => $expected['id'], 'code' => $expected['code'] ?? $expected['external_id'] ?? $expected['catalog_code'],
'status' => $conflict ? 'conflict' : ($current ? 'reuse' : 'insert'), 'current_hash' => $current ? OpportunityCanonicalValue::hash((array) $current) : null,
'current_visibility' => $current?->status ?? $current?->data_classification ?? null];
}
return $results;
}
public function preview(User $actor): array
{
$this->authorize($actor);
$catalog = app(EconomicReferenceCatalog::class); $manifest = $catalog->manifest();
$target = $this->target(); $code = $this->fingerprint();
$ledger = DB::table('migrations')->where('migration', self::MIGRATION)->exists();
$column = $catalog->schemaAvailable();
$unique = DB::selectOne("SELECT 1 FROM pg_constraint WHERE conrelid='public.economic_activities'::regclass AND conname='economic_activities_sector_uq'") !== null;
$sectorNullable = DB::selectOne("SELECT is_nullable FROM information_schema.columns WHERE table_schema='public' AND table_name='economic_activities' AND column_name='sector_id'")?->is_nullable === 'YES';
$index = DB::selectOne("SELECT 1 FROM pg_indexes WHERE schemaname='public' AND indexname='economic_activities_sector_idx'") !== null;
$installed = $ledger && $column && ! $unique && $sectorNullable && $index;
$consistent = $installed || (! $ledger && ! $column && $unique && ! $sectorNullable && ! $index);
$rows = $this->references($manifest, $column); $sources = $this->sources($manifest); $reasons = [];
foreach (['sector' => 'sectors', 'cluster' => 'economic_clusters'] as $name => $table) {
$expected = $manifest['existing'][$name]; $record = DB::table($table)->where('id', $expected['id'])->whereNull('deleted_at')->first();
foreach (array_filter($expected, fn ($v) => $v !== null) as $field => $value) {
if (! $record || (string) ($record->$field ?? '') !== (string) $value) { $reasons[] = 'Identidade/atributos do '.$name.' divergentes do manifesto; não foi usada semelhança de nomes.'; break; }
}
}
if (! $consistent) { $reasons[] = 'Ledger e esquema divergentes; reconciliar antes de instalar.'; }
if (collect($rows)->contains('status', 'conflict')) { $reasons[] = 'Conflito de identidade/versão: não será aplicado parcialmente.'; }
if (collect($sources)->contains('ready', false)) { $reasons[] = 'Exemplar privado ausente ou com bytes diferentes.'; }
$imported = ! collect($rows)->contains(fn ($r) => $r['status'] !== 'reuse');
$scanPath = $this->directory().'/scans.json';
$scan = is_file($scanPath) ? json_decode(file_get_contents($scanPath), true) : null;
$state = ['target' => $target, 'code_hash' => $code, 'manifest_sha256' => EconomicReferenceCatalog::MANIFEST_SHA256,
'migration' => self::MIGRATION, 'installed' => $installed, 'consistent' => $consistent, 'imported' => $imported,
'publication' => $catalog->publicationState(), 'rows' => $rows, 'sources' => $sources, 'scan' => $scan,
'divergence' => $manifest['divergence'], 'convention' => $manifest['convention'], 'common_reasons' => $reasons];
$operations = [];
foreach (self::OPERATIONS as $operation) {
$why = $reasons;
try { $this->authorize($actor, true, $operation); } catch (HttpException $e) { $why[] = $e->getMessage(); }
$evidence = $this->evidence($target, $code, $operation);
if (! $evidence['ready']) { $why[] = 'Decisão própria do ativo e prova fresca desta revisão/alvo/backup/restauro necessárias.'; }
if ($operation !== 'schema' && ! $installed) { $why[] = 'Instale primeiro o esquema nominal.'; }
if (in_array($operation, ['publish', 'withdraw'], true) && ! $imported) { $why[] = 'Importação privada completa necessária antes de publicar/retirar.'; }
if (in_array($operation, ['publish', 'withdraw'], true) && ! DB::table('audit_events')->where('source_system', EconomicReferenceCatalog::SOURCE)->where('action', 'import')->where('after_data->result->manifest_sha256', EconomicReferenceCatalog::MANIFEST_SHA256)->exists()) {
$why[] = 'Execute a importação privada autenticada, inclusive para registos reutilizados.';
}
if ($operation === 'withdraw' && $state['publication'] === 'private') { $why[] = 'O lote ainda não teve publicação para retirar.'; }
if ($operation === 'withdraw' && collect($rows)->contains(fn ($r) => $r['status'] === 'reuse'
&& in_array($r['current_visibility'], ['public', 'published'], true) && ! $this->createdHere($r['id']))) {
$why[] = 'Há referências anteriores já públicas reutilizadas: reconciliar o mapa de retirada antes de agir.';
}
$token = hash_hmac('sha256', OpportunityCanonicalValue::hash([$actor->id, session()->getId(), $operation, $state, $evidence]), config('app.key'));
$operations[$operation] = ['ready' => $why === [], 'reasons' => array_values(array_unique($why)), 'hash' => $token, 'backupDate' => $evidence['date'], 'evidence_mode' => $evidence['mode']];
}
return [...$state, 'operations' => $operations];
}
private function scan(array $manifest): array
{
$directory = realpath($this->directory()); $records = [];
abort_unless($directory, 422, 'Área privada do lote indisponível.');
$paths = [['name' => 'manifesto', 'path' => database_path('data/economic-references-lot-01.json'), 'sha256' => EconomicReferenceCatalog::MANIFEST_SHA256]];
foreach ($manifest['sources'] as $source) { $paths[] = ['name' => $source['name'], 'path' => $directory.'/'.$source['relative_path'], 'sha256' => $source['sha256']]; }
foreach ($paths as $file) {
abort_unless(is_file($file['path']) && hash_equals($file['sha256'], hash_file('sha256', $file['path'])), 409, 'Originais alterados após prévia.');
// Scanner's path confinement uses the private source directory; manifest is scanned via a private exact copy.
$path = $file['path'];
if ($file['name'] === 'manifesto') { $path = $directory.'/manifest-scanned.json'; file_put_contents($path, file_get_contents($file['path'])); }
$result = app(MalwareScanner::class)->scan($path, filesize($path), $directory);
if ($result['signatures_at'] instanceof \DateTimeInterface) { $result['signatures_at'] = $result['signatures_at']->format(DATE_ATOM); }
$records[] = ['name' => $file['name'], 'sha256' => $file['sha256'], 'scan' => $result];
abort_unless($result['result'] === 'clean', 423, 'Scan não concluído ou não limpo para '.$file['name'].'. Nenhuma referência foi importada/publicada.');
abort_unless(hash_equals($file['sha256'], hash_file('sha256', $file['path'])) && hash_equals($file['sha256'], hash_file('sha256', $path)), 409, 'Bytes alterados durante o scan.');
}
$proof = ['at' => now()->toIso8601String(), 'manifest_sha256' => EconomicReferenceCatalog::MANIFEST_SHA256, 'files' => $records];
file_put_contents($directory.'/scans.json', json_encode($proof, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR));
return $proof;
}
public function apply(User $actor, string $operation, array $input): array
{
abort_unless(in_array($operation, self::OPERATIONS, true), 404);
$this->authorize($actor, true, $operation);
abort_if(array_diff(array_keys($input), ['hash', 'idempotency_key', 'confirm', 'reason', '_token']), 422, 'Campo de ator, manifesto ou conteúdo arbitrário não permitido.');
$data = Validator::make($input, ['hash' => 'required|string|size:64', 'idempotency_key' => 'required|uuid', 'confirm' => 'required|accepted', 'reason' => 'required|string|min:20|max:1000'])->validate();
return DB::transaction(function () use ($actor, $operation, $data) {
DB::select('SELECT pg_advisory_xact_lock(161026,120000)');
$requestHash = OpportunityCanonicalValue::hash([$operation, $data]);
$old = DB::table('audit_events')->where('source_system', EconomicReferenceCatalog::SOURCE)->where('correlation_id', $data['idempotency_key'])->first();
if ($old) {
$receipt = json_decode($old->after_data, true, 512, JSON_THROW_ON_ERROR);
abort_unless((int) $old->actor_user_id === $actor->id && hash_equals($receipt['request_hash'], $requestHash), 409, 'Chave de repetição já usada com ator/conteúdo diferentes.');
return [...$receipt['result'], 'replayed' => true, 'current_publication' => app(EconomicReferenceCatalog::class)->publicationState()];
}
$plan = $this->preview($actor); $phase = $plan['operations'][$operation];
abort_unless(hash_equals($phase['hash'], $data['hash']), 409, 'Alvo, ator, revisão ou estado alterados; consulte nova prévia.');
abort_unless($phase['ready'], 422, implode(' ', $phase['reasons']));
$manifest = app(EconomicReferenceCatalog::class)->manifest(); $changed = []; $reused = [];
foreach ($this->referenceRows($manifest) as $row) { DB::table($row['table'])->where('id', $row['data']['id'])->lockForUpdate()->first(); }
DB::table('sectors')->where('id', $manifest['existing']['sector']['id'])->lockForUpdate()->first();
DB::table('economic_clusters')->where('id', $manifest['existing']['cluster']['id'])->lockForUpdate()->first();
// Recheck after locks in case another approved writer changed a reused master.
abort_unless($this->preview($actor)['operations'][$operation]['hash'] === $phase['hash'], 409, 'Referências alteradas durante a preparação da operação.');
if ($operation === 'schema' && ! $plan['installed']) {
config(['economic_references.authenticated_installation' => true]);
try { abort_unless(Artisan::call('migrate', ['--path' => 'database/migrations/'.self::MIGRATION.'.php', '--force' => true]) === 0, 500, 'Falha na migration nominal.'); }
finally { config(['economic_references.authenticated_installation' => false]); }
abort_unless($this->preview($actor)['installed'], 500, 'Esquema instalado não corresponde ao plano.');
$changed[] = self::MIGRATION;
} elseif ($operation === 'import') {
$scan = $this->scan($manifest);
foreach ($this->referenceRows($manifest) as $i => $row) {
if ($plan['rows'][$i]['status'] === 'reuse') { $reused[] = $row['data']['id']; continue; }
$values = $row['data']; if (isset($values['metadata'])) { $values['metadata'] = json_encode($values['metadata'], JSON_THROW_ON_ERROR); }
DB::table($row['table'])->insert([...$values, 'created_at' => now(), 'updated_at' => now()]);
$changed[] = $values['id'];
}
} elseif ($operation === 'publish' || $operation === 'withdraw') {
if ($operation === 'publish') { $scan = $this->scan($manifest); }
foreach ($this->referenceRows($manifest) as $row) {
$table = $row['table']; $record = DB::table($table)->where('id', $row['data']['id'])->lockForUpdate()->first();
if (in_array($table, ['reference_catalog_versions', 'economic_activities'], true)) {
if ($operation === 'publish' && $record->status === 'draft') {
DB::table($table)->where('id', $record->id)->update(['status' => 'published', 'updated_at' => now()]); $changed[] = $record->id;
} else { $reused[] = $record->id; }
} else {
$visibility = $operation === 'publish' ? 'public' : 'internal';
// Withdrawal touches only objects this importer created, never pre-existing public references.
$createdHere = $this->createdHere($record->id);
if ($operation === 'withdraw' && ! $createdHere) { $reused[] = $record->id; continue; }
if ($record->data_classification !== $visibility) { DB::table($table)->where('id', $record->id)->update(['data_classification' => $visibility, 'updated_at' => now()]); $changed[] = $record->id; }
else { $reused[] = $record->id; }
}
}
}
$result = ['operation' => $operation, 'lot' => 'lot-01', 'target' => $plan['target'], 'changed' => $changed, 'reused' => $reused,
'manifest_sha256' => EconomicReferenceCatalog::MANIFEST_SHA256, 'code_hash' => $plan['code_hash'], 'replayed' => false,
'publications' => $operation === 'publish' ? 'references only; no investment or original source publication' : 'none', 'business_records_changed' => 0,
'receipt' => $data['idempotency_key'], 'scan' => $scan ?? null];
if ($operation === 'import') { $result['previously_public'] = array_values(array_column(array_filter($plan['rows'], fn ($r) => $r['status'] === 'reuse' && in_array($r['current_visibility'], ['public', 'published'], true) && ! $this->createdHere($r['id'])), 'id')); }
DB::table('audit_events')->insert(['source_system' => EconomicReferenceCatalog::SOURCE, 'entity_type' => 'economic-reference-batch', 'entity_id' => $manifest['catalog']['id'],
'actor_user_id' => $actor->id, 'correlation_id' => $data['idempotency_key'], 'action' => $operation, 'data_classification' => 'restricted',
'after_data' => json_encode(['request_hash' => $requestHash, 'reason' => $data['reason'], 'result' => $result], JSON_THROW_ON_ERROR)]);
return $result;
});
}
}
@@ -84,7 +84,7 @@ class ExistingBusinessClassification
if (($kind === 'sector' && ! ctype_digit($row['related_id'])) || ($kind !== 'sector' && ! Str::isUuid($row['related_id']))) {
$fail('related_id', 'Identificador de referência inválido.');
}
if (! app(OpportunityClassification::class)->targets($kind)->where('id', $row['related_id'])->exists()) {
if (! app(OpportunityClassification::class)->canRetainReference($kind, $row['related_id'], $row, $this->context($business)['relations'])) {
$fail('related_id', 'Selecione uma referência existente e consultável.');
}
if (in_array($c['purpose'], ['regime_recognition', 'enterprise_admission', 'specific_benefit'], true) && $kind !== 'zone') {
@@ -229,7 +229,8 @@ class ExistingBusinessClassification
$effective = $this->effective($business, $row, $state);
if (in_array($effective, ['archived', 'revoked'], true)) { continue; }
$rows[] = ['dimension' => OpportunityClassification::TARGETS[$kind][2], 'target_type' => $kind, 'target_id' => (string) $row['related_id'],
'label' => $target->{OpportunityClassification::TARGETS[$kind][1]}, 'purpose' => $c['purpose'], 'purpose_label' => OpportunityClassification::PURPOSES[$c['purpose']],
'label' => $target->{OpportunityClassification::TARGETS[$kind][1]}, 'target_code' => $target->code ?? null,
'reference_path' => $kind === 'activity' ? (app(EconomicReferenceCatalog::class)->activities()->firstWhere('id', $target->id)?->path ?? []) : [], 'purpose' => $c['purpose'], 'purpose_label' => OpportunityClassification::PURPOSES[$c['purpose']],
'state' => $effective, 'source_reference' => $c['source_reference'] ?? null, 'citation' => $c['citation'] ?? null,
'authority_id' => $c['authority_id'] ?? null, 'production_stage' => $c['production_stage'] ?? null,
'external_status' => $c['external_status'], 'valid_from' => $c['valid_from'] ?? null, 'valid_until' => $c['valid_until'] ?? null];
@@ -250,13 +250,12 @@ class OpportunityCanonicalContract
};
$check(($payload['opportunity_category'] ?? null) === $record->opportunity_category, 'opportunity_category', 'A categoria deve coincidir com o registo e a autorização.');
$check(($payload['promoter_id'] ?? null) === ($record->organization_id ?? (int) $record->owner_user_id), 'promoter_id', 'Identifique o promotor real da oportunidade; o operador do portal não o substitui.');
$sector = DB::table('sectors')->where('id', $payload['sector_id'])->whereNull('deleted_at')->where('is_active', true)->first();
$subsector = DB::table('economic_activities')->where('id', $payload['subsector_id'])->where('status', 'published')->first();
$activity = DB::table('economic_activities')->where('id', $payload['economic_activity_id'])->where('status', 'published')->first();
$root = $subsector?->parent_id ? DB::table('economic_activities')->where('id', $subsector->parent_id)->where('status', 'published')->first() : null;
$check($sector !== null && $root !== null && (int) $root->sector_id === (int) $sector->id
&& $activity !== null && $activity->parent_id === $subsector->id && $activity->catalog_version_id === $root->catalog_version_id,
'economic_activity_id', 'Sector → subsector → atividade requer referências publicadas da mesma versão e hierarquia.');
$previous = app(OpportunityManagement::class)->values($record)['canonical'] ?? [];
$sameTaxonomy = ($previous['sector_id'] ?? null) === ($payload['sector_id'] ?? null)
&& ($previous['subsector_id'] ?? null) === ($payload['subsector_id'] ?? null)
&& ($previous['economic_activity_id'] ?? null) === ($payload['economic_activity_id'] ?? null);
$check(app(EconomicReferenceCatalog::class)->validHierarchy((int) $payload['sector_id'], $payload['subsector_id'] ?? null, $payload['economic_activity_id'] ?? null, $sameTaxonomy),
'economic_activity_id', 'Sector, subsector e atividade devem corresponder à hierarquia/versão publicada; os cinco níveis originais são conservados.');
foreach (['internal_contact_id', 'public_contact_id'] as $field) {
if (! empty($payload[$field])) {
$contacts = DB::table('contacts')->where('contacts.id', $payload[$field])->whereNull('contacts.deleted_at');
@@ -551,7 +550,7 @@ class OpportunityCanonicalContract
'schema' => $this->schema(true)['$defs']['opportunityCreate'],
'definitions' => $this->schema(true)['$defs'],
'submissionTextLimits' => ['demand_statement' => array_intersect_key($submissionProperties['demand_statement'], array_flip(['minLength', 'maxLength']))],
'activities' => DB::table('economic_activities')->where('status', 'published')->get(['id', 'parent_id', 'sector_id', 'label_pt_mz', 'catalog_version_id']),
'activities' => app(EconomicReferenceCatalog::class)->activities($record ? array_values(array_filter(array_intersect_key(app(OpportunityManagement::class)->values($record)['canonical'] ?? [], array_flip(['subsector_id', 'economic_activity_id'])))) : []),
'contacts' => $contacts, 'contactInvestors' => $record?->organization_id ? DB::table('investors')->where('organization_id', $record->organization_id)->whereNull('deleted_at')->whereIn('status', ['prospect', 'active'])->get(['id', 'legal_name']) : [],
'countries' => app(CountryCatalogue::class)->all(),
'authorities' => DB::table('authorities')->where('status', 'published')->get(['id', 'label_pt_mz']),
+28 -4
View File
@@ -79,7 +79,7 @@ class OpportunityClassification
[$table] = self::TARGETS[$kind];
$query = DB::table($table);
if (in_array($kind, ['sector', 'activity'], true)) {
return $kind === 'sector' ? $query->whereNull('deleted_at')->where('is_active', true) : $query->where('status', 'published');
return $kind === 'sector' ? $query->whereNull('deleted_at')->where('is_active', true) : app(EconomicReferenceCatalog::class)->constrain($query->where('status', 'published'), 'activity');
}
$query->whereNull('deleted_at');
if ($kind === 'chain') {
@@ -97,14 +97,16 @@ class OpportunityClassification
return $query->where(fn ($q) => $q->where('data_classification', 'public')->orWhereIn('id', InvestmentPortfolioController::visible()->whereNotNull($foreign)->select($foreign)));
}
return $query->where('data_classification', 'public');
return app(EconomicReferenceCatalog::class)->constrain($query->where('data_classification', 'public'), $kind);
}
public function options(): array
{
$targets = [];
foreach (self::TARGETS as $kind => [$table, $label, $dimension]) {
$targets[$kind] = $this->targets($kind)->orderBy($label)->get(['id', $label.' as label']);
$targets[$kind] = $kind === 'activity'
? app(EconomicReferenceCatalog::class)->activities()->map(fn ($r) => (object) ['id' => $r->id, 'label' => $r->display_label, 'code' => $r->code, 'level' => $r->level, 'path' => $r->path, 'source_version' => $r->source_version, 'edition' => $r->edition])
: $this->targets($kind)->orderBy($label)->get(['id', $label.' as label']);
}
return ['version' => self::VERSION, 'dimensions' => self::DIMENSIONS, 'types' => array_map(fn ($v) => $v[2], self::TARGETS), 'purposes' => self::PURPOSES, 'states' => self::STATES, 'externalStates' => self::EXTERNAL, 'targets' => $targets];
@@ -112,6 +114,16 @@ class OpportunityClassification
public function validate(array $payload, Opportunity $record): void
{
$previousPayload = $record->exists ? (app(OpportunityManagement::class)->values($record)['canonical'] ?? []) : [];
$catalog = app(EconomicReferenceCatalog::class);
$lotIds = array_column($catalog->manifest()['activities'], 'id');
if (in_array($payload['economic_activity_id'] ?? null, $lotIds, true) && ! $catalog->available()) {
foreach (['sector_id', 'subsector_id', 'economic_activity_id'] as $field) {
if (($payload[$field] ?? null) !== ($previousPayload[$field] ?? null)) {
throw ValidationException::withMessages(['canonical.'.$field => 'Referência retirada: apenas a classificação histórica já guardada pode ser conservada.']);
}
}
}
$seen = [];
foreach ($payload['relations'] ?? [] as $i => $row) {
if (! isset($row['classification'])) {
@@ -142,7 +154,8 @@ class OpportunityClassification
if (($kind === 'sector' && ! ctype_digit($id)) || ($kind !== 'sector' && ! Str::isUuid($id))) {
$fail('related_id', 'Identificador de referência inválido.');
}
if (! isset(self::TARGETS[$kind]) || ! $this->targets($kind)->where('id', (string) ($row['related_id'] ?? ''))->exists()) {
$previousRows = $record->exists ? (app(OpportunityManagement::class)->values($record)['canonical']['relations'] ?? []) : [];
if (! isset(self::TARGETS[$kind]) || ! $this->canRetainReference($kind, $id, $row, $previousRows)) {
$fail('related_id', 'Selecione uma referência existente e consultável; nenhum cadastro é criado por esta relação.');
}
$purpose = $c['purpose'] ?? '';
@@ -172,6 +185,16 @@ class OpportunityClassification
}
}
/** Exact persisted relation retention is not permission to choose a withdrawn target anew. */
public function canRetainReference(string $kind, string $id, array $row, array $previousRows): bool
{
if ($this->targets($kind)->where('id', $id)->exists()) { return true; }
if (! app(EconomicReferenceCatalog::class)->historicalTarget($kind, $id)) { return false; }
$content = fn ($r) => array_intersect_key($r, array_flip(['related_id', 'relation_type', 'classification']));
return collect($previousRows)->contains(fn ($old) => OpportunityCanonicalValue::hash($content($old)) === OpportunityCanonicalValue::hash($content($row)));
}
public function hash(array $row): string
{
// Client identity/status cannot certify a relation. Object-order normalization is reused.
@@ -320,6 +343,7 @@ class OpportunityClassification
// Original documents, internal rationale, actor IDs and decision history stay private.
$rows[] = ['dimension' => self::TARGETS[$kind][2], 'target_type' => $kind, 'target_id' => (string) $row['related_id'], 'label' => $target->{self::TARGETS[$kind][1]},
'purpose' => $c['purpose'], 'purpose_label' => self::PURPOSES[$c['purpose']], 'target_code' => $target->code ?? null, 'catalog_version' => $target->catalog_version_id ?? null,
'reference_path' => $kind === 'activity' ? (app(EconomicReferenceCatalog::class)->activities()->firstWhere('id', $target->id)?->path ?? []) : [],
'physical_category' => $target->physical_category ?? null, 'legal_regime' => $target->legal_regime ?? null,
'state' => $state, 'source_reference' => $c['source_reference'] ?? null, 'citation' => $c['citation'] ?? null,
'authority_id' => $c['authority_id'] ?? null, 'external_status' => $c['external_status'] ?? 'not_assessed', 'availability_confirmed' => false,
@@ -0,0 +1,323 @@
{
"lot": "lot-01",
"version": 1,
"origin_version": "eBAU-sha256-97ef68346803",
"scope": "five-node rice slice and editorial CLU-01 chain; no normative edition conformity assertion",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"divergence": {
"exemplar_subclasses": 600,
"prior_instruction_subclasses": 579,
"status": "documentary_open_nonblocking_for_slice"
},
"convention": {
"subsector": "01",
"activity": "01120",
"levels": 5
},
"existing": {
"sector": {
"id": 1,
"slug": "agronegocio",
"code": null,
"source_system": null,
"external_id": null,
"name": "Agronegócio"
},
"cluster": {
"id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"slug": null,
"code": "CLU-01",
"source_system": "upgrade-v4",
"external_id": "CLU-01",
"name": "Agro-indústria e segurança alimentar"
}
},
"sources": [
{
"name": "CAE eBAU.xlsx",
"relative_path": "sources/97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"bytes": 76699,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar 97ef68346803"
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"relative_path": "sources/e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"bytes": 1658773,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar e1169a7743b1"
},
{
"name": "agronegócio 1.docx",
"relative_path": "sources/c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"bytes": 15453,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar c8033366e265"
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"relative_path": "sources/356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"bytes": 24358,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar 356e46acd551"
}
],
"disclosure": {
"reference_designations_and_citations": "bounded editorial/reference slice authorised for QA; active requires explicit Tempo decision",
"source_originals": "private only"
},
"catalog": {
"id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"catalog_code": "economic-activities-cae",
"version_no": 1,
"locale": "pt-MZ",
"source_system": "retained-ebau-exemplar",
"source_version": "retained exemplar 97ef68346803",
"source_reference": "CAE eBAU.xlsx, folha CAE; cinco nós A/01/011/0112/01120, hash 97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545; edição normativa não determinada; 600/579 aberto.",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft"
},
"activities": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": null,
"sector_id": null,
"code": "A",
"label_pt_mz": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 1,
"source_record_id": "1",
"parent_source_record_id": null,
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 39,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "none",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"sector_id": 1,
"code": "01",
"label_pt_mz": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 2,
"source_record_id": "110",
"parent_source_record_id": "1",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 57,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "af45b335-61a5-53da-a029-a8fab91cf624",
"sector_id": 1,
"code": "011",
"label_pt_mz": "CULTURAS TEMPORÁRIAS",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 3,
"source_record_id": "200",
"parent_source_record_id": "110",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 124,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"sector_id": 1,
"code": "0112",
"label_pt_mz": "CULTURA DE ARROZ",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 4,
"source_record_id": "731",
"parent_source_record_id": "200",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 238,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"sector_id": 1,
"code": "01120",
"label_pt_mz": "CULTURA DE ARROZ",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 5,
"source_record_id": "1049",
"parent_source_record_id": "731",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 1122,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
}
],
"chains": [
{
"id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-INPUT",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-INPUT",
"name": "Modelo editorial — Fornecimento agroindustrial",
"stage": "input"
},
{
"id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PRODUCTION",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-PRODUCTION",
"name": "Modelo editorial — Produção agrícola",
"stage": "production"
},
{
"id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PROCESSING",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-PROCESSING",
"name": "Modelo editorial — Transformação agroindustrial",
"stage": "processing"
},
{
"id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-LOGISTICS",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-LOGISTICS",
"name": "Modelo editorial — Logística agroindustrial",
"stage": "logistics"
},
{
"id": "16d3e30c-3acc-598c-851b-92267342eaae",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-MARKET",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-MARKET",
"name": "Modelo editorial — Comercialização agroindustrial",
"stage": "market"
}
],
"links": [
{
"id": "61be8cc1-7a17-5444-a79a-3007f201ef86",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-INPUT:CLU01-PRODUCTION",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"to_value_chain_id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"link_type": "supplies"
},
{
"id": "c295605b-710c-57e8-9df6-57407d1a6bb8",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PRODUCTION:CLU01-PROCESSING",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"to_value_chain_id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"link_type": "processes"
},
{
"id": "a651e9cb-65c1-5812-8ffe-20b14a91a968",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PROCESSING:CLU01-LOGISTICS",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"to_value_chain_id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"link_type": "distributes"
},
{
"id": "f84a473a-1797-53bf-b054-bb29c4ebce3b",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-LOGISTICS:CLU01-MARKET",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"to_value_chain_id": "16d3e30c-3acc-598c-851b-92267342eaae",
"link_type": "distributes"
}
],
"citations": {
"activities": "CAE A1:F1; linhas 39,57,124,238,1122; SELF_ID explícito",
"chain_model": "Programação v6, §§534–543/631–635; modelo editorial genérico, sem operadores/capacidades/fluxos reais",
"context": "Agronegócio 1 §1; Corredores do Agronegócio §§4/10/23/29/39"
},
"new_reference_count": 15
}
@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
$target = DB::selectOne('SELECT current_database() AS database,inet_server_port() AS port');
$qa = app()->environment('testing') && str_ends_with($target->database, '_test') && (int) $target->port === 55441
&& config('database.connections.pgsql.host') === '127.0.0.1' && ! config('database.connections.pgsql.url');
if (! $qa && ! config('economic_references.authenticated_installation', false)) {
throw new RuntimeException('Economic hierarchy requires the authenticated nominal installer or isolated QA.');
}
if (Schema::hasColumn('economic_activities', 'metadata') || ! DB::selectOne("SELECT 1 FROM pg_constraint WHERE conrelid='public.economic_activities'::regclass AND conname='economic_activities_sector_uq'")) {
throw new RuntimeException('Unexpected economic schema; reconcile drift before applying.');
}
DB::statement('ALTER TABLE public.economic_activities DROP CONSTRAINT economic_activities_sector_uq');
DB::statement('CREATE INDEX economic_activities_sector_idx ON public.economic_activities(sector_id)');
DB::statement('ALTER TABLE public.economic_activities ALTER COLUMN sector_id DROP NOT NULL');
DB::statement("ALTER TABLE public.economic_activities ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb");
}
public function down(): void
{
// Published source versions and their downstream uses must never be destroyed by rollback.
if (DB::table('reference_catalog_versions')->where('catalog_code', 'economic-activities-cae')->exists()
|| DB::table('economic_activities')->whereNull('sector_id')->exists()
|| DB::table('economic_activities')->whereRaw("metadata <> '{}'::jsonb")->exists()
|| DB::table('economic_activities')->select('sector_id')->groupBy('sector_id')->havingRaw('count(*) > 1')->exists()) {
throw new RuntimeException('Economic references have been used; retain the additive schema and compatibility contract.');
}
DB::statement('ALTER TABLE public.economic_activities DROP COLUMN metadata');
DB::statement('ALTER TABLE public.economic_activities ALTER COLUMN sector_id SET NOT NULL');
DB::statement('DROP INDEX public.economic_activities_sector_idx');
DB::statement('ALTER TABLE public.economic_activities ADD CONSTRAINT economic_activities_sector_uq UNIQUE(sector_id)');
}
};
@@ -2427,3 +2427,47 @@ Mesmos sete requisitos com complemento operacional parcial; 3395 outros registos
Tempo autorizou expressamente negocios-compilacao-nome-QA-7ef0facd0e27. Renovado backup/restauro do estado base já entregue: 295 tabelas, 31 sequências, 1304 ficheiros e 29 documentos; clone arrancou em leitura. Trocados somente os 161 ficheiros de compilação, sem fontes/configurações adicionais nem comandos de limpeza de cache. Título ativo observado após carregamento: Oportunidades de negócio - InvesteMoz. GET/TLS/assets passaram, catálogos preservados; comparação final das 295 tabelas sem diferenças. Zero classificações reais ou relações divulgadas. Reversão do suplemento repõe apenas o build base; reversão integral mantém o contrato de preservação das novas revisões.
Saldo operacional zero. Limitação UUID no ativo permanece explícita por ausência de anúncio próprio da conta 2; não foi criado anúncio nem forçado acesso. Cadeia sem caso positivo, ausência de ensaio volumétrico e limitação do payload sintético da reversão conservadas. Outras quatro lacunas e aceitações anteriores mantêm-se. Mesmos sete requisitos recebem complemento, restantes 3395 registos brutos e todos os estados preservados. Relatório/recibo final: outputs/investmoz-negocios-classificacao-ativacao-20261016/RELATORIO-FINAL.md e RECIBO-CONSOLIDADO.json. Propostas e relatórios das fases anteriores conservados como histórico.
## 16/10/2026 — referências económicas e cadeia de valor delimitadas antes de implementar
Mapa QA em outputs/investmoz-referencias-economicas-mapa-20261016/MAPA-LOTE-MINIMO.md. Inspeção READ ONLY de QA aceite e clone do destino restaurado, sem ligação ativa: 12 setores/6 raízes editoriais/8 clusters, sem elos/ligações; três níveis adicionais da QA são sintéticos e usam setores diferentes. Restrição técnica UNIQUE economic_activities_sector_uq e pressuposto de árvore de três níveis identificados; não constituem exigência organizacional aprovada. Catálogo editorial não equivale a CAE oficial.
Acervo integral anterior reutilizado (10717 ficheiros), anexos acessíveis enumerados e 12 exemplares lidos. As duas folhas CAE eBAU têm bytes/hashes diferentes e as mesmas 8145 células: 1360 códigos, cinco níveis, 600 subclasses contra 579 no roteiro. Edição/âmbito dessa diferença mantêm-se concretamente indeterminados, sem nova validação da credibilidade oficial. Proposto ramo A/01/011/0112/01120, código textual e SELF_ID preservados, e cinco elos editoriais/quatro ligações no CLU-01 existente. Convenções de apresentação e natureza editorial submetidas à Tempo; não são factos comerciais ou novas oportunidades.
Oito artefactos aplicacionais previstos (seis fontes/uma migration/um manifesto), compilação futura e dois instrumentos QA. Zero implementação/migration/importação/publicação nesta preparação. Caso positivo nos consumidores canónico e /negocios ainda por demonstrar, só num clone novo; original publicado/v12, documentos, permissões, classificações e histórico preservados. Reversão após uso deverá manter dados e contrato compatível, com prova de edição posterior, sem down destrutivo. Estimativa QA restante 12–18 h, discriminada por tarefa, excluindo execução ativa.
Mesmos sete requisitos existentes recebem delimitação parcial; 3395 registos brutos não relacionados e todos os estados preservados. /negocios mantém-se concluído no âmbito reportado; observação do editor UUID no ativo não demonstrada, não bloqueante, sem anúncio artificial nem elevação de permissões. A Tempo não conferiu os anexos dessa disponibilização. B, COUNTRY02 e aceitações anteriores preservados; parques serão o próximo recorte, duplicados e regulação Fintech continuam separados e abertos.
### 16/10/2026 — DOC01 do mapa económico, sem autorização de execução
Recomendações documentais recebidas: 600/579 é divergência a reconciliar, não escolha arbitrária da Tempo. Proposto manter em QA apenas cinco nós do exemplar com hash/versão, divisão 01/subclasse 01120 no recorte e cinco elos do CLU-01 como modelo editorial. Fonte oficial aceite não é revalidada; não há conformidade normativa integral presumida. As recomendações não são autorização QA ou ativa, nem prova executada pelo utilizador.
Desenho operacional fechado desde já em outputs/investmoz-referencias-economicas-mapa-20261016/DOC01/DESENHO-OPERACIONAL.md: extensão do padrão autenticado existente com preview, instalação nominal, importação privada, publicação e retirada distintas. Sessão/MFA/autorização efetiva, CSRF, scans ligados aos bytes, hashes/estado, repetição, concorrência e recibos previstos. Sem exigir abrir o instalador em manutenção; compatibilidade do código antes da migration passa a critério novo e delimitado. Não reinstalar B/COUNTRY02 nem alterar o importador documental. Ainda não implementado ou instalado.
Manifesto previsto passa de oito para 12 artefactos (dez fontes, uma migration, um manifesto): quatro fontes acrescentadas para serviço/painel/rotas operacionais, preservando o lote de 15 referências. Estimativa original 12–18 h era QA funcional; +2–4 h para provar o mecanismo operacional, total QA revisto 14–22 h. Disponibilização futura separada 2–4 h com backup/restauro fresco, após autorização própria. Reversão após uso explicitamente parcial e compatível: schema, dados, seis fontes funcionais, manifesto e build de compatibilidade mantidos; sem reposição integral presumida. Suspensão de código não retira publicação automaticamente.
Mesmos sete requisitos complementados; 3395 registos brutos e todos os estados/critérios originais preservados. Mapa/ZIP/recibo anteriores conservados como histórico. Nenhuma implementação, migration, importação, publicação, alteração ativa ou repetição de testes aceites. Caso positivo de cadeia segue pendente; parques, duplicados e Fintech separados; B, COUNTRY02 e /negocios mantêm o fecho reportado e os seus limites.
### 16/10/2026 — lote mínimo económico executado em QA
A instrução posterior da Tempo autorizou executar somente em QA as convenções delimitadas. Candidata `referencias-economicas-QA-966202f15577`, preparada no clone `economic_references_20261016_test:55441`, servidor 18531. Cinco nós A/01/011/0112/01120, divisão 01 como subsector e subclasse 01120 como atividade somente neste recorte, mais cinco elos editoriais e quatro ligações do CLU-01 existente. Catálogo editorial anterior, IDs e referências preservados. Divergência documental 600/579 e edição normativa continuam abertas; não há operadores, capacidades ou relações comerciais reais confirmados.
13 artefactos (11 fontes, migration nominal e manifesto), sete substituições/seis novos, mais 162 ficheiros de build. `ExistingBusinessClassification.php` foi acrescentado aos 12 previstos para conservar relações históricas retiradas também em `/negocios`; sete fontes funcionais ficam retidas na reversão. Instalador nominal autenticado pela dupla existente, importação privada, scan ClamAV real, repetição, publicação e retirada expressas demonstrados. Corrigida em QA uma recusa indevida de retirada após repetir a importação de referências criadas pelo próprio lote. Sem grants, novas oportunidades ou alterações no ativo; nenhum acesso à base ativa.
83 verificações/170 pedidos HTTP dirigidos, 13 de reversão e 184 de preservação; tipos, nove lints PHP e build passaram. Caso positivo de atividade/cadeia demonstrado nos dois consumidores, filtros combinados, preparação/confirmação separadas da divulgação, recuperação e cinco níveis visíveis. UI conserva a referência histórica retirada e explica a indisponibilidade. Referência QA original continua publicada/v12. Não se repetiram os 12 critérios aceites.
Limites explícitos: pré-condições de aprovação canónica são fixtures QA para observar só a projeção, com imagem sintética existente e metadados editoriais completados; não repetem nem reaceitam o workflow integral. Save canónico pelo serviço/rotas anteriores persistido no rascunho 15; save do editor anterior de negócios exercido com conteúdo legível e estado editável numa transação QA revertida. Não demonstra recuperação de payload legado sem chave. Reversão parcial conserva schema/dados, sete fontes funcionais, manifesto e build coerente, sem down destrutivo; retirada de publicação permanece separada. Sem ensaio volumétrico.
Mesmos sete requisitos complementados, 3395 outros registos brutos e todos os estados/critérios originais conservados. Preparação QA deste recorte concluída, saldo zero. As 12–18 h funcionais mais 2–4 h operacionais DOC01 (14–22 h) eram estimativa de preparação agora executada; o ficheiro de compatibilidade não aumentou essa previsão. Disponibilização futura: 2–4 h separadas, com decisão própria, janela e backup/restauro fresco. Relatório, proposta única, procedimento, reversão, manifesto e recibo em `outputs/investmoz-referencias-economicas-QA-20261016/para-revisao/`. O desenho DOC01 anterior fica histórico; não autoriza ativação. B, COUNTRY02, fechos anteriores e limite UUID no ativo mantêm-se; restante CAE/reconciliação, parques, duplicados e regulação Fintech continuam abertos.
### 16/10/2026 — lote mínimo económico disponibilizado com autorização da Tempo
A mensagem posterior «pode avançar. esta autorizado» autorizou a proposta concreta `referencias-economicas-QA-966202f15577`. Entrega concluída: 13 artefactos e compilação de 162 ficheiros; migration nominal `2026_10_16_120000_extend_economic_reference_hierarchy` pela ação autenticada da conta real 2. As 15 ausências foram importadas privadamente, com scan ClamAV real limpo e recibo; repetir o mesmo pedido recuperou o recibo sem duplicar. Uma ação autenticada distinta publicou expressamente o catálogo, cinco nós CAE, cinco elos editoriais e quatro ligações. Os quatro exemplares de origem permanecem privados e não foram publicados na biblioteca. Nenhum anúncio real foi classificado ou teve relações divulgadas.
Backup fresco do destino `investemoz:5432` restaurado em `economic_refs_before_20261016_104913_test:55441`: 295 tabelas/31 sequências coincidentes, 1304 ficheiros conferidos e arranque do kernel HTTP em leitura, sem ensaio de servidor TLS no clone. Troca em manutenção, saída antes de abrir o instalador; somente `view:clear`, sem limpeza da cache de dados. Conferência final das 295 tabelas: nenhum dado de negócio, histórico ou permissão anterior alterado; 15 inserções autorizadas, uma entrada de migration e três auditorias operacionais. Cache/sessões variaram com os pedidos; a cache de dados estava idêntica imediatamente antes/depois da troca. Os 29 originais documentais continuam iguais. API pública recupera A/01/011/0112/01120; catálogo editorial anterior e listas públicas de investimentos mantidos. B, COUNTRY02, conteúdos e aceitações anteriores preservados.
Reversão após utilização continua parcial e compatível: conservar nove artefactos (sete fontes funcionais, migration e manifesto), schema/ledger/dados e build completo; restaurar apenas as rotas e remover três fontes operacionais por hash. Retirar a publicação exige ação própria antes de retirar o instalador; trocar código não a retira automaticamente. Não foi executada reversão no ativo. Relatório final, manifesto aplicado, mapa de reversão e recibo em `outputs/investmoz-referencias-economicas-ativacao-20261016/para-revisao/`. Matriz existente complementada nos mesmos sete requisitos, preservando 3395 outros registos brutos e todos os estados/critérios anteriores.
Saldo deste lote QA/operacional: zero. A estimativa de 2–4 h fica como previsão histórica, não declaração de horas consumidas. Divergência 600/579, edição normativa e restante CAE continuam abertos; cadeia é exclusivamente editorial, sem relações comerciais confirmadas. Limites QA, ausência de volume e observação do editor UUID no ativo não demonstrada/não bloqueante mantidos. A ficha operacional dos parques é o próximo recorte previsto; duplicados e regulação Fintech permanecem separados. A autorização executada não é uma conferência independente dos anexos pelo utilizador.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,991 @@
{
"files": {
"app/Actions/Fortify/CreateNewUser.php": "caaaa98a8867c44ddaa45a1f58fd388f3b46f781d22cd9f8af67e292d3b82e60",
"app/Actions/Fortify/ResetUserPassword.php": "8ec7f8a74a7f30b729bf77578d1b6a9add3c48643c92d584f7bb69e5b81c0996",
"app/Concerns/PasswordValidationRules.php": "bc156c8d3556c45784ff6a319d02d7fb52ba2678ac4e4d6bf17d04861c4ebef7",
"app/Concerns/ProfileValidationRules.php": "274b9a825d140cc4a154f7ec816d368e1a9d7e8585158a70842b1d03415dae65",
"app/Console/Commands/AiBenchmark.php": "4e4c4b9b27abc0fa4bf3e747ff40dfffaa83c7c943c81c36fa529899ed4c75e6",
"app/Console/Commands/AuditTerritorialCsv.php": "853c5a180543d851de915bfdea81af159d153da7e35569b3802cb0771938fe7a",
"app/Console/Commands/BackfillMneCompatibility.php": "7ea719478dde2556b6653da2ea1a80d2db83a4cc63db953bf3a306d083bfbe8c",
"app/Console/Commands/CheckDocumentLibrarySchema.php": "ba2345c60518c4a4c5f91fddfb8988ca529f75f0a8fe28a6a8606993be0e1911",
"app/Console/Commands/CheckMalwareScanner.php": "c2a3fe2b754b703a77cb506911ed028912bc0c7371fee26b78776a50687ab9e1",
"app/Console/Commands/EscalateOverdueInvestmentTasks.php": "c09855a9919e6e5e686cbe751371e5a298a4d8e32b37724fd4b8146d8636bcb6",
"app/Console/Commands/ImportDocumentBatch.php": "d7baab722413459817ff973114c7ee6123c806a5ea168fe58bf5ddc054cc8d78",
"app/Console/Commands/ImportIndustrialParkCandidates.php": "5dd60087f41b4c4cfa9083ad0cb8b91e11a3be3a9868928abbb1cadaa0db762e",
"app/Console/Commands/ImportInvestmentPortfolio.php": "a3b85f04b4cd4f8110391e480caf9538f03d79e5e77ebf820d9962086a31e0d0",
"app/Console/Commands/ImportInvestmentZones.php": "5442bf352b489b3fdb0991c0307f0e47134c1a0978d0bb6ffe5fd6e94e75afe3",
"app/Console/Commands/ImportLegalSourceArchive.php": "09cfec89c44805c96d1348223b124a7fb56137d17b8be7a729b17b424d97f9e3",
"app/Console/Commands/ImportTerritoryWorkbook.php": "b5d70a1287a4861fd9ec05056f896e01d712dd6f27982287c5c91148884ff500",
"app/Console/Commands/InstallFeaturesCommand.php": "d4322788cbaf54d35838519b16c874d05e8c24bd3cfb3e9f14af1767e19f9439",
"app/Console/Commands/PortalReadiness.php": "2371d25d75acd8bafdf8f4c9eb2e920bed44b14bbe01c13cf53ca8406f3f0ffe",
"app/Console/Commands/ReconcileInvestmentIdentity.php": "7974b6b9968d538d84efd4e8533ec8df439392c9d1c19451ad4e49852af0eb9a",
"app/Console/Commands/ReconcileMneCompatibility.php": "af621782870836180283e1ed5ab3985e62c8ddabc8328efff5c929416035d825",
"app/Console/Commands/ScanPendingDocuments.php": "d28942e41f10b1a6649b284436acc364dac0205a646af4f6a07400d01b8f6a6b",
"app/Console/Commands/SuiteCrmProbe.php": "ac271bac3144c329bbccf2270bc4a01c9cf135c72bfbdbf98916c621edbc1a84",
"app/Domain/Interests/Enums/InterestStatus.php": "38347f9c0af8e5702f4c43119327f420d16e34e1056a42c6f4a2847eab737598",
"app/Domain/Opportunities/Enums/OpportunityStatus.php": "24a13cbbe6945ca39ba1a639dabe16f46f185bc2b29b7831b153c3ef9099893e",
"app/Http/Controllers/AiController.php": "fd22c177665fae1785e75ce4bd526a9b16f37e5737ef31a616f2ab51b36169f5",
"app/Http/Controllers/ClusterValueChainController.php": "4048cbc7001f2794027f0800dc0c4c8615a1ed893ec30c8a781559b8b16f9bc6",
"app/Http/Controllers/Controller.php": "25d1c1ef8e6cc8a376553faacfba2b07d9dfaee9bdbb84f14f77517580e9deb1",
"app/Http/Controllers/CrmController.php": "99c05b3370902a5f1781f05b2cb8b1360e0d654f9f593a14ccfc40acef151856",
"app/Http/Controllers/DashboardController.php": "5d94b243a7f58783e950ad9fa968b0be53ad0789ce7498384ccd3f48af8376d9",
"app/Http/Controllers/DocumentMalwareController.php": "0dd3f3f1b238f5c28c40657d8bcebf5ff26b48ef804dc5d4f729f57401340b89",
"app/Http/Controllers/EducationController.php": "ec6e007f9b9b9ee85b2905fd716f6bf74796f69e4844d03444cd1cdf7654c1f9",
"app/Http/Controllers/EducationInvestmentController.php": "30d16ae7db35dbeda19e1bb3ee90f374b0a045a431fcaffb616920c86f3f5d02",
"app/Http/Controllers/ExistingBusinessClassificationController.php": "42bae16c7e6445bf73328b0f8e2120c64be0f48fafa342108272dd862b9d1b93",
"app/Http/Controllers/ExistingBusinessController.php": "ab085d31582b93c913fd5f0657c557b8f1d893cfb557a52302894a0f05956e7d",
"app/Http/Controllers/InvestmentContextController.php": "1fb407368b4dbc6c65c0e8b7e6ab2609a2f61c5772d12a196c0eaaf7341a83a9",
"app/Http/Controllers/InvestmentCoordinatesController.php": "76e44c73f0ae73e8c5a0d4b625caaee8e0eb9654dfa7dd72e2b457cfb15f10ff",
"app/Http/Controllers/InvestmentDiscoveryController.php": "df3cc8f5a43766832399cbde836617bf86e7fcbde56b660f008714daf5560ba8",
"app/Http/Controllers/InvestmentLegalSourceController.php": "95ac989b099270620c737462e7b570838323d8064cbbb2db6bb51377a446d5f9",
"app/Http/Controllers/InvestmentPortfolioController.php": "d1d7f6d8bec6941b2d736a3b8878d0942b060e066d65d11ec8562327c28e50f6",
"app/Http/Controllers/InvestmentRelationshipRepairController.php": "9b862cd953fb83d8aaba70cd01c40a9b8406552ccfa09dd5b599b5241f5402ac",
"app/Http/Controllers/InvestmentStructureController.php": "ef4963175dbf5341c1706305e2717e317887bc392651b8a47920a2fdb34e7a07",
"app/Http/Controllers/InvestmentStructureRelationController.php": "a4f93c1a383a18b941e990e4b44289a73a4f2035b7704a3d145833dff1426099",
"app/Http/Controllers/InvestmentSubmissionController.php": "c4b309a8ff79f870a519379e41d6ec23387da0b903510d5ce99cfd48a00e921e",
"app/Http/Controllers/InvestmentTerritoryController.php": "4b8567223bbee2604486ff0fd5bdae51a981bdfa02dbd2c7ae576955df1189e7",
"app/Http/Controllers/InvestmentWorkspaceController.php": "6f7ec5bb0af3eb4ba72c4f3442f20ca6310ff4cf997264c365c65fa0db16eefc",
"app/Http/Controllers/InvestmentZoneAttachmentController.php": "98a2866083ba9696561962bb1a7b9a27701000d2f2bf2723ca7fd47b319c525b",
"app/Http/Controllers/InvestmentZoneController.php": "2eeff9c79e92cb695ae88add9ba92d130d8d8bb40ce9d2aa26623281c1212666",
"app/Http/Controllers/InvestmentZoneGeometryController.php": "cb38c92ae15c4f2410ef0472f3c82b492f724993c2c4945fdfe0b0ef90d8a7b5",
"app/Http/Controllers/InvestmentZoneLinkController.php": "1c1aa6c164489d0905b0ba9b5460573b436aeb3dd52da4b2aa5167f760da9861",
"app/Http/Controllers/InvestmentZoneRelationController.php": "0f2fb3e5917629dd453d30b525a041a034110eb2e72f0b3ee17d8495cec80694",
"app/Http/Controllers/InvestorGuidanceController.php": "4aa1a8140fc80c9e34aaaccd7a41d3086b63e761c567c088928156d6a0d8b878",
"app/Http/Controllers/InvestorPathController.php": "6a69fbe1f5bc1e7dfa23ee023ad59a36225c6286912d8b8d3a9e651bc57ea8bd",
"app/Http/Controllers/InvestorWorkspaceController.php": "8279f05f55fb690df02470481187d81ac5fd213a8385c17e0dd4e97b7e2f4cb8",
"app/Http/Controllers/LandAssistanceController.php": "3177919b63517064d36f977b7f779bd4d7061329c98c8b3710978c179a420031",
"app/Http/Controllers/LegacyContentController.php": "6d660d91e3e0267e02fe46c3b30ee128b0bf07f8bc0b9fa5e23007341d8a3e61",
"app/Http/Controllers/OpportunityClassificationController.php": "7befceff95da3e50fe635cc635f654897b94d26f3a0cddbd861251a5cdf18333",
"app/Http/Controllers/OpportunityManagementController.php": "98bf34319020d580fcfd434a57ec8eb91b8f4fe7a952ec5ec543b8302cd93136",
"app/Http/Controllers/OpportunityOriginReviewController.php": "4f00025abb2ea1d2032e13931b97c5cae2db8467c1d68c5489b47421e179da5e",
"app/Http/Controllers/OpportunityResourceController.php": "dec2b5ef5c34760d8c09224ec1c9029d4c07c241f56d36199c2bde4418673b0e",
"app/Http/Controllers/PartnershipExchangeController.php": "0e605942f079e10b8454ebf40a84aa676d4b59aca0d0c51ecdca42c72a056805",
"app/Http/Controllers/PartnershipInstallationController.php": "350aebe2e4d6d57484716f5d3611f35dbead6da862a3693ba2307d854fe2347d",
"app/Http/Controllers/PortalManagementController.php": "f03dd52e6072d2f745a1ed8ab6725a93182281c1e5cb507ed31c7e017cecb878",
"app/Http/Controllers/PortalProfileController.php": "b293fdd7d1b6928bf038fdb4619030368bc5125914054a0c78cbf26b25a38286",
"app/Http/Controllers/PortalProfileInstallationController.php": "083cd389cb8387715896bf68e946e0345801a3b14797e17c8e22648d7e78ccbf",
"app/Http/Controllers/PortalServicesController.php": "09ecbde4287a092899f2ed7a751083062f933221723f57e9d6476572b8b7145b",
"app/Http/Controllers/PublicBusinessOpportunityController.php": "8d85b5be2519fbc1885b2d4306160ad727c416f9c68bb8b7e69d6b4162c23deb",
"app/Http/Controllers/PublicGeographyController.php": "9d255ddfb5c86f864b43465874fba06b847279484cac4888a5fc522f378d468f",
"app/Http/Controllers/PublicPortalController.php": "64811db2b3d0f9c1db45e86537e9e12d50cde3937931d07c409d62c9e2b44a1b",
"app/Http/Controllers/SimulationTaxRuleGovernanceController.php": "35c85f59d5e46b8fbc791ec7c749ef6fe5ecce769b8389fce1b03ac13c79f5cc",
"app/Http/Controllers/TerritorialRegistryController.php": "2e57b79332cec408c0c55afbdde5bc2167c6df345a16c05bcf71b0d7aee42ae5",
"app/Http/Controllers/TerritoryGeometryImportController.php": "44e7c64200103f58e87439a47042c02c619e0689c4a51202e5ef7e9b508db7c5",
"app/Http/Controllers/VirtualDeskController.php": "f13623f85bb95290e5be167388b4120e377737df368fd7b1bd6a376550d39fa5",
"app/Http/Controllers/VirtualDeskInstallationController.php": "890c2608b0e747684ed027616dabe29a9628fd312abf29657f237bdf8f2caff7",
"app/Http/Controllers/VirtualDeskOperationsController.php": "c7d8539e327cd83632e516f23b4b427806b86ca8ccdc9cad366a0f8ddb73b8c5",
"app/Http/Controllers/Api/V1/HomeController.php": "cd2bcda6658fcba744f8bd0677a3f5e0ee6e5859d1abcdd8f6c0f25d6b4ca99d",
"app/Http/Controllers/Api/V1/InterestRequestController.php": "e3ecfb08c407954d317db460cde851f1e0781a46828bab25baaa090ccde8335b",
"app/Http/Controllers/Api/V1/LegislationSourceController.php": "07e48fda465501a0d1482149339c75cda1f98d38fb3b703f07d65a2f8ce416b3",
"app/Http/Controllers/Api/V1/OpportunityController.php": "32715dc066782aa2996b63efb508d04eed68e28e4068e1d544584059659d620f",
"app/Http/Controllers/Api/V1/ReferenceCatalogController.php": "f5a2920d3f6b4c92fde9ca968039c2e6953abb96ff40f1ba6da78d99b02c4a70",
"app/Http/Controllers/Api/V1/SectorController.php": "2b759477e908469cc478f7b20532d1ccd27c84ea8d24613e27c4587e77f895f4",
"app/Http/Controllers/Api/V1/SimulationController.php": "adec2e05c9d60f33dfa4a9511ff8b8881bf2170ef3bbe54b7a73343c65b49e18",
"app/Http/Controllers/Api/V1/SimulationFormDraftController.php": "b5c721e61956143d272c39a82f50b3defe79f3c7765a9abdf4637e88dd455d25",
"app/Http/Controllers/Api/V1/SimulationTaxParameterController.php": "450e8342f7e86a613a6c8c4dcf54f0e654b34e628ec3490a1eed4373db0d7e92",
"app/Http/Controllers/Settings/ProfileController.php": "1155df036512d539d81dcf03a116bba07a411007d125fff060c60bde41101152",
"app/Http/Controllers/Settings/SecurityController.php": "de88a5e8594c9b03d55bf85a248231d1a148128ac4a1d8b7693847d6daa9ea85",
"app/Http/Middleware/AiEnabled.php": "f05236bc05eee01d9f1903f2274a1f9d6d915f4602076fcb54ee992719b3c527",
"app/Http/Middleware/AuditProfileDecision.php": "c4bcb3649ac4d43fc272c157472becf71ac5ca0ef3cadad331ce749d9c7ae2dc",
"app/Http/Middleware/CorrelationId.php": "eec2fd36fd224e68226fdfd18c871c862b7cfab178934ecb1ae929a22280e890",
"app/Http/Middleware/EducationEnabled.php": "00343c9529e9e63e0f2ecd99ccdc6da7357c8c56008eae88c87f30da936b2824",
"app/Http/Middleware/EnsurePortalProfileAdministration.php": "ed0d7805a89011507dca2af86176f4ca8dc83b4ebb2fdd2308ac1669b2836917",
"app/Http/Middleware/EnsurePortalProfiles.php": "b620dbc7ab03eeedd3c62fdf07324b47b5606b28cd585472a81d91224a4e1160",
"app/Http/Middleware/EnsureSimulationRecoveryCookie.php": "2ca1c938673dc37bc4845b8e891b1593028174a88c6bfbfd22c82c5da8227370",
"app/Http/Middleware/ExistingBusinessEnabled.php": "9e002d09f8c488ff4e09c2b2aa6c36d4705f71788d8bc3bc94aaf5e6e022b225",
"app/Http/Middleware/HandleAppearance.php": "0615a413bb12e39cb1c4a6baa93dfc2877c0988bfe31732d9e9cb8ef2b0523df",
"app/Http/Middleware/HandleInertiaRequests.php": "e117d366ce411944fd560b5b8117853859532e255bff5e732f1874a1eac70979",
"app/Http/Middleware/PartnershipInstalled.php": "c3111eee7853dc492c55b12ef74df6780b352ab9941d664f5834f90baa1b0403",
"app/Http/Middleware/PortalProfileSession.php": "b36d128f81256475c7f44ee8608a08a15a45355fa66ff50b2f4f14d6a972ae32",
"app/Http/Middleware/PreserveFormFeedback.php": "d056e6da373ebdcc7742970827a9c72c454cd635f60e5bd3ef45876a5f855dee",
"app/Http/Middleware/PrivateInvestmentResponse.php": "ef897d4dca11c968281bf5a4755a591a5b22766feb426ebdffc50c10fc5c8fdb",
"app/Http/Middleware/ProtectPrivilegedIdentity.php": "f9eec06267a35a01f50f077e3a46df287f88294f0951eeeae0ffab894018ab81",
"app/Http/Middleware/ProtectProfileOpportunity.php": "53c30d652a568733ecbd240acc8c22165307de9e26b761b3d26ba1468f4d7b5b",
"app/Http/Middleware/RequireZoneMfa.php": "5eec5a272f7b77386ccb9e991a27bea0345f9e23931970e29bb3c99d15e5d57c",
"app/Http/Middleware/TerritorialRequest.php": "c49c16e7ffd33025d3d94d6d87627474dda51f83181ea3b853716afefba92b60",
"app/Http/Middleware/VirtualDeskInstalled.php": "a0a5d9b6123892b3b38313457415e73e6c9e4997cea8312adb215d60c45d188d",
"app/Http/Requests/AttachSimulationToDraftRequest.php": "51d9bb8027e7b3e2d3690aca4fb945da91da3b6dec4a65b23e5803cd2cd4090c",
"app/Http/Requests/ClaimSimulationFormDraftRequest.php": "a1bba65a18d049d3b9a0bf046864783e6b4d6b29ce1ef31826070729f5fb6461",
"app/Http/Requests/LinkSimulationDraftBusinessRequest.php": "7516a52c0daf533a267868bb5b066e7dca23f6562033f397d5c7f85746eb2b9e",
"app/Http/Requests/ResolveSimulationTaxParametersRequest.php": "ef2a856b7eb307341d8bb398573a76afcba9fb7a4f5ea8577a4fbfb53c672e68",
"app/Http/Requests/StoreInterestRequestRequest.php": "9b965d197345c81e4c666c0d9174ede3e0f125785808a1592d01aa87a36f42cb",
"app/Http/Requests/StoreLandAssistanceCaseRequest.php": "2b3f24698e98f7262dfdd1df963ae8cf0f347f3b338c072e3d8f524c05c49ce4",
"app/Http/Requests/StoreSimulationFormDraftRequest.php": "e0cbc5e0e229b101dc3b08bba63ffdc3eef9f3a9cff66b3b76f5f181a96bd15c",
"app/Http/Requests/StoreSimulationRequest.php": "c07f9e5e1b1057f30f63bc7e03b55224cf55cea6bc9dab1849440ce74830071d",
"app/Http/Requests/UpdateSimulationScenarioRequest.php": "c54d78771ad60c44320da0a50068ec62aab1c59833b20d83be2e376fa9b1ec83",
"app/Http/Requests/Settings/PasswordUpdateRequest.php": "a32e9198f1e25363834ff12a1a7d1cc5ec0bcfda3f32cf1c1d03530315cf2bf5",
"app/Http/Requests/Settings/ProfileDeleteRequest.php": "f4d89321b0b482797c3fd5325f907ab4809b06ca3b60ffa8ea6d13540643b00e",
"app/Http/Requests/Settings/ProfileUpdateRequest.php": "846e47b3ad44f7d7cea00c6c6b5744552cb894e82e8f5ed5a9a7244a5c8b2c6c",
"app/Http/Requests/Settings/TwoFactorAuthenticationRequest.php": "ca9fb1252964deda922ad8dc4123650b86c07136f973f42bae4d103019b79b89",
"app/Http/Resources/PublicBusinessOpportunityResource.php": "e59cc4923af15affbe0eb4ae782bd2368f670aa91e9e305ca9a39ce3bec72606",
"app/Integrations/SuiteCrm/SuiteCrmClient.php": "fa2dd9e8bc4afcc07b49e8b27d1aa5594832b6e171b3d9f9583affc0b026115e",
"app/Integrations/SuiteCrm/SuiteCrmException.php": "a2a6c19e96b60a116fb882b7c35f2db5593234b77f5f5175427b2f2961b34dde",
"app/Jobs/CompareMneBusiness.php": "45789dfa3a98a640c74740b8c79cb2e7e3db99f8aa6a7168081ec26049131a0e",
"app/Jobs/NotifyInterestReceived.php": "2907eef3b044b19b15b9e4b3f05b4ebe1c7292e01a4452e2890f10a67463dd5e",
"app/Jobs/RunSimulation.php": "594f6927508586f6c0c0775430ce84c345896300d8252c6114e9c67680ad6272",
"app/Jobs/ScanDocumentForMalware.php": "af4d1163ce3e3e0045a1f4a9b3e756208d59555249fb8412c37b825a19b5ad7b",
"app/Models/AiRun.php": "4c466497c2a149cbf3614775b65e884ba9790e5a6ab350cd1c41f17f216f3a16",
"app/Models/ClusterProject.php": "f7a2b5addaea3cfdbc30828526a620e1de1762b3e4bfd8123a4038a2fbe0f309",
"app/Models/Contact.php": "9bde71aa4063acdf908e3706986719a039750d6d8285c3b6a3a69c2030d3bae4",
"app/Models/Course.php": "76d58938d2dc508259a19c92d9fa0315af8ec0f8aa66b7f92e4ba4e54790300f",
"app/Models/CrmRecord.php": "7a0ca250364f7c5ec676807df438b77f662cd85aa30ece274faaec279a517008",
"app/Models/CrmTask.php": "01675a49d14685e27c391500f1d7e4c4c0d55af7ab4aa47b860bb2cae30fc4b5",
"app/Models/DevelopmentCorridor.php": "2143709560b929f38ebc479b85fb7308130566e795d7dc449fe551ce5664c985",
"app/Models/DomainRecord.php": "0bcbac4c31f8375bc8ad79e40aa3b53b862721ac2a22f15a26b4929eb8e490c2",
"app/Models/EconomicCluster.php": "e8460fc9acc4b3249693c7ed46fba46d365d869fe537aa12c74464087687fb71",
"app/Models/EducationInvestmentProposal.php": "50136e6ed9f8a644f70e492d625df5a9609ffe5b30d78578bc29e212dfff9214",
"app/Models/ExistingBusiness.php": "52f2f8c9a5a1b120b3573f0cbcecca9a33462b532b8b5e0e404f86874c18ec07",
"app/Models/ExistingBusinessMandate.php": "cc13c3a96db1acc980a0ef90fccac61d85c884bbc39f3ff0953b1595bacc58e1",
"app/Models/ExistingBusinessObject.php": "ae7d73fb1090723dc472cd0ad9ecb97bed6f10a07840ff89c2a0e55778808984",
"app/Models/GeoLocation.php": "de01aa587f6063b7de0b442beed98469eefa97ee4509e47ae83e94cf15b11414",
"app/Models/InterestRequest.php": "50c095520d26e779c670c5406b7ebc10f1659a35372af41f18b8731999ced027",
"app/Models/InvestmentDossier.php": "53737c61a7ed830b68f7ab1a2f30ac014896826494b7a1ef7d1821ca4c77d4ba",
"app/Models/InvestmentGap.php": "383da3cb1306b3b8121ea2a8d502f9c2ea368fe37eab5286be74559036240dcb",
"app/Models/InvestmentItem.php": "179743470b44baacc7609fea817ee11ea3bf6cb0bb779a5b9ddcbb3cf2dd5a9c",
"app/Models/InvestmentLegalSource.php": "73bb8d4d4429edf05312eb9b85c38210c41fc2671eda7f574a157ca84db2e0c7",
"app/Models/InvestmentSpecificNeed.php": "e1a288ec8b869e255a9b5929fa853add36028beef334e7507dc08c973120a9fd",
"app/Models/InvestmentSubmission.php": "e220f9c88acef6302ecbbd7e4fe4f19e8f30356f0296c9d45a53dff8fa2936aa",
"app/Models/InvestmentZone.php": "8489b2ecf71ba849c13e170efc878487b08dfc2de9d85d2b0d2ab82d00b99357",
"app/Models/Investor.php": "4ee58768ddb5c7691b364bad04b497a428a10ff63fad4475b51ee081b148cb8d",
"app/Models/InvestorJourney.php": "5de09adeb944d94c360dbe2249980d35157127cc3550f054f01e85d52d5e65e2",
"app/Models/LabourDemand.php": "01d27f7c6527d7c0a5ee327920a702af55f790aa3a7a8c820e5a384c65a476f0",
"app/Models/LandAssistanceCase.php": "705ab9476f0e6859c0ec8df8e6e8ee1522b23d49f4084fb8d058b0b9524f69e9",
"app/Models/Lead.php": "732b38bcb0f28dd68cd86f47659c1dbf01d805f3fff2f97c32a233421bf6343b",
"app/Models/Occupation.php": "41143d001e01c4844755292480b9946c3d481ad545a2467c5c2c3716aeb990df",
"app/Models/Opportunity.php": "db3ed93d14040c55888eee7f13d1e3eadd4cae5786ff525b03cf77a56f712dd2",
"app/Models/Project.php": "ba2c5caa85665eaa4118822cfe439b737cf5ec1230e33310146d463354a01564",
"app/Models/QuestionnaireVersion.php": "83ff9cdacbeda3ffda4d241f837c0048c2bcb977dd8d5a033c40bb0da9891f20",
"app/Models/Sector.php": "abd9b12c411bf9cce9b9de938ae1b9c5c5696e9ebf3de86c6300481e56a5d0e0",
"app/Models/Simulation.php": "9a3b23497e97b6b28a4dfbf85a19f87d367d2fe67d6115986904d3b89edb6cdc",
"app/Models/SimulationFormDraft.php": "bef40f3f7bc1d6a6ccea1f6c3ef038e4e60a4681375db1dbcb12fa407e17bfbb",
"app/Models/SimulationJob.php": "7029fe77dbe5290b8fb586f6f8340b6c8365d6176adedb88bce6e94460029c32",
"app/Models/SimulationObligation.php": "1524b2eb97974b2c5d070c51f59c65ec91dd06d937d5497954f96d3d4b7e0b52",
"app/Models/SimulationReport.php": "bfc911113a22c908b23e3a32219e88ab99d1528004fda99f0d45229498ee1b7b",
"app/Models/SimulationResult.php": "2f5f4d9c60aa8e2291c214433bb36b0741ca7738cfd47d6f6aa749d54e5cfdff",
"app/Models/SimulationResultSource.php": "e6a95cdf0805e04f260aaf5b0639136336ae9b52028106113b2dd604d1ec3082",
"app/Models/SimulationScenario.php": "7c79aa8acac92a5f3f3d9e44ec644131fd8ca0bfe84140ed8b53e61619259a1b",
"app/Models/SimulationTaxRuleVersion.php": "8d7a24d4a9243d8d8cd356d247d61422a98921e0d8073fe16ae28e13e440d0cb",
"app/Models/Skill.php": "180c87130ba86153cc7099922b03000f69e2ab761659d83a5a159c17d4813b40",
"app/Models/TrainingCapacity.php": "70dea08b17c70c36db37f11726026cd56cc8f6bb04eaa3808a7a0c8d72a748d0",
"app/Models/TrainingProvider.php": "6d556bfbdd242501d3e664726b52431a59aae9dbf5a21b5c666c0f9703a7a3b3",
"app/Models/User.php": "63f950a46c8dae576f1f8ddb236d3b7176f4f7c9b18b7736de9b26d4ba0aeb76",
"app/Models/ValueChain.php": "3890d84bd4f7eb83738c58087dc1a8a3ef98c2359a37a16a348b75c2f8c34b40",
"app/Models/ValueChainLink.php": "64429a190ecabdd5688fc1e4db033adea5e9ee76caeddfe62d547e8107c3bda7",
"app/Policies/ExistingBusinessPolicy.php": "00c9620b5375141ef73d61c616b469dfcc07524f09bb9eb4eb8023ece04d310b",
"app/Policies/SimulationPolicy.php": "681b76ca9fc717140a5c5a243a7bc16fbb66ded53ec973859ff03b89f60cafb6",
"app/Providers/AppServiceProvider.php": "78b436ad0a20df484d01a0f994f3fb46fe452a4181dda4146052424d14d182cf",
"app/Providers/FortifyServiceProvider.php": "0e49420e8450835e31b6c765343f40deea8f5d697471c330655c581c112e378c",
"app/Services/BusinessFormSchema.php": "a4145d8be1515b2d78910050f83fecafce4fa24e96a59026c95159c80877b4e7",
"app/Services/CartographyWorkbookAudit.php": "18186dc62542e653487f729775334ddfac0afdf9e96bb2c58cdffd691b41e95b",
"app/Services/ConvertInterestToLead.php": "b1c75250cbacc4f3f92a3815f8a78a5b9e8cc8f5635c617674dd169d2cf4639a",
"app/Services/CountryCatalogue.php": "fc0561dd0ee0e4c8340450892fcfb1c8678a7dd420428c60eb3890b2d82d9312",
"app/Services/DeclaredOriginStatistics.php": "6b73574974a951bc941cbb2fe2062de0f7940218b5c50a4acf0840829bf4f70e",
"app/Services/EducationGapCalculator.php": "7cbca9c8cb6b03d97866a368cfa627ec1f0351e4761a1aa2d00f29d2b383292b",
"app/Services/ExistingBusinessClassification.php": "17af07174fcfaebefcbef68e4527e28ad8452d6ec7c3881422921af5a7160d09",
"app/Services/ExistingBusinessDrafts.php": "07cc7008582d99b4507ab516dc4356b8694d7703de6cc8942035b99f798044e6",
"app/Services/ExistingBusinessIntake.php": "3ef03e137ff8241b2bd3ea64e00a0006de68ac20703edbbbb06d2837d09cbd1e",
"app/Services/ExistingBusinessObjects.php": "0ccb9a9fd8b0c2b4c5e940a0dfe37a0f1cbda70c3f2c10164ad8a7a63f6e7f16",
"app/Services/ExistingBusinessVerification.php": "ac444e2bb74703aaa3bca1b2141f4079aa44e0282c22196dc587c8411729fa53",
"app/Services/FintechInvestment.php": "d1d94c60aeb57ce4abca8aa479365a4f22fa8a327c8b00adf1daf109a5b7934e",
"app/Services/IdempotencyConflict.php": "0cf235eaf05f75eb8fea94c5dd024fdcb9053f52c93e6e8cb0d9d98e0bfc490d",
"app/Services/InstitutionalLinkMonitor.php": "d72d6d0d0017bd0d085e59cd324e0986c3696d73a854489a4b6fa12cc81bf544",
"app/Services/InterestSubmission.php": "47b561d0d52d4990928d2eda84faecb3beb8b207a2ec7c07b01068177961730f",
"app/Services/InterestWorkflow.php": "ae4939ce34156fa4833dc5c29aa0fd62a5e05844746fdaa0af6086770b15af86",
"app/Services/InvestmentCatalogue.php": "65fbb701f3ab589c3b08886f1a8adefa1bd782d30758176b804df4fd10541824",
"app/Services/InvestmentGeography.php": "7ea71267aafc87badf7c87f10cd11cb80cfdca52670fe3643c781b0a6acc7cb2",
"app/Services/InvestmentIdentity.php": "368ee3f2788b1011473c652dabd9c66618afadeb5463c606a2d8ef781fb3527f",
"app/Services/InvestmentRelations.php": "436e2e0e886741ee7e6440a447566f5c1ab0e9cad7e8fc88d298a5682bc2b92f",
"app/Services/InvestmentRelationshipRepair.php": "82c6496f504437ea32981ea04755238d8a9f55e0316e94117de2c9cf87b46c14",
"app/Services/InvestmentTerritorialTraceability.php": "4bc01f49f97a1089f88f46ef143ddcab931931a8d4510f03bcf8e3d487f63fc2",
"app/Services/InvestmentTerritorialValidation.php": "72de2f379db8fab7e40204d7e05ab971363a6f3e80f0301d73cb61e2588657f1",
"app/Services/InvestmentWorkspace.php": "75a7c7f01469291e5358a8e738dcded0dfd18213936bd96983750d3a951adf90",
"app/Services/InvestmentZoneAccess.php": "18707c3b5d69cb44a000632b982b3aae3e185f69a077d9a268086b3a8337f8f1",
"app/Services/InvestmentZones.php": "4ecacb6598b84673fa1f94118db3a54c065613e69c9516a43158904db6f102fd",
"app/Services/InvestorPath.php": "b81551118d0379f420731e9c972b8b2348e35a51f4ff9064d757bd8e5de14533",
"app/Services/InvestorPathDefinition.php": "288b43cfc27a665a9b9dc9d4630e24bca84ea72c02dcfc0ee9093be7382a1ec1",
"app/Services/LegacyContent.php": "29936d087001242566a5d6ae46ca2875b7911f327289249b4621450e2534345a",
"app/Services/OpportunityCanonicalContract.php": "78f7656b13a09830bd20e1cd4258e1f364e064851348fdbedcb745629f5c9591",
"app/Services/OpportunityCanonicalMetadata.php": "b620420f8d53bef285e271a615f8697efcdb01776346962a89b814714ca70142",
"app/Services/OpportunityCanonicalResponse.php": "21b67b9354235a9b586c9db87a7fd7221bc4ed9895b7bb9bc008f28a804b43d4",
"app/Services/OpportunityCanonicalValue.php": "1487d91443baf3d892d755e86d5def44185a42069132e6fe48cb86b15cc08353",
"app/Services/OpportunityCategoryFields.php": "f452092648f673a672277b2234294348e3ad9a1a601aa493bcac01851a5d9558",
"app/Services/OpportunityClassification.php": "fc924b187bbe1634a4723c4d11d1412228d7a90816189d2260b2e12f9d9a7cbe",
"app/Services/OpportunityCompleteness.php": "b6d4ae8b05cdf88327d1e0f1213cb6120cf09c273b21b4181c5183febac2f31b",
"app/Services/OpportunityContacts.php": "d186abf83a959069c61b837a2424ce78719286e32d94672e3eedbe46f419121a",
"app/Services/OpportunityImageProcessor.php": "ab0f244a004b018c626ebd5e60c22a05b2fe249f80e51145f325efea6b8aa2ac",
"app/Services/OpportunityManagement.php": "b8fbb40f7f143db71c380be64809e3e8ac2f92b9cdefe6206a0e98be598b9399",
"app/Services/OpportunityManagementInstallation.php": "6e21c7b0dcacc775d2c8dc9ea9daee9281d83059ffd3fa0a4a4c427aee6f3c20",
"app/Services/OpportunityMaturity.php": "d649aa4509abe30e4e9f9502ad89f5741bb7cce1b9d91bfef4e59bf58a1e5fa3",
"app/Services/OpportunityModularProfiles.php": "cb986c24a03bbc4722340f2a3a1392c1c334445c06ad6f725751afb588d79eaa",
"app/Services/OpportunityOriginReview.php": "e3c7061ff0d00ef064bc26a94e2adaea0cdfb146de670b8c70847561593cc35b",
"app/Services/OpportunityProfileWorkflow.php": "9c0f7f10efdc55da19e2baf3482d755ba9e6d7239382fc8cdf9c9be636859457",
"app/Services/OpportunityRealEstateDraft.php": "b03dd6401c23c09353ce64c4f198c9e6503bad55d5267776f508aa263975fc11",
"app/Services/OpportunityResourceInstallation.php": "791b17af7e003ff25160e6487341d7c6195a07fe47438435f4c5b0f052ffd7d5",
"app/Services/OpportunityResources.php": "21adfc77be4810576b64e07d4d1c1adef69ea6d34f0b67d959631593fe8282b2",
"app/Services/OpportunityReviewConditions.php": "0f4362a347eb1b8a4a95b05c037f0180ca40e76793bdcbb9eae51226861fba41",
"app/Services/OpportunityReviewMateriality.php": "afcf465a51a7dab1ff9f50d41243407b5e9d83aeb85fb5ef0af3ebacdf9b7eaf",
"app/Services/OpportunityWorkflowTasks.php": "2f9fb22446e535adeaadce24ba25fff7e5d9b1c240c9639d0e75b5bfbeef58d2",
"app/Services/OrganizationCountry.php": "cdced1699c1fb33db8d3001b801134c3e9ad954b71b045b04426370f90e14ad3",
"app/Services/OrganizationCountryInstallation.php": "fe7ab6843cb16c89e794ee23439bd322b55dede71c8ba15adc0e56f51ca8afe5",
"app/Services/PartnershipExchange.php": "5ac62230a6b1c93903378c4abc6c6884384aab85dd2ab37c1b5d4765430fd1ac",
"app/Services/PartnershipInstallation.php": "54fffd68e38a5e3b15c5ce37d1f8079e70e52f3a773b11698a34dc994e1c847d",
"app/Services/PartnershipMatching.php": "47e3a82b816a5006862e3d787b4d7b0445745f2d48dbe75391757abe068c3c1c",
"app/Services/PartnershipSources.php": "6f2b77169ea6f957223fef0dc5cd3dc95124032ac9a7c03483ec4fe2f2639a89",
"app/Services/PortalAudit.php": "27bac6fb750ebcfc32d0db6909776402716c792ca0a60c5fb05ec1df74227137",
"app/Services/PortalInternalDesignation.php": "e4628c479c913904f7c58890088aa9e59624d33ff37cbff76138b641a397bcf4",
"app/Services/PortalProfileAccess.php": "d4a79226771c96351c96d8382b77df52a52c2ee185a7b855ed66476edb11202d",
"app/Services/PortalProfileAdministration.php": "5001c87c962fee2d690ba0543d253e884cf5b2aa5dc983f43b08e3462bfe4203",
"app/Services/PortalProfileInstallation.php": "8a724e8abbfa2848a30a475b9fc4c61a6103acdadc613e0dfb5dc90a571f3a0b",
"app/Services/PortalSuperusers.php": "e36c75af077dd2a7bc8792baa3b8fc6d87ce34c50f4ae44c164b27cba5c553d2",
"app/Services/RetainedGeoJsonCollection.php": "5561fba6f062b3e2f9246dc1c2a230d209eb34f805772271949c57d5be4d2203",
"app/Services/SectorInvestment.php": "494421af0b3b989193dabcb679c6f0745c57b3af05ddfea6ef044ce40de66acb",
"app/Services/SimulationExecution.php": "d9ca669d3df1fffabe7ee8cc6b32107d0820fcf17b2bc297e65558fb9542fb52",
"app/Services/SimulationFormDraftPrivacyPolicy.php": "997e4402b7cb322b0bf322f9074c5a3f391f97e1d9550cb65069705f1f78ec74",
"app/Services/SimulationFormDrafts.php": "36563de817cb06b1b5f164e5702282d41d2fb7fdc9e50ce955d3a05e03ec472f",
"app/Services/SimulationTaxGovernanceAccess.php": "f6fe00673295f5874d78e2f1ab5c0e5175f81be6dc8ab04079bd17382f79f4a7",
"app/Services/SimulationTaxParameterResolver.php": "053876a03d4aca525fa9b8f4f8cd152bc6e57967d5f1f827c03ba1fc42ab27db",
"app/Services/SimulationTaxRuleExpression.php": "b8a36311baf5c134e72f9d265fdd898a257ea3f3fcc6035dfb9dd660dede4ed8",
"app/Services/SimulationTaxRuleGovernance.php": "437e959e519f8e45c23f83877c5caac3f8b98400278881a76a59d1f828632191",
"app/Services/TerritorialCsvAudit.php": "1dd3ff9b6ac545f3bc199a9f2e02c0a073fddbc130147f79ef52a8284c8d6eb5",
"app/Services/TerritorialRegistry.php": "bb3ea61a71d544a99c44ff880c85b2b815b1aae35c377476b95d80587486559d",
"app/Services/TerritoryGeometry.php": "08ec5a12ce2170f2f765442add2fdb6dcdcde4415f90028966109e531153bf95",
"app/Services/TerritoryGeometryImport.php": "ddfe1ba81be9a6940b74003325f18b0832db11ac28240509d9c2b8846d7c9480",
"app/Services/VerifiedDocumentBinary.php": "1b26a873bc28da916c1efda3b0ef1a1bbd28c266504b897ce30a9407f2b486c7",
"app/Services/VirtualDesk.php": "a053735e6fc019b94b09245c2acd107983a7fda66a784fc1c6d7e98f7d93b243",
"app/Services/VirtualDeskInstallation.php": "f6e1588d13e13e9ef4b11517f09b2389fc03ea440ed36b79a63d3225bef8af76",
"app/Services/Ai/AiGateway.php": "ddec947af17d966169a2337f5f2d68f2bbb2bed32978c9391a1c01fd3758632d",
"app/Services/Ai/AssistiveRules.php": "1e03a4235e6f9a7a865ac9cc98357a0ca8e590a3afb5d25607f8e4fa19679930",
"app/Services/Ai/EvidenceRepository.php": "19561a952f5af8420089271b102514e40ca7f99d6ea18c523d7cccb2b304c7b3",
"app/Services/Ai/HybridFusion.php": "4dd8c1575a88163636abd517ff92c2f50ac06ba67e3f3d216c52b08a976160f3",
"app/Services/Ai/InvestorGuidance.php": "8fc7b9ad608bfc88c1d887741ccbdcf2674887421ea90dfd1dec13cebb0794e8",
"app/Services/Ai/InvestorGuidanceEvidence.php": "795e3aa445b0acb02ac992adc63fd5626ea5b4cc464d68fb69294b7db8433c14",
"app/Services/Ai/InvestorGuidanceRules.php": "91f89953ff484420c2f78798a6048f231f4ad1adf8ef3907924621b787a6c78c",
"app/Services/Ai/SourceIngestion.php": "39518ea510a4b95b587558505967d07a22593f27e1b88b3817627a3f7f431da9",
"app/Services/Malware/ArchiveLimitInspector.php": "9b7efc0aedfd07806a926efe71fa7aa462d62f5922c871fa5799dcf8ae953693",
"app/Services/Malware/ClamDScanner.php": "394833a9e2f3d82aa3ce0c29df6882f9bf3e6d6cb279ae4e13bea358f78ecf3f",
"app/Services/Malware/MalwareScanner.php": "162edca81f840dda27c515816e959b867a47f4e7f566f41d63c4540f56db3fc9",
"app/Services/Mne/BusinessRepository.php": "b5ff5a6a55bde93258b443f3e4fe3ab940c89fee88c876de2fe30b499f5779a4",
"app/Services/Mne/CompatibilityBackfill.php": "25b6924f62fcc88fca04e3ae3d8c77e3413c3360dd9ae5d3caf11b39195adba9",
"app/Services/Mne/CompatibilityShadow.php": "654fb448354a17a740f1ec841ab65d31608c52b6a890eadc8ff043c6acc690e3",
"app/Services/Mne/CompatibleBusinessRepository.php": "9ea93e7ae7e7c1c5f020530cee535638a1da5ab57c3ab612561c0bb4ff617937",
"app/Services/Mne/IdentityResolver.php": "2736710cd35bcb795ababb22a7d35ab2b34cc68cad0c2c04c01dab506a1ecc42",
"app/Services/Mne/LegacyBusinessRepository.php": "37cfc6a7704e8221c3526dc380ff6fc0aec474067ce70d8c2c970d305f7fe85b",
"app/Services/Mne/MneBusinessRepository.php": "f763c296cc4106c4d791d35e6b862b847b9d8e44d26367d4fa95d4c06a7dbdcb",
"app/Services/Mne/SectorResolver.php": "2394b1ed6176552cec05fda7e239f17217e46c57948cbeda037189184d0b964d",
"app/Support/SkillsEducationMigration.php": "c0d96a418138049613662e4e8f583fc4170a35ddf443b1ccf1b3b06b5dd91342",
"config/app.php": "eacf313dcf76c1ca917065784eeac291e0cfabae8e52e19306103b2bab0ca583",
"config/auth.php": "c7e204e9785c9f596d66fb884b493f658f2327f157646bdb4088efd6b3a7773f",
"config/cache.php": "ee4ad2bba1edfcff52e9599f37371f2370d0b167cc226ce72d46cdf6edf2dc55",
"config/database.php": "02cd62f589b43d33f9ceac740705dac1dec9740eb2bb9e6e202d4b66a15244cf",
"config/document-requirements.php": "b3ccc0f1158314384b7a992a40def1af195b45c81fe1d4d62b57bf1264402356",
"config/education.php": "beea0a59c1078f3da63d9f020ac61ce8d1bc2310789feb314f8543cc8c32884a",
"config/existing-business.php": "c2c46436ad32dd52cdba99d2082fb8bd5d22e9aa486f89313c14bdc5eb6c3137",
"config/filesystems.php": "7e51d9aed3ee11bd8e15b6cdda38d02eebb378166cbe7c9f23980e1e6e3964b5",
"config/fortify.php": "bc7de1df10d3f66d02885afef6f133f54bb8e922fe5f7ed4088a16eaf13a6598",
"config/geometry-correspondences.php": "6eec57e1a108e82c51c9711bd2436f67e062e0c9058822efeaeef88a666b5cbc",
"config/geometry-import.php": "6bbbe72577bc3fd1123570a268af02015a3cc02a6bfedb2649d43e21e5b0f6f1",
"config/inertia.php": "80c68e12bf6cb64e39931e2467b43909893cea3eb6d04c3c1e68bdcb1236dfb7",
"config/investment-zones.php": "415c39d3587e069989c211c6267a3ea7e224c501899dc59c028af6700119e646",
"config/investmoz_ai.php": "587590b129e3dbd8c62b226cfbbae369763aa83b5cc098bf433e49daacd5324d",
"config/investor-path.php": "0940a08d699b6b95de67ad9ea791e8de3120064a8f44c46755b54239834104f3",
"config/legacy_content.php": "f5046ab156121519d05e4b44793241948bb5d81e6bac060d9893cdda87981007",
"config/logging.php": "beb1ffd0db910f6f0b4f75214c3d5aa385d692733ece8a450f4c169d2c99ce38",
"config/mail.php": "2d0879e0900bdc95dc6611811a6eac4f88aefd1a1607f33349aee6faf9cfe381",
"config/partnerships.php": "bd38c86021ba6f92c904965f3f1f92ab482b636c730a8fa165162f1bd955d1ab",
"config/portal.php": "ce50dca880179554af458ca94418357a799cd032c8f54572aaac1b5bc2a4135a",
"config/portal_profiles.php": "93758b42db760c966fade64a78c0d69d5168e371a2d6d88a8806f911e8b80c2a",
"config/queue.php": "02cb2143bde722caef3d682474a07675cbc8b97952c632110a4e17058eaa3a9c",
"config/services.php": "3fa143acc899f8ff5c86d9ad115b71692bbd84f5de7d6c51171f51e4a44a1a8e",
"config/session.php": "272de4fd3ad8b806f5726a34d2a4ad11cbdbd4184fcad17143280ee2a8d4c7d6",
"config/simulation-tax-governance.php": "cbebe6e251900055a809c2cc35f18c62e02e79231c5a06eb812087257af95c6f",
"config/suitecrm.php": "f217a1490dc597900adfac7bee2de00cdf8c8ecc2a78d5ba0b0f89beacc4b674",
"config/territorial.php": "7f5376cc8fe31e22cfb741a76545faca264b9879fdd02fd4af51458b0f67d6f6",
"config/virtual-desk.php": "e8dcbd93c06fdcc8de93eac9d9ac5d0959332cd35d2468123b542d289045174d",
"routes/api.php": "51a33855059223325a82e3944ed0fd0f8baeeddf065c07ab2527c06b2d5b2ed9",
"routes/console.php": "c623926e7fc9a9577ee5a5e67c56c5ddcd6de0024b50213163f003a1a9a1be09",
"routes/existing-business.php": "8aa4d914f47608f50d7ec6936a76934589d3664f39ac1686640443bdb34c5078",
"routes/investment-zones.php": "01fc7bd65b447fbf0a05154f518ee161b460a9aa2850d24bffa0618a71d0c877",
"routes/investment.php": "e5f3717da92548c2138792643e58c09281613742fad669cd8f095b231e31d049",
"routes/investor-path.php": "592c75fd8c6e7ca1e4636b2dbf9a9d81ac3f8a577616ad07e6a418d82fbcfb38",
"routes/land-assistance.php": "76522b6b78ab1a0319605aea5b57cca188e60a09ec2b5a6af4930ffb464b2410",
"routes/partnerships.php": "0bb5796d5ff98cf708969d58cfb256c606d6ef8d0dbcfa420729021078f2e5d2",
"routes/settings.php": "db0137dbd4b668aca2367c8eeaac7eda168c307b4d8a9f24fd367a1fc9bd7f79",
"routes/territorial-registry.php": "f857f6590b09677f8625a937d2ab5da76baf409207b7ffee7900ea71ff46e3c1",
"routes/virtual-desk.php": "cff6864e0b261ea086b50261c65fd056d6ddcd8fa9d71d6ad1bb07a738136cd2",
"routes/web.php": "049080ce60b271f9d1a28e5cb7a2a59d8973f6b562a3893b42057d39d336c10f",
"database/.gitignore": "e758642d95e83e907e010b6e46b07b3f953c7cef11fe5ebefc2a77b9d7b4d5f7",
"database/database.sqlite": "06d2ba75228190157767342f3421f0aba35017ce3187abe6800902f5f85d2203",
"database/data/industrial-park-candidate-drafts.json": "314d3374493eb5c8c23e1f693289bb743843065d2f08768692d93aba33ed8ec3",
"database/data/industrial-parks-reconciliation.json": "c9661ace4282f28d4b8f14a9c1dc24a2b8465193fe62869e4dc9bdef1cf0f196",
"database/data/investment-portfolio.json": "ae4a85af7c0542732333f5ca6c75a370ea82e6a46fba7a4c5476ddd9d57f143f",
"database/data/investment-reference-options.json": "72f419944f8ccc580aef20849f3b7e5e34acb1e8e753c34ecef55bcad3313ca2",
"database/data/investment-zones-initial.json": "73a45cb04dd9d9ba1bfa49089e1d551433488cf052719920e2c9484be35ef129",
"database/data/territory-locations.json": "7656e0657f68fd80c5f433ee46980a96a70e4b55eeccf8ce60f4b364966fda41",
"database/factories/InvestorFactory.php": "38db8127c708d1dcd41e9ffbce27593166156d050a082b60549e963e2499b585",
"database/factories/ProjectFactory.php": "e8851a5ce4751e8d34d3f50d8ef3d103c76c88b8278fe0097750944aabf88080",
"database/factories/UserFactory.php": "9fef56551ff7cc8a1f33014bdc90987e86934916c305d6f413d7466551d57bfc",
"database/migrations/0001_01_01_000000_create_users_table.php": "10d79883bc08ce46510f9ad8b1830b4d06d586dc56ae2c8bac3b3e491f69a90f",
"database/migrations/0001_01_01_000001_create_cache_table.php": "fbb4665e5a977e71df4e74ec75b3c06ca4f17ad0de7138fe9786639189978e77",
"database/migrations/0001_01_01_000002_create_jobs_table.php": "df4910687180313a14a3f96a8bddd808ae145ed1b107cd772caf865c0dc2b746",
"database/migrations/2024_01_01_000000_create_passkeys_table.php": "3c866281584abdc808b6b6fe1d28aae55d997d3f97c5dd2d07ae106ff58531fc",
"database/migrations/2025_08_14_170933_add_two_factor_columns_to_users_table.php": "79f22594944d826286ad1dafb13217967781e104dbb021a1c85fbdf9270db4a5",
"database/migrations/2026_01_01_000001_create_sectors_table.php": "7c14fadbf9fff20df321e4e04cfabd63f6c73ef1a60bf9c16d9bf2d80b2662f7",
"database/migrations/2026_01_01_000002_create_opportunities_table.php": "6d3c9c9ed11bf20751e3deef2a67a07087d58a235c5611724f397e01de3dca7d",
"database/migrations/2026_01_01_000003_create_interest_requests_table.php": "a7ea8a534af29639254f8c2ba49ed80c5b9fca92b5be76d93f5b1c84b5b1a5d9",
"database/migrations/2026_09_24_000100_investmoz_extensions_functions.php": "3daa494165853ba673f99012ed5651cfecfba153c676ae4b7099b9e6596ade38",
"database/migrations/2026_09_24_001000_investmoz_identity.php": "f644b0369b17b2954b05f563a569d92533ae1bb06f89bf1cc8454d069b733b96",
"database/migrations/2026_09_24_002000_investmoz_content.php": "9f3006caa7092eb3651033d7756982b176a54c79ac47a9cf9a67c306e369a81c",
"database/migrations/2026_09_24_003000_investmoz_geography.php": "405a75432fb9b90b4472c697a9239fc8d59907da8defbb985cf81cd3da958ee6",
"database/migrations/2026_09_24_004000_investmoz_projects.php": "7b7f652cf323299c346133e7fda6564722eab60e8bba193387f8fa2af8bf2d35",
"database/migrations/2026_09_24_005000_investmoz_clusters.php": "93dc9bff75f759fc209f00b1bbb2d6727fbf4d3014fa368db394254789ad7df1",
"database/migrations/2026_09_24_006000_investmoz_corridors.php": "8061e16466dfd505785bdd233851216cd01a62397d144da2f9c996a15b5481cf",
"database/migrations/2026_09_24_007000_investmoz_crm.php": "ef49c4e0b15f1a0e2eaccc6c60b578e88a616aeb42e3a420865bb29aa83009a8",
"database/migrations/2026_09_24_008000_investmoz_journey_aftercare.php": "f64af9031e071ff30b94df64c13f507800928d3bb54e5d7d0bd6a8f2c495cd51",
"database/migrations/2026_09_24_009000_investmoz_education.php": "fa6245b9a0a07dadd3512099450230919cfaa134c98b81c6362fb76abc9a3ea0",
"database/migrations/2026_09_24_009500_investmoz_document_links.php": "68601d5dec9410609ae34050b137b46af3d8e09e3510a331aa824fc58d01ed9f",
"database/migrations/2026_09_24_010000_investmoz_governance_ai.php": "c66ce3cf351a97f164c325c87941260a448b2b301ed037d251e0562143e48f85",
"database/migrations/2026_09_24_011000_investmoz_integrations.php": "3bab367d76ae5d3a9ef5836a95ddc41d01b35d24d119c7f1380b9153f4055b38",
"database/migrations/2026_09_24_012000_investmoz_indexes.php": "ff069e7a2cd518b104671bb2879444aba1df504fce6664cd61cce80038901eca",
"database/migrations/2026_09_24_013000_investmoz_triggers.php": "a41f8563aada3f3dba8882e67c3647fd1e9edc88f11b382af59399d380f6b83e",
"database/migrations/2026_09_25_100000_extend_crm_intake.php": "3a3dd9daa6d33f574ddb4b4ae10106785a5d4c32033d2df26370ab5f353930a1",
"database/migrations/2026_09_25_110000_create_investment_gaps.php": "ac63e17c82ffe0f3b7f8b123ba7b7758f84f81746446147b324b4c8aaae24d36",
"database/migrations/2026_09_25_120000_add_interest_submission_receipts.php": "d91b496f157bb4cfef1d4c3f90a9cbbfc58c4825a2b849cc089daacf199f7ff5",
"database/migrations/2026_09_25_130000_investment_portfolio_journeys.php": "fb568a7542308c8d547383a46178df65482351114cd11c79a36be53c02377988",
"database/migrations/2026_09_26_100000_education_intake.php": "f1be568973d1d36fadaa4596be3913d97915b78f749ceca67223b43eedf4860f",
"database/migrations/2026_09_26_110000_education_investment_proposals.php": "cb5424ac06378922e88c2e078a4dc43d7399f90ccb09bfc08b222f753acabd11",
"database/migrations/2026_09_26_120000_investmoz_ai_foundation.php": "a46234f6e9c6f4e7a9183591f1061109a579551c83596f8a5f05677d508bc114",
"database/migrations/2026_09_26_140000_portfolio_owner_approval.php": "581a459ebdbc13649926dccdb1510c0d18d098cb61d14b829d7e29128b28bf4f",
"database/migrations/2026_09_27_120000_public_portal_services.php": "78b52a15cd5ff297ab894ab11d2a76c46ad42b91622b866bb7c885e96f00fea3",
"database/migrations/2026_09_27_140000_investment_unification.php": "13f7dfefb524b60ed5e64d04a74961c942484e7bb2dfd88bf05847aca6f8ff23",
"database/migrations/2026_09_27_150000_investor_workspace.php": "e0a8e15f190c167d9ee8003a126ca04b63e8403d1cdd2bcd80f1e32a2e445005",
"database/migrations/2026_09_28_090000_version_investment_dossiers.php": "0799712b2fa00243f51a61f67333946fe88806d1aaf2a4df844de9f3e70b0433",
"database/migrations/2026_09_28_100000_investment_zone_foundation.php": "13272489c8d63a4691a59ede5c9d051e27c71d4f6d622fc36ec093e7645ceef0",
"database/migrations/2026_09_28_110000_zone_geometry_review.php": "ed1350417e63d83c568b526d5dc853f04629de5c45507ba6376505668d740331",
"database/migrations/2026_09_28_120000_investment_submission_zones.php": "005df60312dacd190f11c5fccf34ed7d499778fecac22e319b73d6f038d67680",
"database/migrations/2026_09_28_130000_existing_business_foundation.php": "70a11a505c2bbff501f8e175d60a1dc5dd31df127cc6fe33c908bfdbe4fddf7d",
"database/migrations/2026_09_28_140000_existing_business_intake.php": "0b438174960ec39b905ec352d227c1eaa475a11e122069bcd6bb9aa3b1b78fba",
"database/migrations/2026_09_28_150000_territorial_registry.php": "deec29bc66e1c3c3f3f36d2345d822665192620d6af8e5931000b5efa1bec274",
"database/migrations/2026_09_28_160000_investment_primary_territory.php": "5aef6eade1a1ef59aa173941d62342f526edc5075262f2812cf00605455b1981",
"database/migrations/2026_09_29_100000_territory_integrity.php": "e01f43328a121f3b8e5ad3e1e2b38cf5ae6cddda3a7e7266b57619a1b82bc92f",
"database/migrations/2026_09_29_200000_existing_business_form_sector.php": "ceb4080d5fdc8235a400d8b665156f1aed81c8f96ce92cff41325e5a00e40f6c",
"database/migrations/2026_09_30_100100_skills_education_1.php": "024c510fc512d642628bdd50e1b7cb6d11b6f7af5a2e31927b626615cc7e1bd9",
"database/migrations/2026_09_30_100200_skills_education_2.php": "00aaf84c56e041072ca3203fd39edc81fe2c353e4fc70b715e7c290c1e3c2280",
"database/migrations/2026_09_30_100300_skills_education_3.php": "d009706676e62a9ee3fca6b208d3b13c17141d8fd701f647f32e6404cde0b2f4",
"database/migrations/2026_09_30_100400_skills_education_4.php": "c8b2a61c5faa6b0b55a7188f0273b4f7cf2e33fab83a3bbc67db7be96c34658a",
"database/migrations/2026_09_30_100500_skills_education_5.php": "5c6fda4c6fb80cf37ebed1a39f16b2d86e8c96ef10640abbbd10dea65468e27e",
"database/migrations/2026_09_30_100600_skills_education_6.php": "2d46e02f41242f7045d0b230c9bfaf1d701a3baa2834e8c40708e6001412daf9",
"database/migrations/2026_09_30_110000_project_dependency_integrity.php": "f249120f0f643093a1c640cbbe18124b78e5f09e391527a5a662e457efc8d1d9",
"database/migrations/2026_09_30_120000_extend_existing_business_marketplace.php": "92e2720c44dec895b52cc4a29b779c1c51164bd925cdf50aeee79f125de20ca1",
"database/migrations/2026_10_01_000100_create_reference_catalogs.php": "8eeff960ac42fbb6032cc4012630f72c420f665a834d6ebda42c577267a60acb",
"database/migrations/2026_10_01_000200_create_simulation_execution_core.php": "1468ce4dbdd95b17c2d70c135b0a56a0b505bed5f6646de599326779e2557ea4",
"database/migrations/2026_10_01_120000_create_simulation_form_drafts.php": "3fc94c8302a6dd812c8e8d4be020b23697274bdc261755e77d1d2719de2ff988",
"database/migrations/2026_10_02_120000_allow_owner_to_read_soft_deleted_simulation_drafts.php": "d595329fe3a6139d71005e4921f315a505cc2994c320a07f0fac8254144f15df",
"database/migrations/2026_10_02_160000_extend_existing_business_opportunity_types.php": "bcc18791582d2d3d971ff17e2c880bb05ed7f4933780bb6d9723c1dd9fada7c9",
"database/migrations/2026_10_03_170000_create_simulation_tax_rule_governance.php": "45ff5ddc7605cc0d240c3c8f93b8a73dfc1a721cc3ea1841b365c2c6403b90fb",
"database/migrations/2026_10_03_180000_govern_investment_structure_relations.php": "af7c896a3c198ecfc9e186542bf22cf99e9f81ae0981caf4101038d0944366cf",
"database/migrations/2026_10_03_190000_allow_public_read_of_published_tax_parameters.php": "0ecf6107cb21a8af02b4b80c2804799a934bf5f90a599dc8d0fd6388596e5a53",
"database/migrations/2026_10_03_200000_create_land_assistance_cases.php": "d02e00e88ff9566f71e734651c5fc4f6f8d1963a94cca0e57f71f0de3815ce5e",
"database/migrations/2026_10_03_210000_make_interest_request_email_nullable.php": "0f4e014ff0ac76ed9b2e7a7d3d815c10dbaae7e0b9e08d78a955649a2fca2bf6",
"database/migrations/2026_10_04_120000_add_opportunity_geography_scope.php": "f877d0e33d85a27051038ed952d0e6fdc532f6c29e6a7e4ee8ac052663926563",
"database/migrations/2026_10_04_120000_add_simulation_draft_continuity.php": "9c2f83cd5d3257b4ff63c91bf92c859432635b1f53b16bdd1037457916e9ada2",
"database/migrations/2026_10_04_130000_extend_investment_zone_records.php": "bd7fb6af86073cbbfb03e219c8401225eb09618a0b538245a2d0f581c945edf7",
"database/migrations/2026_10_04_140000_create_investment_zone_attachments.php": "f5bb1afb2fc90379749b1e294b73e6c383ccbbd4f68417a5612c5d3e78619a9d",
"database/migrations/2026_10_04_150000_relax_zone_operator_publication_requirement.php": "807d4c8a7c143a8c01058dd73e607c0d805c67aea7fd20ff108365b87a11e46a",
"database/migrations/2026_10_04_160000_extend_zone_development_and_area_scopes.php": "041c09d968c921aa27ece295f3a904feb701117fca42053133ec09e56dfa0fb1",
"database/migrations/2026_10_05_120000_extend_portal_document_catalogue.php": "d799fc0feddb6839060c3997dcfdbd32283b23b24d3ab5fb2626ab070eae9490",
"database/migrations/2026_10_05_130000_add_document_malware_scanning.php": "6e968d047ed54ecd88b37689e1b2885e23cb51b67596dd982902d2db26ab09ab",
"database/migrations/2026_10_06_140000_allow_unapproved_private_portal_resources.php": "4683ac0861dc0b66f20b8b6dc06369ad007272b1cdaadd7410efb987b0c9458d",
"database/migrations/2026_10_06_180000_add_document_applicability_dates.php": "6f3389c323741d2947bbbbd5f2002db18aa9babc4d20c63d4a3d48bde8923e08",
"database/migrations/2026_10_06_200000_add_document_requirement_evidence_links.php": "935d36cdd2d08487a31a426a9676642c37f1262fa30ce78c91d203a925c8f867",
"database/migrations/2026_10_06_210000_allow_informational_zone_publication_without_second_publisher.php": "fe33d216608040be464cab06d75efbc23340d4e7ccd259dfa7d0b909802a08da",
"database/migrations/2026_10_06_220000_add_company_purchase_business_modality.php": "7df04852ef45a7c33238f23a8274f63e2d187d58f56b7376b037e4931d655ce5",
"database/migrations/2026_10_07_160000_extend_internal_partnership_exchange.php": "558ae77d99ad35b32719462bc773e159c62a390101eecc827d7f8b74fc129784",
"database/migrations/2026_10_07_190000_create_internal_virtual_desk.php": "4a91b9ae313084feb913533f79ce2c61662c2110d38dd5effd98f6cd6fa1bd3f",
"database/migrations/2026_10_08_120000_extend_desk_investor_guidance.php": "bec56cead85748e3c28bba21f79086984d177d63b5194a38b385d7b2e19ec4b5",
"database/migrations/2026_10_09_020000_extend_opportunity_management.php": "8a804748cc6b2b537bb7c0e10e09dff3dc4d89b6c974b9f909a198adb2dd048d",
"database/migrations/2026_10_09_030000_extend_opportunity_resources.php": "d4e5c753ede8216e1d383865178c6db37c5422c21c3c8e7458cd4ee1e68659ed",
"database/migrations/2026_10_09_190000_prepare_investor_path.php": "939c2b2e5f9fd6a454fe7f8dd4f4373fd7df53f80e5c5f169db08e6e4c676728",
"database/migrations/2026_10_10_040000_create_portal_profile_authorization.php": "797c27b5f201b65e825fbdea6fd0ea49de2f9d48b1a9bf210d76af285224cc93",
"database/migrations/2026_10_10_050000_extend_organization_country.php": "1f4556f9c38c4b3aa85e34281ba3fc4113a61eab0f1d64193711a67e7ab18d30",
"database/seeders/DatabaseSeeder.php": "65365566a876ec8377a19173467bcc3a5711dd92bb5e88f5742c35ac9b8ad5e3",
"database/seeders/InvestmentAreaSeeder.php": "f757e84fd2701e991141c0e39862e26264284d87f9693958e228bc64984c8cc8",
"database/seeders/InvestmentPortfolioSeeder.php": "6e9e1f91e5e52eec46974dfd454a8c22a7805aab817c8db25f32be97f5858ba0",
"database/seeders/InvestmentReferenceSeeder.php": "6676e751f41dab976754317027c50c0da2729d0b9fe47892057f3f9aef0fca64",
"database/seeders/InvestMozReferenceSeeder.php": "b8cefc04fe38b8f1d8c40fc527e9671a2fc34a80557165f1675a03b1ad45ff93",
"database/seeders/LocalTestUserSeeder.php": "39b08e776ca7974c0ebb6302c622560deb6f3dd13824c53ecd0c9949bb4683e7",
"database/seeders/OpportunitySeeder.php": "7f1d9e65a71a680e66827cce952fc357227ea33943a2b17a9f42a2283833ba42",
"database/seeders/ProductionReferenceSeeder.php": "31aa9137f70d03e3bd3023ca1e24a11f60ed8a6109f36a19a7db79e53582ae09",
"database/seeders/ReferenceCatalogSeeder.php": "5167f9ada8e543b7c45d35944598d7040df02045a134fa9d35ac6a61bb479dd6",
"database/seeders/SampleManagerAccountsSeeder.php": "417215b953920d043a4c69c37f8488d1fb60bff651da0adf26ce96920d296b14",
"database/seeders/SectorSeeder.php": "3ddc96a7f7d7340a81c678b891dfd658dec9a06235695f051ea9f6ef524d02cc",
"database/seeders/TerritoryReferenceSeeder.php": "6706502c2438ea9478fa2edf34229f8f8821e199bc45f62f91364d0d75a52392",
"database/sql/skills-education/01.sql": "4a1fbf9ff4fff4839ba79a6825953c939cfb1cab9eb0e0ac46180324cfbd2053",
"database/sql/skills-education/02.sql": "99956b920ec2c8125c8e9f886f2f8b866f5472efa35673bd700d172d7eedbdb1",
"database/sql/skills-education/03.sql": "d88066850aee76382e1d60c6ef7752a451735eb048f90c826cf3f00fb538b2f0",
"database/sql/skills-education/04.sql": "87602b41487717ee72f4ffc9e3ead6a43a201ef7195c04953441a5f3459d8b85",
"database/sql/skills-education/05.sql": "951255fc078ae401ba8e5b162a613daa19082589a714f32548e3c71abe706f9c",
"database/sql/skills-education/06.sql": "cc01578c909b5b629055377ef7cc86d6d1cabe5706fe824f57d66b3fb3dc2a08",
"resources/css/app.css": "5ce36ae9288aeac7076e5548d78c0878c212181cb6b2d837d3b6137795e20239",
"resources/data/investmoz-opportunity-modular.schema.json": "7765d133c103355ed6534311e8f6b2473be6963bbb31645d4cc3a612a4e8ac78",
"resources/data/investmoz-opportunity-modular.source.json": "80d77c0670f819d8450f80609c169a050c9d5487a8604dedba77fcc089d8029b",
"resources/data/iso3166.tab": "837c80785080c8433fd9d4ea87e78f161ac7a40389301c5153d4f90198baeb2a",
"resources/js/app.tsx": "e852d5b96b15e7219bc632615949d9040bb34806c2da92e3c33e6e11f1d778a2",
"resources/js/actions/App/index.ts": "c6d561133623313382aad0840150305e7b69b6de1cf7fc13cf8d37f314055fac",
"resources/js/actions/App/Http/index.ts": "0b55b9d20a4a7464c270c1eb7c9c7340520835951956fd2bf5c2f5970696a372",
"resources/js/actions/App/Http/Controllers/AiController.ts": "310f362f99884a80cd755ce853f53bc2c641d32a3e69a15fb87f2884197c1ff2",
"resources/js/actions/App/Http/Controllers/ClusterValueChainController.ts": "0e4818d93040b786731a4f4f0a5d906fdfdbc507fe935a93a80deb2dc76ebe43",
"resources/js/actions/App/Http/Controllers/CrmController.ts": "00cc740e3ff5c7a935c5bd1a92a69334361788aef0b2722f892c5666d44f3a24",
"resources/js/actions/App/Http/Controllers/DashboardController.ts": "3224a256cb76c58a731ef9e92a015ba3479057eb32bd58c1c289070edc650b6f",
"resources/js/actions/App/Http/Controllers/DocumentMalwareController.ts": "8c80c18bb70c8c95043b206e662e11b90e94d362695e1ffca446f662674ad6c5",
"resources/js/actions/App/Http/Controllers/EducationController.ts": "f56cfe5141d5fe74dcb888a5cbb3fcc0967fdee592676682ee5622bbd097608a",
"resources/js/actions/App/Http/Controllers/EducationInvestmentController.ts": "78892e990c1df9f3f147951d65b34235865dd1f4ccb82d1e81a72f23a9f770a9",
"resources/js/actions/App/Http/Controllers/ExistingBusinessController.ts": "2be958d053a796afcd5f042c96d8d0c7369c42e2f7be0a214abbaef357c972c2",
"resources/js/actions/App/Http/Controllers/index.ts": "19644ba49db87e03d08c60011e8a6cc10117b527b75390889ecc47e386fcecaa",
"resources/js/actions/App/Http/Controllers/InvestmentContextController.ts": "2e7b1831c903ce8ae13ecc6d563f44f9be1b856ffe15d046e77b75e427550a14",
"resources/js/actions/App/Http/Controllers/InvestmentCoordinatesController.ts": "49bc6558eab060408f27e89a7115b00fc767f2db4aa6e7c090ee242320455382",
"resources/js/actions/App/Http/Controllers/InvestmentDiscoveryController.ts": "2ba110295e1fd1d8d547fa6d581c8511188e56f10f5062b8f7bc3004f93df953",
"resources/js/actions/App/Http/Controllers/InvestmentLegalSourceController.ts": "aa40baec6c2c71cf10166b12722d0d09bdd2b55e70f66a71d5a28b2c489d726f",
"resources/js/actions/App/Http/Controllers/InvestmentPortfolioController.ts": "1ae14f69fb82c9f6bd41af786f39aede23fc5f5b958e179c09b38f3152a6786c",
"resources/js/actions/App/Http/Controllers/InvestmentRelationshipRepairController.ts": "e51e1656bd6adf3dad125f9605158cd6f796bacedd0af4da8389f4ac741c3d29",
"resources/js/actions/App/Http/Controllers/InvestmentStructureController.ts": "f22ba2a1e7f3375b04f1a488e1708aad17d6962c32df899c978457714eea9ecc",
"resources/js/actions/App/Http/Controllers/InvestmentStructureRelationController.ts": "0b98080380ef7672413b4d7e20747f0ab401b17c727e1acb0633cfe3be77592a",
"resources/js/actions/App/Http/Controllers/InvestmentSubmissionController.ts": "3468701b1b411ec9d2ed5c8fa927b0f3932deae523872f531185a339e03bcbfa",
"resources/js/actions/App/Http/Controllers/InvestmentTerritoryController.ts": "617922c2a5bb35b44a02bd7c3db7b5a39374efaef5ac17e9c6481045f1cb0ceb",
"resources/js/actions/App/Http/Controllers/InvestmentWorkspaceController.ts": "2762bbd3528a2069282dc164dac81342d6c0a3486bca09e7ad7030dc997a8c84",
"resources/js/actions/App/Http/Controllers/InvestmentZoneAttachmentController.ts": "f0b9843e24bc2a5e20ea600ae1b3f3602dd6abf997ca00ac35d77a387121b747",
"resources/js/actions/App/Http/Controllers/InvestmentZoneController.ts": "5bb9200b3ee0db2efe3f0321d835be63215f7147318991dce26604281e3fcb8f",
"resources/js/actions/App/Http/Controllers/InvestmentZoneGeometryController.ts": "10550cd13c344415017f3ae355915c96d73a6f7d3671e90611b03bde3771edcf",
"resources/js/actions/App/Http/Controllers/InvestmentZoneLinkController.ts": "1968603f89620c7e4759b1d526578aeb1c14e6490843bf314cc50cf80505c117",
"resources/js/actions/App/Http/Controllers/InvestmentZoneRelationController.ts": "1db58fcfeea381c351e5d4de7fedb8f66fd9bfa03df65b44429632dcbca9096b",
"resources/js/actions/App/Http/Controllers/InvestorGuidanceController.ts": "49c4902932b9a51bf1d92cbe55ce125883d153d4c6f514f74012ec63f5d2ef9b",
"resources/js/actions/App/Http/Controllers/InvestorPathController.ts": "c80520dd1dbfc14bc3361e3320a0145ab852c15c710061ab5a95a64aff404cd8",
"resources/js/actions/App/Http/Controllers/InvestorWorkspaceController.ts": "365106c90da959a18df4e7e96def82d21bfcb611c4f1497f5bc54f16dbff095d",
"resources/js/actions/App/Http/Controllers/LandAssistanceController.ts": "1309157865723242ab18cffd0e6aa062b1669a01e77a1642feaaaf2eabdf2bc5",
"resources/js/actions/App/Http/Controllers/LegacyContentController.ts": "edca5b9b0ca466515fc340d65f48dfb92732c6567d78fdeb64c3e1850815dd5e",
"resources/js/actions/App/Http/Controllers/OpportunityManagementController.ts": "d276edde8dcb5ed7c930b22d99e660974dd97ebc5269ae5dbcf292777a35631c",
"resources/js/actions/App/Http/Controllers/OpportunityOriginReviewController.ts": "aef57f071793ff0b02b8806888bc0522245a1da58f4a3b715df175acda6a1f8d",
"resources/js/actions/App/Http/Controllers/OpportunityResourceController.ts": "89edc98e77553c9d12dd7941e9d919053495f21082f040fee32daa6cea8222fa",
"resources/js/actions/App/Http/Controllers/PartnershipExchangeController.ts": "b4e7ac0b79301b799d00a6a8ac66a39327b2694be6366d33d3d776c856c461fc",
"resources/js/actions/App/Http/Controllers/PartnershipInstallationController.ts": "1d76a415e78ff2cf4462a3d93393edfbe075a6c986cc3607c8b8a09cb5449dc8",
"resources/js/actions/App/Http/Controllers/PortalManagementController.ts": "1376cc533ff8ba93aefc8d69a583836d9692b587acd1e5b47caf53918797e7e2",
"resources/js/actions/App/Http/Controllers/PortalProfileController.ts": "aa26beb95f76b01600d988bcb02b2c43dcaff8681b20291f3d2a7fe4b48b9f98",
"resources/js/actions/App/Http/Controllers/PortalProfileInstallationController.ts": "39c3719ec2bade78bb72f32dfd6c60cdd60361bf086180132dcf86f56d45233d",
"resources/js/actions/App/Http/Controllers/PortalServicesController.ts": "05a00e55a98b35062abe862a00aa4d3b726210695b1b5b509f009b1a88a7eb8c",
"resources/js/actions/App/Http/Controllers/PublicBusinessOpportunityController.ts": "6a237ad7002b90ba6d88b4a51e2d93db974eb6f01b50a134e5325a75a2a47047",
"resources/js/actions/App/Http/Controllers/PublicGeographyController.ts": "c3dc1f008dcf868cd1d42e9046e5606be277dc696e5865ca3cc7a6eeff0bb30e",
"resources/js/actions/App/Http/Controllers/PublicPortalController.ts": "b76b552f6e0c7c68d23ae5055e276b2da8135bb15ec8ad0a77d4d372ca3af5d1",
"resources/js/actions/App/Http/Controllers/SimulationTaxRuleGovernanceController.ts": "084b25150ed1acc28fcca7c886161dd98686dcf2ff2443b1cb2b9df8c3581216",
"resources/js/actions/App/Http/Controllers/TerritorialRegistryController.ts": "ee6c23d144320733e768c35182a65a9bc6b4974b637210ecce0c6e852bdfec67",
"resources/js/actions/App/Http/Controllers/TerritoryGeometryImportController.ts": "bc540e47263ffa86fbc33f84ba284506d7733d11ffb6af1214c7fc60ba4d3224",
"resources/js/actions/App/Http/Controllers/VirtualDeskController.ts": "72f9b4cb27d05eb1cd115449b87ee49435e082b784a83eb5b2ef1ce3c99e8a10",
"resources/js/actions/App/Http/Controllers/VirtualDeskInstallationController.ts": "926f03c248aaf2493be1a19f02caa86180c015dee001ffc085f90ccea436aa54",
"resources/js/actions/App/Http/Controllers/VirtualDeskOperationsController.ts": "b313370b1c273e8ba06c589af79db12912312b506ff09bba4d10702774854b62",
"resources/js/actions/App/Http/Controllers/Api/index.ts": "65a5cf087ef5953a3b647e0b2b5e3f250bf1546b6309fcc22e64a7c968e5af82",
"resources/js/actions/App/Http/Controllers/Api/V1/HomeController.ts": "5c35ad5441564c2c9b23de6ae489446f3451a98b53ff8b690062e468309da67f",
"resources/js/actions/App/Http/Controllers/Api/V1/index.ts": "4790aeccae49183ca00b2ec42e5f9a29ee3f42dda9b3596264129741c84d17aa",
"resources/js/actions/App/Http/Controllers/Api/V1/InterestRequestController.ts": "c35464fa3b6dcdac8a5716154feb3d484b5ecdce566e078a93f657d97400d5c2",
"resources/js/actions/App/Http/Controllers/Api/V1/LegislationSourceController.ts": "b8c041e9d91235bb7e0566b9d1b71446eb50fcf6432e85feb080a672e02a41a0",
"resources/js/actions/App/Http/Controllers/Api/V1/OpportunityController.ts": "bd48c4f3dfc6f9f8af803500459364884ff1d4242408e3e618348505b5d14f2a",
"resources/js/actions/App/Http/Controllers/Api/V1/ReferenceCatalogController.ts": "20623a546807bff5048fbbf89af695fdaac25c9a0bf37531336403630d48139c",
"resources/js/actions/App/Http/Controllers/Api/V1/SectorController.ts": "562f80cf59f78bae8574263e775452000e6e06ca109b4a09862fbc47ae69f3ee",
"resources/js/actions/App/Http/Controllers/Api/V1/SimulationController.ts": "93aba895ae23d75c6322650d723f02b292f61a1b6564af2a02d767fede356c63",
"resources/js/actions/App/Http/Controllers/Api/V1/SimulationFormDraftController.ts": "18c4779d34ce2e1abeeedcfdc809574422e72133b60bb6f56e3f037ae54083dc",
"resources/js/actions/App/Http/Controllers/Api/V1/SimulationTaxParameterController.ts": "2c6f015a93d6da766a1960c29b2315db17f391ed7c41cbe37499843c32a31759",
"resources/js/actions/App/Http/Controllers/Settings/index.ts": "e0adf324ae0e36956f61b63d6aacd254a17e5fa4fc6a3d29402a3ce1620dd0a0",
"resources/js/actions/App/Http/Controllers/Settings/ProfileController.ts": "7313726f725e743555112f40e0fc8710829bba067eea0d87dcffd8ed478dc03c",
"resources/js/actions/App/Http/Controllers/Settings/SecurityController.ts": "f245533c2e84c6271f047680dc817bf12be63c3e02f3f97b0d6c55e0e95b929f",
"resources/js/actions/Illuminate/index.ts": "5e9fe597eed0c242b053b49076b248dedb585cec6ccb2a20101cea14da6e4c28",
"resources/js/actions/Illuminate/Routing/index.ts": "88142a675525a48c2f2c9e28ea1ab2f5e8f37c98bf9e0a0f6295f2222589b522",
"resources/js/actions/Illuminate/Routing/RedirectController.ts": "b3d9199482a9417ed1d6c0c7e1aa7efbf634fd8126f91a8e66ca132ceb37c890",
"resources/js/actions/Inertia/Controller.ts": "4a7cb28472ad6d35f718054f9de4e967cfa76ca1bec8cc05b0e553b27006b983",
"resources/js/actions/Inertia/index.ts": "f170c7ba412a0bfa44d8b3ed9e3523cf244d00801a0ef4c73bccd9bccfeb1107",
"resources/js/actions/Inertia/DevTools/index.ts": "a74cb264c047488c8b3138cb4cc36b5dd72b2ffc2e414dd3fab8205bba76d3e4",
"resources/js/actions/Inertia/DevTools/Http/EntriesController.ts": "e16d2f9a4b5710ba1dcedb027e8d15d2ef1ece3cbb7aff940fb61d4cf46bf6c7",
"resources/js/actions/Inertia/DevTools/Http/index.ts": "90ef8bf9af6f62a66a2a87787e151fb8013580df43953cace2aa4296d3fdfbca",
"resources/js/actions/Laravel/index.ts": "1077bc3732b450e978452c90a9162a11df3c5627ebb66dcc8d4841ab32f5ee05",
"resources/js/actions/Laravel/Fortify/index.ts": "4b2326063175a4cbb8d5faf1c299151d9617b47036fbc82c3d5e564dc6534270",
"resources/js/actions/Laravel/Fortify/Http/index.ts": "0b55b9d20a4a7464c270c1eb7c9c7340520835951956fd2bf5c2f5970696a372",
"resources/js/actions/Laravel/Fortify/Http/Controllers/AuthenticatedSessionController.ts": "a4d7379c4ecfeb721adf65abd9f130f7906747edfcfd28686862317a38fa92c9",
"resources/js/actions/Laravel/Fortify/Http/Controllers/ConfirmablePasswordController.ts": "0eb50613d04546b333fb735c66368b25de335e3dc376d04c7c426c3e001edfa9",
"resources/js/actions/Laravel/Fortify/Http/Controllers/ConfirmedPasswordStatusController.ts": "707b5b99ce5fbc0e21fdafaee71d85831ae781aadebdcf597e33d324a47fe1c1",
"resources/js/actions/Laravel/Fortify/Http/Controllers/ConfirmedTwoFactorAuthenticationController.ts": "3ccdf038cfea9df01513c087b3a4ea9da5cb76830a9207f258731ba1117224ce",
"resources/js/actions/Laravel/Fortify/Http/Controllers/EmailVerificationNotificationController.ts": "f534405e501ee6393c728704af08521cdd492668020d96d1de584473f39d59d0",
"resources/js/actions/Laravel/Fortify/Http/Controllers/EmailVerificationPromptController.ts": "a43af96c03453f0a5833b133ee1e6f3f4ee072c09b346c185a0dc6e22574e498",
"resources/js/actions/Laravel/Fortify/Http/Controllers/index.ts": "0f2e8c4c68c26bb344272dde56982d11a2ea9754fa5fdb8f514eccd9c3672d74",
"resources/js/actions/Laravel/Fortify/Http/Controllers/NewPasswordController.ts": "ef50c1a93f738bd8be906edd85f154c8c3b8ee23ab2dac45862c2f4fa851027e",
"resources/js/actions/Laravel/Fortify/Http/Controllers/PasswordResetLinkController.ts": "414aaf7c4a8949ba2e4a6a2a5f916325ca2d7b8f7ea8ea57cc10ad227dbc50e0",
"resources/js/actions/Laravel/Fortify/Http/Controllers/RecoveryCodeController.ts": "78ba0c43903d6b1e198e80931e26d0247eb3e58e7b789e3ee71f336eaced170c",
"resources/js/actions/Laravel/Fortify/Http/Controllers/RegisteredUserController.ts": "d852bf6adea905d60dfb727605abc01505d55c5b6f01cc04db019f2e7b960423",
"resources/js/actions/Laravel/Fortify/Http/Controllers/TwoFactorAuthenticatedSessionController.ts": "ee505723357577ddcf843e156a5e69c5d26da3e03c6bf70128c407f376b5fe8e",
"resources/js/actions/Laravel/Fortify/Http/Controllers/TwoFactorAuthenticationController.ts": "4407bf5ca09eeb54bd167db7ee51d1a9545d6dee20c8104ab924b2651c81b75e",
"resources/js/actions/Laravel/Fortify/Http/Controllers/TwoFactorQrCodeController.ts": "021d7142d66724d7e2da246d71960ab1aa65a41b4380058dc091f5256b4997bb",
"resources/js/actions/Laravel/Fortify/Http/Controllers/TwoFactorSecretKeyController.ts": "0e917ec3356f8ba3ae4b77aa1bb863c79e579a14f9b33d8b14604ccac9c6d30b",
"resources/js/actions/Laravel/Fortify/Http/Controllers/VerifyEmailController.ts": "36c94a831ad5cf2e670eb06490499963a106243f7b17316b61cb03e5f302a510",
"resources/js/actions/Laravel/Passkeys/index.ts": "a74fdfb05e73ef7209382b3531e356bb1a34d1776ab5d56c8c0786dd34df0e10",
"resources/js/actions/Laravel/Passkeys/Http/index.ts": "0b55b9d20a4a7464c270c1eb7c9c7340520835951956fd2bf5c2f5970696a372",
"resources/js/actions/Laravel/Passkeys/Http/Controllers/index.ts": "747ff1c0b944e6dfdc485958bb3a2c16772b0cfcd172f72b2803ff48fdd99466",
"resources/js/actions/Laravel/Passkeys/Http/Controllers/PasskeyConfirmationController.ts": "d5daa2ad82e6271f97bfbd96658b005c7360646195a3562d68c30a1fe5419a30",
"resources/js/actions/Laravel/Passkeys/Http/Controllers/PasskeyLoginController.ts": "bc68eded49a4c4b7160f995ca791706b0ce398ba64f3b2c28e02e0eb95ef8558",
"resources/js/actions/Laravel/Passkeys/Http/Controllers/PasskeyRegistrationController.ts": "fcb4dcd36ac04ec9503e7cc26359461485c83224e4163e97603e54a386024be8",
"resources/js/components/alert-error.tsx": "bb2845205fd65353a13cc2d4bd91eb6615521ca81f7bfe811536a2563953b34f",
"resources/js/components/app-content.tsx": "3e1108b00c0343c5b467483b33e9278ffb2778d4c8e7877f0c63a1b879e272bb",
"resources/js/components/app-header.tsx": "268aeb25a0bcbcb7460c0ab9a8c026bf2b3ad21e57b4d0512a2af8a7629416e7",
"resources/js/components/app-logo-icon.tsx": "b9fc868aef3f74410cc0bb821c165292c6ff1c36a0d687a65919309b66a7475c",
"resources/js/components/app-logo.tsx": "eed72cc4da3cea15a8e5d75b84b12d05575da829bf898a2b04ac1d2aedc765a0",
"resources/js/components/app-shell.tsx": "e290b18e92dec75b60b0ef4ff69aa78e398fe6e2f98a9ae13e1df18616253348",
"resources/js/components/app-sidebar-header.tsx": "9d4bd87e66b385789a99efde4d7d79ff9b479452cc40d45105e9f32b9f2d24e0",
"resources/js/components/app-sidebar.tsx": "fe41a7c709675278a9089071752860e832db2d861ed247b243b50c16a50f3451",
"resources/js/components/appearance-tabs.tsx": "77f8e26a951dd669d7b7dbdc2e53afbdcb4b503645f83a2d8b4770299602ab92",
"resources/js/components/breadcrumbs.tsx": "b6968897d551e98eaf73a87ae7cede9d53b4f88d6757cad0008404a6990555e3",
"resources/js/components/country-select.tsx": "6392f1054c36f87c10503201b04f93ed88f9c19fbf8d1b4155c761be0f8e3e3d",
"resources/js/components/delete-user.tsx": "32e58456a6268f423b2ab1d4405497833584a52d72e210c29435b1d1aef50a43",
"resources/js/components/desk-internal-operations.tsx": "697cbf7dc54020947607a96f1442b78039cd4895ef5b8c408ff9635735719773",
"resources/js/components/fintech-investment.tsx": "b0ba0af0da1da4a7ce7f1281370c766afea8ef5b26a14b4ed27186c526aad640",
"resources/js/components/heading.tsx": "22b088092301a7afd15bebfd515a9128b5a507d0e502f65fc2069d1b81b7d178",
"resources/js/components/input-error.tsx": "6a7e5e44d6a77d8ee0c7b0896b53b94784341a5c7cfd7825d4499e8593a313b4",
"resources/js/components/interactive-investment-map.tsx": "63248875b73182f0f29a7532e7da96592a1ef6cd87f423d7f68a274ffccd5657",
"resources/js/components/investment-coordinates.tsx": "361fc644c64a9a827d75051b437dc5d0491cb05dcdb16236d7affea5905efb7f",
"resources/js/components/investment-map-panel.tsx": "1bdab2aa862e970a71b7b4bba7f2fb3466250d76a0c2515bebe99afb71f84cc8",
"resources/js/components/investment-roadmap.tsx": "1d3f2835b03eb072c745e174b70983cca84c7a16f575b7c5a52072cfcc51f087",
"resources/js/components/investment-territory.tsx": "fc693426f374ea6b544b758c3bfb66229c197f8fd48d8e5c1d9f18b137a228a1",
"resources/js/components/investor-guidance.tsx": "66f12681140a1202f4b98e001039fcf7a9c142aeba874724e4147acfca2707af",
"resources/js/components/journey-companion.tsx": "73a6c20b5c0998e9ae2e0d7fd7e152f1493b4502dd7df1c6a11e6226a5c81a34",
"resources/js/components/journey-document-resources.tsx": "372d84eebae80b980e7559d453b567a129d4d6390901182518db06fb94dd19b7",
"resources/js/components/manage-passkeys.tsx": "18bb74a9673ddf319718404d158e9bb6d8bfaec6e3a4af653b40b4fefd0e4d97",
"resources/js/components/manage-two-factor.tsx": "71f9f55c1c82f0a9dd8a20c818542d048994a04bb8d503660f3727fe0bde7738",
"resources/js/components/nav-footer.tsx": "357eeed7fde8937dcb629272896526ab223343f540bd30c2a087504d8433550a",
"resources/js/components/nav-main.tsx": "e168bd24c34c260d6d2b91ec5514176694066d200b10ebec0d9b0d92db787327",
"resources/js/components/nav-user.tsx": "7a003397c732b1d25df125c43ee58b1a906ba3353f5d721aeacf99fbed165cc6",
"resources/js/components/opportunity-canonical-fields.tsx": "542ee4d6bdbd259fc1c7a5a41757bb78279cc4210bbe75d2d377f894598cc83d",
"resources/js/components/opportunity-classification.tsx": "91a609af736dcaefac3e47ebab30156e8081f7ae5024f38066b8ef9dfdb3505b",
"resources/js/components/opportunity-contact-form.tsx": "a4029bef84283c70973d709e9fe6cbd60a564641e806eba640b38b8e4b733910",
"resources/js/components/opportunity-parcel-geometry.tsx": "0fa65eeade8d6e1a1b11ccd079fb40f9247dcd45105563d2f7665e7490a1edaf",
"resources/js/components/opportunity-profile-actions.tsx": "ae26baa8aa60b4c6c20093a332c4d26644a67ee0ab3e511c995ea7327133bb44",
"resources/js/components/partnership-search-results.tsx": "afe5f5537caf7c2a0e0e71822b2ce27a7aaa946b6764e9cf32bb5aa751621504",
"resources/js/components/partnership-source-links.tsx": "167af5b0e0fdf997121e327c68ace7acd3df0aef9ebf9ab08f2c095bae4278d5",
"resources/js/components/passkey-item.tsx": "265c94637a6922eb1b569b7538221e8f1de0459d39aa8d813f7f6d6d015f761b",
"resources/js/components/passkey-register.tsx": "bf34f22b8763dfc34566dc497b9d83f627bc6bf05f118f5962084c270cbc7f8e",
"resources/js/components/passkey-verify.tsx": "032dbba8d857074c7e39d57a8043ff21c37b2db0ebb3d0d5e37de703f4a345ae",
"resources/js/components/password-input.tsx": "25a9961de6d319f6c34ff090965a35ee67b9d2a30ba1483a3d4674b3bb4c83f5",
"resources/js/components/portal-grouped-menu.tsx": "a9ff5bc1ef0126f67a0f00cc13dd3fe087af98a0bfad5feb3cb8fe13214901a3",
"resources/js/components/profile-navigation.tsx": "416770e73af5d6ea121a71024d786cec7d20e7679bff604ca1ef30a9d2f98890",
"resources/js/components/project-dossier-export.tsx": "25d787f4d81354c4cd477603b5c0fc3e3b31d7644f75faa513a1f9a099408c47",
"resources/js/components/project-planning.tsx": "c06629c89124f2a44402c8c30cfd7c51f19dd884f70287ea6609107373a96c57",
"resources/js/components/project-readiness.tsx": "b1ede2bcdea2eae2f408c52e87afab5b15fcf01cacc9e4325d1ba16b3383119f",
"resources/js/components/sector-entry.tsx": "4a38870164da882159e58b4f211c337c4fa95953cc7eb19e7b6fed27e931e95c",
"resources/js/components/simulation-business-plan.tsx": "440067d2a025db83093338e3b2e8275345392e07b9f310dac84d59b194e2b924",
"resources/js/components/simulation-cashflow-planner.tsx": "5db5cc5396fb4dd29bf938a3de3367b902a587e4e23aa4698c13f040fffe5669",
"resources/js/components/simulation-financial-tools.tsx": "b9eeb05e5825e2d8bebdf20a7f26ef7481b70278553a16d8f3f39bf84db9156d",
"resources/js/components/simulation-fiscal-status.tsx": "a332d69b2a9faa17f42132011184d86406344a6e9426ccceadf74696f1b4578b",
"resources/js/components/simulation-form.tsx": "d789dfdf7c8b2be4a00e0b0e195a0fdd2bfff91440559db8d773bf841df9f56a",
"resources/js/components/structure-geography.tsx": "61416bcec30e40a17b530ff8547af0a4cfba339a3ed31571a3eb44f3e5c6c830",
"resources/js/components/territorial-source-evidence.tsx": "30ae75ad9d60fc541b9ea467eb0680007e4e83ecabacafc0052caaf9e39ccd11",
"resources/js/components/territorial-traceability-plan.tsx": "bd9ffcd4262bd45ec42073b11f75598ca64aa062b8aee3f2daf08992c972d73d",
"resources/js/components/territory-geometry-preview.tsx": "a93b28be70f69540e965293983818eed601ee9af6d083abe2390ef274317711d",
"resources/js/components/text-link.tsx": "d0b1698349e777ed052f0292f44536280d9bb7559b9d5e4c5284d1d1b6565309",
"resources/js/components/two-factor-recovery-codes.tsx": "39e846e7669b76e362c6f61f1ed43fdb2b5a2922dbef9680e047a6bbae44dbfc",
"resources/js/components/two-factor-setup-modal.tsx": "82cfb1e8bf4e002177b2ce2ba3b086912015cd8b905f4b59cfa7c22029eafe8b",
"resources/js/components/user-info.tsx": "d94732380d4339fcfeed37799c406a2bf63f36d43046fc0302b209eec40d829e",
"resources/js/components/user-menu-content.tsx": "de31a540ad229f5383161085392d96b04d9cc56c8589bd21644dc528288992d6",
"resources/js/components/ui/alert.tsx": "ce9841beb06b4b3a2c88dbfb46f9635d198827870becdfd3e2619181e28fdf61",
"resources/js/components/ui/avatar.tsx": "1e8837e409f4ede09137c6a01d290047ac2c0c306991d4872cf499c77b9aff2a",
"resources/js/components/ui/badge.tsx": "da6d8f237f7fd88fd9dd0e83863d9cf65a473f3affaccb5547b1b6503bc815ac",
"resources/js/components/ui/breadcrumb.tsx": "fe3dd16bdc11190bd19d0b320496d7303749a4e360da98f345f93507058483fd",
"resources/js/components/ui/button.tsx": "1260ee658e71b21d59827ca3e86d87ce131a7846484146a1640acfa91b0b6706",
"resources/js/components/ui/card.tsx": "18889fc98cb42833b3d9e3534f891e5d05477533db42511b71ed667b59d316a0",
"resources/js/components/ui/checkbox.tsx": "8300e569667bfa905c5b1e1f0c63d0efeff87066203ed1750aebb2b3cf2eb08b",
"resources/js/components/ui/collapsible.tsx": "661444318605c90d19e47e4d21289a68b4c5f7f01782be70dafa80d3f7a4cd08",
"resources/js/components/ui/dialog.tsx": "ca9fc2582c30924a90f294d1a11b3cc39a2acb0c0224f2704eb9a2167a557c54",
"resources/js/components/ui/dropdown-menu.tsx": "f5f8b2a584f42085b647fe59a009d6238ddfc61d1aa1325561cb543f95d1189a",
"resources/js/components/ui/icon.tsx": "8b04f9bdcefe76ac7d9f31ab6f325e6d2725a83be29f1e4ccb47b16ab8d48f88",
"resources/js/components/ui/input-otp.tsx": "59dc19f93bd031e8320c7df571cd9509e8c1ceb6337506ef380d11b2e10e2550",
"resources/js/components/ui/input.tsx": "17da6ceadd3932f8c4269c34e29fcdad73e490bff5bcf76b6c57d47656631695",
"resources/js/components/ui/label.tsx": "883e35baf22dee1847066678ada2a6aabca32a91c1de4fdc074c6c48140498fe",
"resources/js/components/ui/navigation-menu.tsx": "6c08ab109f9a0285de6806714161b0e7fdca443aff9beb23d8ee06112af6f46c",
"resources/js/components/ui/placeholder-pattern.tsx": "91d8ef7a075067aab8d270c70391d37b75095433633b6738254e6a944afcfae3",
"resources/js/components/ui/select.tsx": "b4e61d449d531da0caf056862ecc214450672ca20c5abdd19f367962c3a0c3f5",
"resources/js/components/ui/separator.tsx": "54d4fb628c7a5c9edddd464b7c988f5690f7b831ea1375e5ba03a58b2891ee9a",
"resources/js/components/ui/sheet.tsx": "4c9c0e6e8727a3229046c5f9571401801ec35bdc8f2b91d0bcbf00ac725302fc",
"resources/js/components/ui/sidebar.tsx": "ca7677aa94cdcf8e973d281aa539273d81264cf54e8f7c3f2e4f99e7b37b053c",
"resources/js/components/ui/skeleton.tsx": "48687fbbfb522a48bdd3e0c93ae0fc4a1621641b4d048903dcfd3b80ce65d6c0",
"resources/js/components/ui/sonner.tsx": "61bd65543a0873ca4ccc4a75cf8421f96cb7f42f8494f2c7552798d6c478b83a",
"resources/js/components/ui/spinner.tsx": "3e6e6e8d37fb4069f8e43e55318f8db06fbc36e6c8be0096da3c9337c1c798b9",
"resources/js/components/ui/toggle-group.tsx": "af297bdf6c9e996af24b27943d6d6cf07afd73d6189a03b71452dc8d8e952cb0",
"resources/js/components/ui/toggle.tsx": "9dab8dcb383661cb660482b41f22e819240d45519a6126232f0eaa35493da1ae",
"resources/js/components/ui/tooltip.tsx": "616e0392245fc59e083fda696ce3512c5fe395351550bfa54bd4b28fd33fd09a",
"resources/js/hooks/use-appearance.tsx": "e91f589c28237176e1e7f5ec21b044c6ad7d9e57fba7afedce0174fd8692240c",
"resources/js/hooks/use-clipboard.ts": "815d9595d6489472581d27944f71d4a53856b1650028dc7dfec37b392d7fce52",
"resources/js/hooks/use-current-url.ts": "ea024f22b8b487bf8319bf884dba8ca5b22fef7d7a9cc8c3d9d58eef1ac5566c",
"resources/js/hooks/use-flash-toast.ts": "27964275a33cb65510e302721a3dc79650cf4eab10ca880adee223b5fdbcf5f7",
"resources/js/hooks/use-initials.tsx": "6d77fee1bfbe966d909725098d14a1e16e67974d1bb15bfa5f9a34bb11abfaf9",
"resources/js/hooks/use-mobile-navigation.ts": "17bac38d056a8dba07f4e2e6e4f000cb7fbd1ff4cfb1f911e440f114c48c6e7f",
"resources/js/hooks/use-mobile.tsx": "c2e8f66c36554591115a5f8f5587d9ce4f84f45d0d13670db1064b18c4b38070",
"resources/js/hooks/use-portal-query.ts": "492356ab615e0ae8513a206c9cd252023622bfab9b4af44c2d4b3fc2ad1c8449",
"resources/js/hooks/use-two-factor-auth.ts": "b13bca63e1e259c67300a31f3c76f05419bf70c9efe31163317c3c3a9372046d",
"resources/js/layouts/app-layout.tsx": "ac429029d84184f1357f441ff1b605514832a6f7edc13e167eb6aecf785536a2",
"resources/js/layouts/auth-layout.tsx": "aaa1eb9cbb9ef27690c24577c8479286397711afd897b3dec8a0b8ff5b4d49ae",
"resources/js/layouts/portal-navigation.tsx": "bed2b4b2a72ce24549d25777d0fb38f18cbfa04aa2d16ae7a5d26463d69dec59",
"resources/js/layouts/app/app-header-layout.tsx": "0ec583aa7c1702bfcce30ba759c80ab39a6b0bd6de4d89446fbc6d26d927bbd8",
"resources/js/layouts/app/app-sidebar-layout.tsx": "fc87bd85d4905b552a06255f850b1a5c1b8eefeb9b025e48e17770a4774781cd",
"resources/js/layouts/auth/auth-card-layout.tsx": "2bbeed8068ab5aa3298448b06b642554df4aac5c58654b91126429ab5d8407ca",
"resources/js/layouts/auth/auth-simple-layout.tsx": "546d3fc038d19a5ad434523c619ed701ced1d9a8f657a0644ce571e81987044e",
"resources/js/layouts/auth/auth-split-layout.tsx": "8fa78eb6e22f8218269cdba7fe94abdd1a527c04c955b19c0963428200c7a62f",
"resources/js/layouts/settings/layout.tsx": "8189ceafbe93d5b7e268be3f5470956864c23b3b37a5a4a3f2d0883770b77387",
"resources/js/lib/business-financial-plan.ts": "b1239b12904508aa50ded1e903c014a54fccc2d950279918abbebe1481b2af2f",
"resources/js/lib/business-locations.ts": "5b6be5b5f168a3437d412d4132620eaa30dabaf27c12274aa7049bad2a38599e",
"resources/js/lib/csv.d.ts": "c0bb5214a11bc49a42622e7c4c591ff394b200ac535f3d9a0224aa7fe922608f",
"resources/js/lib/csv.js": "67deca744dc9cf35b4192d01f0dd79c819a09bd98ffc9a7f092f938f07d322ee",
"resources/js/lib/display-value.ts": "96d23210c16b2b87d343968173339b8942eda48ecf763ea4f2cc9212f2ec95be",
"resources/js/lib/financial-calculators.ts": "4c9517a7d1c9184ec61076589c13c1b18d6e87aa30f551088120c3e5b6872674",
"resources/js/lib/financial-fiscal-bridge.ts": "5a30c501653b16b5fedcb12631ce81fcce4fe473aa542e94374986b3c50f2d33",
"resources/js/lib/fiscal-preparation-guide.ts": "54e2a3965d531b3e57f41c2a9e4cf20a58110cca5fc34e550c8042af85b8c45e",
"resources/js/lib/investment-maturity.ts": "8202a8cb6aba756b5d94f0ff921476f7c650ef04b2d0e725fd8e9fccae3100ea",
"resources/js/lib/investment-roadmap-source.ts": "6ffbfb11b9819c867616e3591e46ad8aab7e81ab1e77b9f4c72db6f72de53a5f",
"resources/js/lib/investment-roadmap.ts": "1dae4942ad731bc25a61adcb2faacf2050d6bfdfa4a57435846d933540fb3263",
"resources/js/lib/investor-guidance-finance.ts": "db9cac40c97f39e7326780e99b2e02ef58324c765172d6c5fb98d8e93d428876",
"resources/js/lib/investor-path.ts": "5c391a14d99a6dc58de3e574881a75ed08927f24f26b2914a68352e3dc160a91",
"resources/js/lib/monthly-cashflow.ts": "498982fba04ad919b3c01d86c655e2487dc8ccbbca20b17955bc5b4bdc0d021d",
"resources/js/lib/operation-key.ts": "7b7480725b113da56a2d18b756566f64eb442693243b8cdce403f265cfc713ac",
"resources/js/lib/portal-api.ts": "fb5b7424f8ed3a734959cffaa19abfeb83f22be1cbb52813b033479209e65b65",
"resources/js/lib/portal-navigation.ts": "fc2a4986eb48795024e8501983ce35f8fa772198be911183b329ccafb888ec62",
"resources/js/lib/profile-json.ts": "fdf04c41e4e6e4e2b9efd3ffb0e5cbc9c91fc281fd99caf63a6e64652ca5b69c",
"resources/js/lib/project-dossier-report.ts": "79f59571976c6cb3c56ac3287ed7b0be3da987deca9a6518230aeb5ed7e5e146",
"resources/js/lib/project-dossier.ts": "ce492036402fb504df71614e9ae83199c420fe25edcf0f89af10e2cfc873f28e",
"resources/js/lib/project-readiness.ts": "21b6f3e21169ca1ad47e0ffefdb5e5fd788db4e60294a36d2e12285c74bb3f13",
"resources/js/lib/simulation-api.ts": "e6c5529ea6c98c54dd2ade09e53b4167211eda6c53605146c95a1bcc97b5b1cd",
"resources/js/lib/simulation-contract.ts": "23365cc5dfe53aa02b051da69c0d565ad241d0ebe8cddc7a68707619dbadb24b",
"resources/js/lib/simulation-form.ts": "a5ba51215c2b1ca916951607eddcb4bef3b04002c1c99a3456ad1c10dbd92b99",
"resources/js/lib/territory-path.d.ts": "f32f3245221e6bad9e6fda506c7fdedf709bc7a0aac492e6c737326fb8c7e72f",
"resources/js/lib/territory-path.js": "c6ed286f0724a2e7fb1d6eb566d0269ab001fae3d0b1de810979da0f1bd619ad",
"resources/js/lib/utils.ts": "69e09bd57c6975cdd8f2d573d92f04d1cc5529aacd83ec38be676a41344a9cb6",
"resources/js/lib/value-text.ts": "7afe5719fe9d96f66ef587fe0c65769f67ca076b2edb040b20c8fa36aa443e8f",
"resources/js/pages/dashboard.tsx": "3741131e1511dcaf41d17229f4fe843c6b466d8d9ec76c31f8714be771dbe658",
"resources/js/pages/management-access.tsx": "a1cf40cc375619717c0f28b8563313e1383815efc0e48fe55cc9a477ac4744fb",
"resources/js/pages/PortalInvestidor.tsx": "6b0e6ced3d7ebdcbbdecb3698d0a327c8b368f59cf6a50cdc6fce50f5cd765a9",
"resources/js/pages/welcome.tsx": "52c0636bc46d5aacdcf6897877d9a44baa78349b7c2c5429589dca97760c1c9d",
"resources/js/pages/ai/index.tsx": "92b65313d5be839d4468c4fe9e476a5391920b091ba41f245383bf278c28bb96",
"resources/js/pages/ai/labels.ts": "24bcca674adc01b17e6e82c7ba26941f72a1fc6e5dec71406eab543e4ffb7c11",
"resources/js/pages/ai/result.tsx": "6a860ed3bb95ca87a25268f581e55d6dd973d2453b62fd086567ebf94dd044e9",
"resources/js/pages/auth/confirm-password.tsx": "315abca0ed7f2029e13393e69b7e7c45dac6541bb31a58d05858f247d98d6699",
"resources/js/pages/auth/forgot-password.tsx": "f17d22c2bc9ea061046ea70f6d2a74e0609210b5307279ed96bbae9b20836b24",
"resources/js/pages/auth/login.tsx": "30b0c2d18c0e0b6ed7820f32d99597fbf4d3b796a3d3e88ffaed1e79756ee48a",
"resources/js/pages/auth/register.tsx": "e4750552f97e4d99e6c54b6d31429077423a645803766f8004b1a13b9ebb7ab5",
"resources/js/pages/auth/reset-password.tsx": "30d78c3a675265c2afa4491f7d1aa7ebdeb39459fe86e157dd387d73e0e3762c",
"resources/js/pages/auth/two-factor-challenge.tsx": "b032c52e00df7a04d2c412275cfa0af5ad7b4d88a81d92fa1c50b5fa34e75fbb",
"resources/js/pages/auth/verify-email.tsx": "38d763f949717537a7547f2e875e760b9805a8af697427f433fc0056fe8091e2",
"resources/js/pages/crm/convert.tsx": "180e31528301fbe79555f2f4bccb744405e9f4c75bddb6f83b08acbe9942470e",
"resources/js/pages/crm/investor.tsx": "4fcb654e37d95b56f7d78fd39e0ca87db5e5a4f3a2ebe552276a49959f0fdabe",
"resources/js/pages/crm/investors.tsx": "5f7b25473616c9653710ffca3f0bb1c02fa8fce9298db51e342ef4fca9c4991c",
"resources/js/pages/crm/lead.tsx": "5ae878f337fa7149931ed1bf7e9440d6761174dd4bd6874fd0649ab9f4538c40",
"resources/js/pages/crm/leads.tsx": "b56122d8dfce7215519293902c09a240a380c3026557ce68542ab1465fd704e4",
"resources/js/pages/crm/types.ts": "e862516ce24e283e21bf9fc7e7d0a9a8d5082c6ee079741a039ff76cceb5df98",
"resources/js/pages/desk/case.tsx": "c9f4430320fbd5de350bdb12511524e7aaf19f59b8bfc61fa9cac67aa87f724a",
"resources/js/pages/desk/catalogue.tsx": "2ee2b9e4c19056839fdbef897b3abe1e05326778c0f93b78f75dd2655b937c1f",
"resources/js/pages/desk/install.tsx": "429fd29e620a76a07cfbc5123dacc9eebe10f41c8152fa9b4982ab8280507f39",
"resources/js/pages/desk/panel.tsx": "8615e6a8943f7196b3340d16b38e9b9f0465c595d013b56f1aee35e1b2984958",
"resources/js/pages/desk/request.tsx": "72eea8b42083a74094c9f7182fbac7ee371207b2bd9e457f634a9285614aa651",
"resources/js/pages/desk/sources.tsx": "09a65801fc2dc3209681b96c540473551aac213d938e8135a6b412a9d13d19c2",
"resources/js/pages/education/analysis.tsx": "ed85602ec44ece0d57558a6312557af82f43f024f9cc37ed73f8e485d4c5ab14",
"resources/js/pages/education/index.tsx": "23997d56db5ead556df9ddd7a531c78c3cd93834429a86a948d61ddb621b9170",
"resources/js/pages/investment/business-classification.tsx": "81cc6e1a9ce6671f8999f9bb414ce812350ae38436018dc2e6c48b41787b7f11",
"resources/js/pages/investment/business-interest.tsx": "2785ebeba2a4756f029514cb4ca2a6d8b312d2c292b5b71e2761b431c3e3dc7c",
"resources/js/pages/investment/business-marketplace.tsx": "5f4cceecac53c2734cef7d0fbed7a7073374e23b0342eb1a63fc22b20a7f30c6",
"resources/js/pages/investment/business-objects.tsx": "a22f742f80ec7f42304cf508368cf5e9726bcaff898d0537d6b2231bd049e37d",
"resources/js/pages/investment/business-opportunity.tsx": "c726c2126ee364f209cc92d5c5324a478ce48090ea00b3a68c816a74c20e5499",
"resources/js/pages/investment/business-types.ts": "0964a8006b8e548c545c1528c6856487574b9cadb713de6e5c7d9ec924325f31",
"resources/js/pages/investment/business-verifications.tsx": "3d056d699860b866d5feed87eac103f88baacc6e899d460bf18dd451ab232fcb",
"resources/js/pages/investment/business-wizard.tsx": "ed55901ea94c73c279525599b205c19ce197037dd3756311876f2b9acfda379a",
"resources/js/pages/investment/business.tsx": "6aa95b7c864d6f559417ce181110ffbefa59fa51278d97f5e137dab6d83c943d",
"resources/js/pages/investment/businesses.tsx": "6b3a267b11cec5eb7161ac437d632f468d002a980751833b37b38a2d6cb3171b",
"resources/js/pages/investment/catalogue.tsx": "649955876ab712c4cba0bdadf1dd3fa511ad10059b58cd4c242a5f84f7c8be2b",
"resources/js/pages/investment/context.tsx": "b30e198c135fbc51beca1602e4d2093ed6c25d960daf96fb1af8a30931200ff0",
"resources/js/pages/investment/conversation.tsx": "75258f0a0e36496ecfc39b9d4328ed5ce2cd3a1e3176db48a4a0b5b4f282a136",
"resources/js/pages/investment/detail.tsx": "c83686fa00fda4de82f3a8d3c842d0526b10635a2b76b1c3ec54d69c96a69e6d",
"resources/js/pages/investment/notifications.tsx": "58a178ba65c30abb322d9ff207d82ab96e0b265e8e990d8da729438bfd43c1ba",
"resources/js/pages/investment/profile.tsx": "d73f99da40a2d43cf24009dd12e11849ccbea8f9703ba97a89518fafb64e19e1",
"resources/js/pages/investment/references.tsx": "d9d8402e6028d5762e17917b8abe5dba4bdb98856070cc980666ef412c87c05d",
"resources/js/pages/investment/shared.tsx": "56180116aab60d81e345506a9732081878825e143ab452f88df292299cccdce4",
"resources/js/pages/investment/submission.tsx": "563c48a71f80d6bda040ac0ac2a6a1610f8519cf15cd57d83b901618818c91a8",
"resources/js/pages/investment/workspace.tsx": "b3d66e759b97752b99b582e22ac09b02d50c404d674cc879808c5b7c0cc95dcb",
"resources/js/pages/investment/zone-attachments.tsx": "7cfc19a333814e62816409187b3db1482513bb4a5ea47182dbab24f7d023be87",
"resources/js/pages/investment/zone-map.tsx": "67748dff3e4c9e45f96f1ce816f7b08c359d4b3c52bb7fc07ed4623332411ef3",
"resources/js/pages/investment/zone-relations.tsx": "4c37d1f2f3cd1f5d79d20dd7341be7dfaf93fe9a8f0b405f579d405bf7edbba9",
"resources/js/pages/investment/zone.tsx": "ee23463c1ea011bafdfa692120f9e8aac6054415ecc6e883701bf9af537b0625",
"resources/js/pages/investment/zones.tsx": "435a622f8d116d6264ddfa1a81cb28b1746d5070b38980c3dd1f28fff6cf6e34",
"resources/js/pages/investor-path/index.tsx": "46faf0a76b388f55206ae8abe1d5e1fdfff682d04fcabf0644803f06e676432f",
"resources/js/pages/investor-path/show.tsx": "ec718a1c56884878a7bf3707ec4ee32a712c045f7b3f03c7d88b4edcbdcd3d05",
"resources/js/pages/land-assistance/blank.tsx": "a6a6aa46a84e56140396c0cc5f40f94ecfcc288876c48dc2a596b55e723daaea",
"resources/js/pages/land-assistance/case.tsx": "ea1937b9ee8ea641ecbcff588ebea06c8aac59762c9f800b11bdf908f69b54d9",
"resources/js/pages/land-assistance/form.tsx": "f9357ac8797ac2a0ba8d9a2022fb5c466d8afc55c57ed02deb144f1bf582f6cf",
"resources/js/pages/land-assistance/guide.tsx": "76a7fce16dc4caaff9c686f25dcc296f2f75256011e0a8bf37addbe80bb9fb7b",
"resources/js/pages/land-assistance/management.tsx": "0da325efe885eaad9a8d05777506b640896a0c30d9f32ccc848f12b0f5a1054c",
"resources/js/pages/land-assistance/print.tsx": "6678d39eacafa102790280a85aa93ec6f9af212a99a2d915385d541df81e678e",
"resources/js/pages/land-assistance/workspace.tsx": "53af95e1cc863b543e87977ab991a829a3b69f57417cdc8292c8ac74f34c0681",
"resources/js/pages/management/catalog.tsx": "d9cf92603e1f3eb67816f7171c206e5dc014f55bb339213f845035dc7971d0f7",
"resources/js/pages/management/editor.tsx": "6defe474cae401d2479a79fe8db3b8be2517e13d1395457e825bdc48a2b764b3",
"resources/js/pages/management/history.tsx": "e825d960893f7975a087577453c331df1e1f2237941755574e189643f9f88441",
"resources/js/pages/management/interest.tsx": "6a7b70fe44e6b97cfecfb464ac9d18f28a8c0ebb74772669990a8ecb83488574",
"resources/js/pages/management/interests.tsx": "173655307accb1ab4607795ae968a1d54759af0d035e5cbe8fba1e1b7b9e5d06",
"resources/js/pages/management/opportunities.tsx": "38f2095ee7881117fcfc08284cb96619aea1217bcebc57be2908712b043cc63f",
"resources/js/pages/management/opportunity-draft.tsx": "d40a69e4f3e4234c4a67732794e53e311c0f4e47c353e9f1535cdbd7e6664ef1",
"resources/js/pages/management/opportunity-install.tsx": "fdbf0b9ff2015c3ba67e5a6ad9b7204fcc8b694640faa3fbeb93b88e078a5275",
"resources/js/pages/management/opportunity-origin.tsx": "29935debe44d88543747541db18298a1b786e63952cb3185d3bdc745e8ea4637",
"resources/js/pages/management/opportunity-resources.tsx": "e607f176cbcda274573565552f7e0876edd1740fbf6da9e6134cf50aecbf721a",
"resources/js/pages/management/relationship-repair.tsx": "8df4c0ef844585a9672119ccbcc37e8fbed020e2bc3112de4bfc11072674504d",
"resources/js/pages/management/shared.tsx": "3d66f10938ff959dff1aa622400cf8c15edb49d3eef4e2d561e2de7e14acdb12",
"resources/js/pages/management/territory-associations.tsx": "9328925919e21d7821acbc2b6dfd6ffff13a3c78a3ba4085e4f42fd20897268e",
"resources/js/pages/management/territory-geometry-import.tsx": "750b2d2a5c84e699325303702971c583525aee47965ecc3064da6e3031c39f99",
"resources/js/pages/partnerships/catalogue.tsx": "b6e906a61243971757f34b1cc6efd05cedfc4335231ffa69eb8a368e99a84b1b",
"resources/js/pages/partnerships/dashboard.tsx": "03fdc581753feed918140ccff3859df11a675fa2464355fbfbfaa7e28775ecec",
"resources/js/pages/partnerships/detail.tsx": "6cb08764284963ee23a4beab57817bf8ae6b78f7a90607a233ff35723d76af4a",
"resources/js/pages/partnerships/editor.tsx": "96d23cbf2dcbfab7a3e9418d90ac5e452b78915c0192dd864cb9ac24dee34a4e",
"resources/js/pages/partnerships/installation.tsx": "960b261e050dc0c1d201034e6263f2f030354279f6f9606c5670d2a2205a1afa",
"resources/js/pages/partnerships/room.tsx": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a",
"resources/js/pages/partnerships/shared.tsx": "ca8f269dc09e109af1971cbad553dbf464f4d0924c0d94d3e9df5bcd273d7a5b",
"resources/js/pages/portal/document.tsx": "192a186c93b70a1868169529d48279d16893741dc009d782132714a27a5e0929",
"resources/js/pages/portal/legacy.tsx": "20fd5e4011eeab6d70a0fac33df27d977abe8280c146e01889d413b3a99b7cc0",
"resources/js/pages/portal/manage.tsx": "b80c986c353ec974c6dbbe8e569e3703ab9b2ad3edcebe9bcf583a19822d7ba8",
"resources/js/pages/portal/services.tsx": "3ee5037bdbacabc94c7de030a5467a73395c441659b8eb07be6226e9d1bc9e4b",
"resources/js/pages/portfolio/index.tsx": "fddc5d4dffa6ec417504e7692b903f5dc634549abb0e22fb7cf5e8d327bf95a2",
"resources/js/pages/portfolio/shared.tsx": "304685524a04c73dcf9fce7d380835b5328a274389bb2c3d4d28e8e186ee2e27",
"resources/js/pages/portfolio/show.tsx": "a99acb0c7724b2bb227e632593a5a18b2e3f0dddf4768355b308125f6d9ddfc7",
"resources/js/pages/portfolio/workspace.tsx": "30ef0fca809e1ec24ceb92a50890f9a04f36ef7e4c8fe45ef5353fcf6f4e68f2",
"resources/js/pages/profiles/administration.tsx": "b88b01ecea5fe923e53d6f96674f298e230f50050e7bd6975cc3de37af5415fa",
"resources/js/pages/profiles/audit.tsx": "1a045abd321c47073f9615862b031cf197035974dcfb5cc60fdd6a58c8a6ae82",
"resources/js/pages/profiles/bootstrap-confirmation.tsx": "58116e24582c429281f8bc42ee0623cb01c88d40d4713f4697f5320a3988f2cd",
"resources/js/pages/profiles/installation.tsx": "5f0fdc75208348f4a09cbf23035eb890a3d3208e8f48a4e00812e56033dfed2a",
"resources/js/pages/profiles/request.tsx": "f110c4741b4db7a7cffb8e52897b5509d612ce455967a956b300fa9e0532a406",
"resources/js/pages/settings/appearance.tsx": "915a7ca2faa1d7213c9cfbe1fb574d3b8674bd32a20bd11ed9d3e5cee18797ed",
"resources/js/pages/settings/profile.tsx": "9a200bfa9a9c41a7c4eb39f3b0942eca4e2ccc7b18e02aaf51a2a3538a2b8960",
"resources/js/pages/settings/security.tsx": "c6ef74994777872e705c33e38bc7a769121fa7e551059facd5ac05ac501b3ec2",
"resources/js/pages/structures/editor.tsx": "2c38f8c7b3e1de4dc6318eac93b0cef2129ed4c62e85c142542ac8cafd42ed49",
"resources/js/pages/structures/index.tsx": "36601966212f14a8b4bdfa3d697f8e940f1bd9af7a0cbdf9433cafa7a1e52eea",
"resources/js/pages/structures/types.ts": "27bf2382317174f09c2ebd69a2f0f03c6cca69156bec23abff6ed03c2ec5516a",
"resources/js/pages/structures/value-network.tsx": "71b0807e28cb1df992eb89169c00343f1b2e2e5249b886e4b82353ccef5ee635",
"resources/js/routes/index.ts": "9487b2aa764ee57d322872a87d316927a17f69fa38cbab94cf170548f5aea5bb",
"resources/js/routes/ai/index.ts": "41766837f98aa065376926a600076b425dcd36ad19f3a3c7071d30ff634026d1",
"resources/js/routes/appearance/index.ts": "ed2e750b5517df969731276b563a5f7acc83ee68692e95312aef854c86c4ecb1",
"resources/js/routes/business-marketplace/index.ts": "834cf2aa5e3931019bff0aa0b82b48d3e658abea51becf50d04930513ea53875",
"resources/js/routes/documents/index.ts": "61bf847ee705442223c982a70cb074d12902789a8e0ef2f6ec152038e1e37020",
"resources/js/routes/documents/malware/index.ts": "8c32c023aaa16daff6d9d77ae7dee1cccbfa2d06f542a33baf261f7b5ffe5c60",
"resources/js/routes/documents/manage/index.ts": "2b1360fb575aaf37db052644fccde7723756d28e03b705cb267e1af2f55c6520",
"resources/js/routes/investment/index.ts": "2748faff4ed7f16096ac1e2a20374bea8fe6f4d396e75044153eb8e011bd9e53",
"resources/js/routes/investor/index.ts": "fdb9cb18a9c39841264935db588c094252948870972be7f01dea4520b2adfaee",
"resources/js/routes/land-assistance/index.ts": "24d511783dbb8cee058aafc5c3585d960295a308b13c4dbc3a942d94a03a7625",
"resources/js/routes/land-assistance/manage/index.ts": "72082c2a8c154fa90c36dae46a51771d8d62a7b865bf75c479949cad25e0b170",
"resources/js/routes/login/index.ts": "f1da49e63e0e8f4fda4eb147c630594a6e486f13ed5f106d0e30b739c277d35b",
"resources/js/routes/management/index.ts": "136192bc59da74bc7891c39a80a39a3780d9b2c7b56e7d89115158497ed40004",
"resources/js/routes/management/clusters/index.ts": "a2df8305ef47b9e6508c9b0570df89465d097f735b6446818ba8d3fc179b3292",
"resources/js/routes/management/clusters/chain-links/index.ts": "e734767956f62a5d70b48fb4667eae67c2ab2f619864509d9c90287e06c4b1dc",
"resources/js/routes/management/clusters/chains/index.ts": "d0e459c6959308f3493c494c084ace0a46aa343eb3c406fb60cc88d322d3a89b",
"resources/js/routes/management/clusters/gaps/index.ts": "7de98d2f02440cb5fa401ed1d3e82277e1a44f23cd2c078788fc1438f77ed2a2",
"resources/js/routes/management/consent/index.ts": "e092a5eece2e23a93e0675210bb86a9ba362bebf64f0ac8fb8e34f01e7ffa63e",
"resources/js/routes/management/crm/index.ts": "1dbb226632ad11265a9b01e8e4a7ecc5299d5bd55839e927affdb34af4ffbc82",
"resources/js/routes/management/education/index.ts": "0b8112f2b37a8ccfd523a4bb53372f1f43b8c6b50f6e8d792f695e8f520709ea",
"resources/js/routes/management/opportunity-origin/index.ts": "dbd12d72ef65919310cecf3a6e31c5d7ad0841d226b2d8cf8f04398320edadcd",
"resources/js/routes/management/portfolio/index.ts": "7ff63fc7e2230392a40f84a920349ec0d9b61ee2e49ec1c1aef5e71c2087dfaa",
"resources/js/routes/management/relationship-repair/index.ts": "78188b6ccb529bbe3922d79072dc7f11ee2beac2aed866b26c009483a926eb2c",
"resources/js/routes/management/structure-relations/index.ts": "350aee87977ee9278632643127f46d6c92418e360f5aed3413e1ce41c15ba3c0",
"resources/js/routes/management/structures/index.ts": "8e26f5e6c7ff966e4ac707784218791c29f15a7a7c3bda59d576d20049180e69",
"resources/js/routes/passkey/index.ts": "31a42b47f4aaa9ee9a5a90a6b2d8ef71031df30928149c7410b877cab3637445",
"resources/js/routes/password/index.ts": "81840427bfe8c964248d096404233a6a955ff3165bb76c3afa9440cb40f67b39",
"resources/js/routes/password/confirm/index.ts": "1bcd48e3c6cac9f564c5fb3d7c458193b9a235f9002d1cc757a3d405acdcc457",
"resources/js/routes/portal/index.ts": "ccd1a5c70b979406164d8a04bb3e0374640cf53e90774798483e00a324dd7b64",
"resources/js/routes/portfolio/index.ts": "e7384d3dc3f5c52523ed4aaaa57a087413b2bc2002074883c4e57a945ed3f763",
"resources/js/routes/profile/index.ts": "3086b8e92735a84e84edb3d02a17a74bf6b04f89097fe58a763cb6a0405d42cf",
"resources/js/routes/promoter/index.ts": "a5605bb49382669d0f1b695a2dd625cd63db2bb165af8a24478539fcdfa13fb3",
"resources/js/routes/register/index.ts": "2aab3600464ec1cc6a88fa7bb7c2ffc0f75bd91a578df1d1cccbdf20e72be8c8",
"resources/js/routes/security/index.ts": "76085bcc9d2872de9ab18c5dda1615403734bc48095edd750450e34f599922be",
"resources/js/routes/services/index.ts": "32a3db106f15254116cd1bc765854734291a9fea28c83318b9a9760b2712a6d7",
"resources/js/routes/services/disclosure-authorization/index.ts": "79e686d281a9394feea21b63a67163e944c8c1af3721d5a539a716d13495481c",
"resources/js/routes/services/document/index.ts": "370855265ccae5c7959a84e56152e180be694cb7034da259b3f9b6666c3cd4b7",
"resources/js/routes/services/resource/index.ts": "3c348cd7ef61b919b2ac7f879465eca07abc72e1212e0d7d7e486392bb4ca011",
"resources/js/routes/services/simulator/index.ts": "b76b0e1181498722b756d4bf59be2f4781ed2c29101604432d03583f4051273e",
"resources/js/routes/storage/index.ts": "d5e90478d6dfc5480e59035b8ee3bbb7b9bf77b82a05516a2288abe6aa669fca",
"resources/js/routes/storage/local/index.ts": "5fb28b89c5851a32e52587443f221686f31bc08be9656f763e8cf11a940fb6a3",
"resources/js/routes/two-factor/index.ts": "c3aeb7f42b940f4732d9dd1674518014858cc333573162301b6f9ee92d97491a",
"resources/js/routes/two-factor/login/index.ts": "2cc6e2088876b1d960003f6fe563bbf8e995dc827a227bca9c70f118f5d8c2bc",
"resources/js/routes/user-password/index.ts": "9a45ba5c7daaedfbd0609906aaa51388fed3dfce74497fe3e5e315a6118bf272",
"resources/js/routes/verification/index.ts": "2f62bd2eca2dd4909d969c51066dfe7363a5882283cab6bfcb11a40fcf5b2236",
"resources/js/routes/well-known/index.ts": "99b75be2f38dacf9bf6967d35547f6d8c8b8c4024662a8b14ae98013ee6098e6",
"resources/js/types/auth.ts": "68aa8fd778c6de04e926827acf5441d600daa088e5dbbb45b5a783c9ddca68c0",
"resources/js/types/global.d.ts": "18312397eaab4634bec6c20782b82fb05df0941559247642f155450362b2895f",
"resources/js/types/index.ts": "fbf32df1cbb06868339accdfacaba99dc3a64ba7237bc0eeb514cf4a6a37155e",
"resources/js/types/navigation.ts": "73331b328a9882fc02009322b4a7b87ccb6d6614ae12602c031ffe35269360fb",
"resources/js/types/opportunity-management.ts": "2714ea554d8096403092b3a83e3c32180689c0513821cf13dea762c8e5c813e6",
"resources/js/types/profile-access.ts": "af3027d54332988ab5692de7fed6ea4f200ccc07e83224555f4d5048725be5d9",
"resources/js/types/ui.ts": "946e77884f2cf6cb152633033c88f21de4a7d49bc32dd186f45d86b5c200e47d",
"resources/js/types/vite-env.d.ts": "65996936fbb042915f7b74a200fcdde7e410f32a669b1ab9597cfaa4b0faddb5",
"resources/js/wayfinder/index.ts": "3efc1c9f2eaa4828a4169414a1239420fc1bea8d3752fbd7a95b4a6da4a60d11",
"resources/views/app.blade.php": "428e8682281ab44b3584b4b3299b71181b45cf172103985c1a159262cefb417f",
"resources/views/PortalInvestidor.jsx": "6525ce5827b6f45098d23bf834a5eb460b1b106d16f47ca987cdb248b2455af4",
"resources/views/errors/database-unavailable.blade.php": "4bd4a79de458ace42f322777c79949e825a0feaf62f3e03c77b611ab23672bd2",
"resources/views/profiles/creation-unavailable.blade.php": "db323dec6d8216191cea5fb9f5d051c827c38db902b4f51c8636afbd9b4226c7",
"public/build/fonts-manifest.json": "66edf17c93351fe01158be7414a441a762f106417c74351881876b405b8b10ca",
"public/build/manifest.json": "da4484c656cf682e0e352535a83fe8bfb0c586596a8a3bdc329bae35de0c9765",
"public/build/assets/administration-Bcn2OjiV.js": "9e2825b52ccd1f4c8e02309085ab0502303560f86434fbede1df39795c38687e",
"public/build/assets/ai-DXQFoK4t.js": "0b836f0f59eefecac95306a7894b14231d754a8027e7e6ef0b70f002478d6b74",
"public/build/assets/analysis-BnfuU1HZ.js": "94e40eecff255fed261094912bc434d7db0fd842e812863ef9c918d7597c5fe3",
"public/build/assets/app-6_PpKK41.js": "a8d8cc671112c46a7d826f98819d64341186e46356f14c9a8483b6063fbbd875",
"public/build/assets/app-CzR4oIqP.css": "cfcbc7b9d1bbb8d2098b86749bd88ea06c92d948da86b85c1ad86bafd95609d2",
"public/build/assets/appearance-7E0G5Rus.js": "8e2858bb37480fb59c179149e5cd6745bb85ae10fd7437a3e0e871ac1898101c",
"public/build/assets/audit-ZQHBSb0v.js": "9ee2fb0115a057bc82150ea3d2add3bcef3b93e03902b1afe77dab8c684c9a4e",
"public/build/assets/blank-2jFZEe2q.js": "9e53a0a455027f070e3041db1f445e8b63702f83e264442d8df87e20048ccbe9",
"public/build/assets/bootstrap-confirmation-CMivqdBm.js": "b1f7f9e616ea33585adf66223302526c7d81007ba63da670d5156b20b9816800",
"public/build/assets/business-BzdSi37Y.js": "cbd0f3e5d81a96d28faebb7d334d5e5eebaa2df09dd1b99d020218cdd0526d4f",
"public/build/assets/business-classification-Dfy8bqgu.js": "c21bab693965a3bced5d4e37cc567572d2b5e3cef9c7cd34cf7e3e92671c140c",
"public/build/assets/business-interest-DNXmIcdq.js": "815e4e54ee340e74f65df93d9810311d8c248dbb4828fd239711ed891ecad19d",
"public/build/assets/business-marketplace-cnZaPTSn.js": "24c48cba839561d8d9371c3246e3e69dd7a447f50ec679ba959609a855abc733",
"public/build/assets/business-objects-DxX1L3pK.js": "2258b0bc7a91ace5322b3565c83213c168dfe1343551a0db90753303a0057bb1",
"public/build/assets/business-opportunity-BKm-57Bt.js": "207b5c9163d77be7d31f37b424079229b9f1368d7acd7ad7170de1389a90e800",
"public/build/assets/business-types-SGCXhH6X.js": "c792ab88a79f57c74d865c47e89e7f2b9aea190acb5c8c676071d4b0a802d58c",
"public/build/assets/business-verifications-JEZ5aUBs.js": "9a0a01b4a1aadceeb984753fa796fc9329eb32be863f406d10d15e93926d500e",
"public/build/assets/business-wizard-BJOfU9zv.js": "c3c284a302106425726d9cc6bb6906f9e7af743c85a1a32b2908a42502803767",
"public/build/assets/businesses-B4JSIAQA.js": "2dd600f8fbc37cc3b2bfe32684f7d33c26b8a258968a4cbc52d22cf68dd1fe91",
"public/build/assets/button-DAU4R6e9.js": "79b615d0b88db74491fb4b312ae70515d43332e8730f8baed64c81eec510171d",
"public/build/assets/case-DYyzDynG.js": "4e1069fb67b1e31b60002096dbd1dba089133937b28a2e33468b8b19eb833be7",
"public/build/assets/case-jhW1p_fJ.js": "c153137a1a70624ffa79a821afdd67e4589ba17d7a63eca3cbe7bb1fdae087a0",
"public/build/assets/catalog-o2C_Ymql.js": "a5c7062cbc8ab1463de453cfefb13e0c4be6f2ace84b059629701fe6150e06e6",
"public/build/assets/catalogue-BwdS5Sio.js": "042e340eb788729316233a426b7be6def249378a71abfef08f85dfc9497d0631",
"public/build/assets/catalogue-CuDJU0Hx.js": "7429a4bb849a11dadedade6e05e7e5cd53f2a85a4952ebae99448de03eb733c9",
"public/build/assets/catalogue-D84LwZCw.js": "e70c1e6eaf8267c043ee50dfbb43e0d1b44d3e983c507028d0d1c16282c13ab8",
"public/build/assets/check-PcBNn_NG.js": "402150a0f6387f9f098fea689a3282723ee063c84e57651f25d35729cdd85063",
"public/build/assets/compiler-runtime-sKsOXjDo.js": "cc5f3db4bfb3bc5ae09b4594e5e137ad20037e8dfc3f0791781665706b860b6d",
"public/build/assets/confirm-Culw9Q-x.js": "263fd058f1562c5729a4091d5d60f5365cc3957ad2cfcb5ffdec04a28f1858c4",
"public/build/assets/confirm-password-B5yQIFPY.js": "c2044b9ecda8e9e7b9efd09127422500a5fff61ffeed3eb1e3c80497b0f9774f",
"public/build/assets/context-DSXOoxey.js": "a26a9cf9b458639e20356b5ef495ba17f0cce9de4cbdee3a55e70a2a8f352f5b",
"public/build/assets/conversation-B-qzvEJ-.js": "42f3d38b5b1bcc436fa8f0819a0aa8e810fccedc4903bab9dd6676fae5b5f6ad",
"public/build/assets/convert-CBHMMT-_.js": "92b5d459b47cf85fc35fa0777d68110d54ad701ca89185dc75031a38609e6aee",
"public/build/assets/country-select-C3BLoPPG.js": "87822f75957659509b95011d1489f6bed2ff824c215fce862a7fd29186f5189f",
"public/build/assets/createLucideIcon-oMeAlXbs.js": "9398e5f9d8be91b886b9f6283574d6eb89b8fa02a4c21866ab9e376c95b74b56",
"public/build/assets/dashboard-AVo8bipS.js": "7069e48b34716ed8d4ca9a014832ee13de7ff08bae45d70e3718b89431b34a24",
"public/build/assets/dashboard-DIQmU8H8.js": "649d9f9353e9724c51bd34c6e971104be712d8bcfa70011b928e04c768effc6b",
"public/build/assets/desk-internal-operations-DbpRBX-b.js": "9b63214daeb62d98530c436aa374645a2735d4bddbf0c29d343778c6b603f1cf",
"public/build/assets/detail-D0uXt5Oi.js": "b0ab3eda9b135400018c125f9f9e0202fc56c3a8e401a2fbe863ca2cbf1b12f1",
"public/build/assets/detail-DG2GUSUR.js": "2912e8242a36a5ec154122f8d55b9488c1537a870b9b31133f2324247f4cb2f4",
"public/build/assets/dialog-CLXxq8NW.js": "2cfab1620801a4f18cae321ebbaf5b250becd5f2fb9952647afb2a5e5c50eb5a",
"public/build/assets/display-value-DRR1EAAK.js": "202c77561454ec7c1ef9cb39faa4f1833ea066dbb83e17f0eb4440b314b189f6",
"public/build/assets/dist-BRfsww6z.js": "1b5218b53553fd01fd50cb0ce2102864c5359d450d4d71f00806f812f1e1870a",
"public/build/assets/dist-Ddn_hEUd.js": "ee0c56af5abd78d01704f2fb0f764ea0746908244078a8014393a672994235d6",
"public/build/assets/dist-DDq_DSJX.js": "0ea9c4863c02cabf343ba678aa470b682ef3ae1588380bee5b0781d356e9ba46",
"public/build/assets/document-XT0MGfs7.js": "71ccbf1925af4fa8bcc7cb97d8692ab24dc66717086323ccd1448417f8d96e65",
"public/build/assets/editor-BAV6dJB3.js": "16eb6c8d5e7a2b630183c68f5e6b97ebb36dfbd1ef9cb8b3653cc6083851c3f3",
"public/build/assets/editor-DAOe4gXh.js": "7809481b7b00e09a598cf473f8b0a78e60f2cceed6ba7c51ac0e1108ce43fffc",
"public/build/assets/editor-hNkBGzmt.js": "930df3bb2580e69d280695a38ed1c358e0027c22c2d7b6dfa6d7e39f428e8620",
"public/build/assets/education-VTpbFtyL.js": "78810dc15cefd8ef2ffc4c10bf937f1867bbbbb2cd62b641f24ad03156a28511",
"public/build/assets/financial-calculators-CsDOUJxx.js": "e76679a1914b5c4dc6c3e74b1b2de8d3d792fcc891dcc61d0fa27042232e2b9a",
"public/build/assets/fonts-C9MNnjVw.css": "3846a9bb60bfad92960eadcccaf0b4e129d74b11d48791506c8d1a827a385cc8",
"public/build/assets/forgot-password-CT_upu0h.js": "757d60c987a274293f722ab4aeb69229d060966c78e89305190127d2e9a275af",
"public/build/assets/form-PQGb3VLz.js": "ad89ed30cc958d757812bc476a90cf1f19927cba442a7027f7d7076ae1e1f201",
"public/build/assets/guide-mndEuKFT.js": "fe519ab69363e83bb705b7dee5ab3fe17249eeb53687846b539668c435ccbd2b",
"public/build/assets/history-10kyFes5.js": "fd8f300a4b66c077b31677f37eaf68eab7ea612f37984dd34a6246d8a3653ce9",
"public/build/assets/input-error-U1QKS0ED.js": "4acac92fa624552b14ac1a390e961f9e387d6eefeac384ad4e95bc73fdffa86e",
"public/build/assets/install-BrfGNJBn.js": "50964a18cd05719450d3a27fa75fbbe4efc83de25835990ec0c21f1789b7b1f3",
"public/build/assets/installation-CvUhYACr.js": "74a3c2fa204de2b91cb918d7fa422700bc72ac7b7f7b602de3df3c7655660cb2",
"public/build/assets/installation-DlTDPi6D.js": "8cca98bdbc869679d26aedec46077441fece37853afc4d69241afa8032341fb5",
"public/build/assets/instrument-sans-400-normal-D1W7dsQl.woff": "797bd3eaa70edbd4757650ab44dad75fbfbfdf18bacedb4b71022c04621d30ad",
"public/build/assets/instrument-sans-400-normal-DRC__1Mx.woff2": "9a91efaa3599a6ef01b2f49e9ec670e3a2f39baeef09c73198f1052cf3bb0850",
"public/build/assets/instrument-sans-500-normal-Dk9ku72i.woff2": "9d3547da16d950d12a677c772a3ff9b69846e60e7dcd1b5efd540993f7286532",
"public/build/assets/instrument-sans-500-normal-Z6ESRlEs.woff": "bd6a8dc8b0dc0cced0c32d3eda93f0e0e82c58ddefea8b53b3307b0c48da3089",
"public/build/assets/instrument-sans-600-normal-B7fBEWYG.woff2": "efb770916eda95a0e31d80cccde9651d4e8617010b21220e9f227c4820d675da",
"public/build/assets/instrument-sans-600-normal-B9e8oLYv.woff": "9b4ce1f2b26be7cb087fd87d6f99a202136292ec820af75bd38ab9e53895cf28",
"public/build/assets/interactive-investment-map-1DTFk8zz.css": "13748a8189dc8c690fc902a1682d30ba289721688f32df4f2459a36de8e383de",
"public/build/assets/interactive-investment-map-C0ZHBrJn.js": "60b2ce5a797e3ec900a90bac70f7f5569a43a1775e4bfa50b1da788adfdab2ab",
"public/build/assets/interest-CFJUViWC.js": "acb185ffd27c45ed2faa18ead7b083955b2f02a3659db0aec580a3def3f9496c",
"public/build/assets/interests-BRydqMIm.js": "ae0b414479188672f23235ac62eea7f91ec391c35b03508d42de4400e7842679",
"public/build/assets/investment-map-panel-CNDkOuLJ.js": "67e7fb2e5528bf51c18e28216571bbfda94dc068de4f44a4c5d669f938a2068b",
"public/build/assets/investment-maturity-CydhhEfV.js": "c2cc75070cb664ab0b53466dde584dd5473f1b5fd992bf6a59ca8a01b7e19623",
"public/build/assets/investment-territory-CL6F28ro.js": "b3ed1fa8859382f3d76dae7e4627cdf955da41ebc86ad47f3a998cf8eb25c914",
"public/build/assets/investor-OuCalesR.js": "d3fd99e5c33327e436366c0053679bf2492b164e75dd8251590b6dd2af61bc64",
"public/build/assets/investor-path-CVprKFtb.js": "fbefb5e489bd76f477e7e678dc98b1dc4c4c728b857890c67dbc7622e8ef47dc",
"public/build/assets/investors-Dse-ngTc.js": "4bbaa20a476c0f65aa4133cb76005b7398df9efb9139e99cfc90c340ce1e670d",
"public/build/assets/jsx-runtime-BpzPEenQ.js": "60a64ced602d5e913f2a0328d2ec4a7b670c893614a26c47794317523d276398",
"public/build/assets/label-D-C_NQs4.js": "6b4996b6f05276fd6edc8dd935f37f83a6c673cad5cf2f9dfa7cf4bdc92816ef",
"public/build/assets/labels-DxqjesIG.js": "deace12e77e3f2e0515b1090cbc376cfeff29b59f57b1a2561b1145459c531b8",
"public/build/assets/layers-2x-Bpkbi35X.png": "066daca850d8ffbef007af00b06eac0015728dee279c51f3cb6c716df7c42edf",
"public/build/assets/layers-BWBAp2CZ.png": "1dbbe9d028e292f36fcba8f8b3a28d5e8932754fc2215b9ac69e4cdecf5107c6",
"public/build/assets/lead-DV-JDFzR.js": "49f1cd6a28c74886dc2a59e918aeeee61051dce00495e043504b74dc6f4ad847",
"public/build/assets/leads-DvDYN3j4.js": "c0d06cbc3b4df40c9d6c45f4e85c014874ea339b4647afc8239f77c9143d9084",
"public/build/assets/leaflet-src-CUWrUTR2.js": "a26eda55b9706e8778766e4d32038202d20411081d7da16faaa39b977af36245",
"public/build/assets/legacy-CuMKZxXa.js": "d481dc9c2a66fa4933f32e75c405ea44b5c229ffc9cc9757b6807c9c5af8a432",
"public/build/assets/loader-circle-DS8Tf4er.js": "cd9fb22e9d7d12342d5e0941aac953ebb5184550cc8008b5c0f8f5ea6acd8ed2",
"public/build/assets/login-BJ77wQtd.js": "79b9f8e9826522698a1f1c3928a2ceafae580dbd7162fa05fdb08da74e7b9000",
"public/build/assets/manage-D_2jf7R7.js": "4417d745677e2160dbe618b368f56725530a43b677433f393b18b70913321bfe",
"public/build/assets/management-access-Dl70YCx1.js": "1d50024d467e7f6fa4be11cca48534b0b697520cf894282b33ba33cc95db026d",
"public/build/assets/management-CvdeRZYq.js": "0c193b26e40abae535aa6b51d1734bd930e4d2570dd0033cf0b41efc47aa16cd",
"public/build/assets/marker-icon-hN30_KVU.png": "574c3a5cca85f4114085b6841596d62f00d7c892c7b03f28cbfa301deb1dc437",
"public/build/assets/notifications-CfKXP-gQ.js": "184b1b8c1d94ea4fd72ba4571d1bc8ca9c134276675bdadfb3ece80eed6a76cd",
"public/build/assets/operation-key-Dr4VtGxa.js": "416fed7a5197657971af7f378998557c9dba2f99e266e39149b727e598bea439",
"public/build/assets/opportunities-DhYIpI_a.js": "4397ee8d18f8a25c56f15b30aa3334885c280460d1b90f87e2e430cbd69665ad",
"public/build/assets/opportunity-classification-BhbOc2qd.js": "d7cb2611e5adbd3f7e9c33308505cfbb8074fe6963083d2f217f9b506afa5a41",
"public/build/assets/opportunity-draft-Qq4WjHNE.js": "3342cd46dadf7a5e72f26d16fc90f6e47aa325597b951f0fb6d8bb66131a9f91",
"public/build/assets/opportunity-install-BkUiTdjX.js": "2f1fdc5e72658a3da21fdb045cb3f8c724f33a8cbaed6266097d27e21dbc3438",
"public/build/assets/opportunity-origin-CROaCFNb.js": "0770ab1d17374bc7d57ea9329ed06099902a538be002fd9577301109a59753eb",
"public/build/assets/opportunity-resources-dzjWnPkV.js": "5161fb009c7cf0325ef8a209ddf730686560d9ca6c6ffa4473ac5957c346a4a7",
"public/build/assets/panel-Bbs0Mqhk.js": "f85d444c6034d1dd6623e9aaa6a21de393b2073beb8e1930ff201793708ca1fe",
"public/build/assets/partnership-source-links-VfrXk2FZ.js": "a4d6c8500f2417983312ae667b96f035df9654f37aa4a7bc86f0cc01fda0ddd8",
"public/build/assets/passkey-verify-BqSOC8Kk.js": "f93fa9176596b20f45fa76fc797c115751f267bafb964513bb9f14a768a9f10b",
"public/build/assets/password-CB_NxgQN.js": "4415e495723009fc084111bafd2b7714221a3712e5f1d2a4dfa0e698f6308c7a",
"public/build/assets/password-input-BCP3MGQy.js": "9512d893b50fe6e67ea4067b9b646067874521b8cc7f4e14f1f5c98b6ddc0374",
"public/build/assets/portal-api-tEuwFTsU.js": "190505d0a96d610ef2893cf06c63edab30f427593452bbc0dafc9d8f8a826c70",
"public/build/assets/PortalInvestidor-B9vctDlB.js": "f359ddfd7ef20310e3512313aaabeeb36f00735fa66bad719f1b9bbfa0404c0a",
"public/build/assets/portfolio-JLEB8oeF.js": "6305ee305db22a815a5f1dae5a824e57f01395ea6606ecfe17dd8d26f8c55dbf",
"public/build/assets/print-EIzSB6Ku.js": "bad87486159deb855589aa92fc7032ea28de222693c2816f2ff54b1583ef6513",
"public/build/assets/profile-DyDK5SQZ.js": "dacbf433a97f03d1e7cb5b4b2ccc82b9aed5be5b8ca609c68bc3222b6d55b2a6",
"public/build/assets/profile-json-BC1mQPe5.js": "269ee0efeb8b9b9e175e6e23e553b5b11b0dd8bdffdde3a99b76427c900dfa2a",
"public/build/assets/profile-Xu2_PZpQ.js": "453d1d9e4bc77160f1819dd6af7268931eac93efb27eda122b4972e94c7f1a42",
"public/build/assets/project-dossier-BRpAqBvm.js": "9906a87fcb5b99bea2eca25e68dc49c149c7b250056a8ac0977d2c8b6cf4e732",
"public/build/assets/react-CjVep8xp.js": "3378f8538b0d8c51e3051e5005dfaebb8fec48c35789a3ba63945fd724f48e6f",
"public/build/assets/references-DLP4i6ee.js": "56fbbec7241ae91dc5bb77deba64bda39017f4e7536739b4424d5d51ec488777",
"public/build/assets/register-lM1W7SJK.js": "c34e17c7edccb044732561c0173ceb6dd4b025136cb50e0d79bd033f8233d20c",
"public/build/assets/relationship-repair-Bq-0rZR_.js": "01bce19211d066cc06483b7485a8551667f736d0377f9595824d94c7759cc062",
"public/build/assets/request-CAPf2Q-_.js": "707b35fcf18bff1edeacf2c8d5ce221288bb7a45a1f90fcb09153260ac51bd50",
"public/build/assets/request-CbvlZOwx.js": "cc283a4d9390eb8c5b7d38dfa075e19b2f416d7f3688bfbbfef175988a3cf09d",
"public/build/assets/reset-password-C73fnz28.js": "d3e4eb29df325a1bf8dd693a9143c05c932c2d2753a87d4f467af249990cb05e",
"public/build/assets/result-Il66oWSo.js": "715e1e78abdf8e82dc4d9350356dbdb9971114a6ab9a5a6c53c87870271bc307",
"public/build/assets/rolldown-runtime-Dd_uD5pT.js": "c5f0356f5d0918a3137e4e811fd18950efe8ac8f6bf84d1d4da7811c477a24d8",
"public/build/assets/room-DZfrOPHR.js": "995eb6939cc23db927484f0353c9b9a9efbf61e70360289d2209d2fa8152449b",
"public/build/assets/security-BbIFXiUt.js": "97b3c4bf9e820784ecf51dd4acd05a26ea1393d01b51795fcaf894efe9d149e1",
"public/build/assets/services-BnBszum1.js": "a00dca8b16c0d0273846928beb548fa9400e29ea50e424ca38bb9760470f254d",
"public/build/assets/shared-B41J9wez.js": "37b02b63ac11efb0d08c6baa52bba95802e6218eb86b7089f2cf85c9c08e7a59",
"public/build/assets/shared-CAtAThHy.js": "18cc69a596a3d72f8d0f144aa1acc4a6d15e399fa5477cbcbd48ad20233bb542",
"public/build/assets/shared-CHRaKAJx.js": "ddb63a83bebf63be5db007002eec2274e75faef259661c48ad0b506fe801875a",
"public/build/assets/shared-ttxv1gnp.js": "a3b28f764e57da28561085afd9f40d6630a81d2322c57fdb3c5bb687fd11adfa",
"public/build/assets/show-DNldzVzm.js": "17cf216f36e1935f0e07cc63d5dc15cd6c8c9e4571ec1737de3e2ed1fce1bfbf",
"public/build/assets/show-D_4ELzmn.js": "1530d45461ca60d47d416fa886d7b0f031a23e1967b9519e415234f0ded405a6",
"public/build/assets/sources-BLEETi_f.js": "9b0948d98bd042b24dcb81279e9e4feecca5227d9ca2e222f196ea399414897b",
"public/build/assets/spinner-hD8hHC_m.js": "0091bbe0e4125cbe30ecd10ec9ff65cff9b7bd270125913d85b4449144aa91fd",
"public/build/assets/structure-geography-CB5-BL4P.js": "d40d3c50d23e145069da0f88f7a72901a97d512735523f210c8ae8973148a660",
"public/build/assets/structures-DdSNeJpe.js": "0b1afff7405014b7585101250b12b205f1ffc1de09c3c395bdbb8fdad105bbdc",
"public/build/assets/submission-jGvQY2Dp.js": "831305fb9f86fd830f0a79154a001ceaae3581c846f9dc877ace6aeb0e4bd6b2",
"public/build/assets/territorial-source-evidence-eKB4ZB36.js": "14048631c51933a0389cea37ae1909a02ea86d564a5a05452a48b40f055cd605",
"public/build/assets/territory-associations-goT3-Ga-.js": "151ddc060b621c406b2a521ab34ec55e306565c5e57c44784890b51547cd1a22",
"public/build/assets/territory-geometry-import-BBu3u9T5.js": "53bed9987dc7a614e3a0fc727ce56b33766bc0c04f547c8a86467a922ec87ec9",
"public/build/assets/territory-geometry-preview-CSxkk5K5.js": "7c1b56880e09b27992e33b6a0625f8e7115e595873af54946267f31d11b8a37a",
"public/build/assets/text-link-BBvcP60s.js": "0e7b5234d766855dbcbd5a78fe3e8c54fa6ffa1ad6163009d7b312eafd19f307",
"public/build/assets/two-factor-challenge-Dce2gUxk.js": "5456b088cb8af4a685afbde1b58a80e2779aeca0edbe3c39478578a7449a098f",
"public/build/assets/types-BoD_IJFv.js": "75c4a127c1aa0b90fe0b4f956c7e3ae9c67bc0f862c89cd0a594709027b983da",
"public/build/assets/types-Cxp_Nskt.js": "cf4ae8cb539c697ca751dcf96e1db3af9eb1ff00807c088268dd859e7c4a5dab",
"public/build/assets/use-two-factor-auth-kpel6Zcb.js": "771c519273e76ec8a5bea59c35605f01e5a55b353443c742c8f22d7bd9691504",
"public/build/assets/utils-CCDJ05Ll.js": "ef54f43266d404b8ffe4e5487b346060eaf81d819317f523c966aa3e7490deb8",
"public/build/assets/value-network-CaW-CTbz.js": "36bb42c256ad1fdab1b5359ff14ba838f304ca7731fc416fd8386ec40f52cc0f",
"public/build/assets/value-text-BztaYdGl.js": "873576810a6ba4eb8c9c116f53cdc649b21ab2995aa2adadd4c85130b04bacd2",
"public/build/assets/verification-BOcn3HIw.js": "10addac3d8f1865e855943e0685e88a268ffd8013ff7a7d51fb89d755b12074e",
"public/build/assets/verify-email-DUzqFjTh.js": "8372503e65fa4bfb1bacda3aaaf4a0bb051d6c89cafdc1dc312501ec89c75156",
"public/build/assets/wayfinder-Dp7PqxvV.js": "3d4c90228fda731e37f541f3087fdf5387d9d59433e35b267b64a97196f70781",
"public/build/assets/welcome-CgRa9kdA.js": "b092af071ef612cf8048b73c79683b055f93704c20d5c76a19e2c83b3b92c8b3",
"public/build/assets/workspace-4_R1CLYI.js": "5d4c742569d9ad33ac7bac01c6433c646f79f939d2f57b7878860c0d25dcee22",
"public/build/assets/workspace-C-YcZShF.js": "5b27b6be314de343fad90caa4f861eb51615eb68eda07b0e00fc2d20fee7a33e",
"public/build/assets/workspace-CCcwuevp.js": "0f86b1151abd1f63ff8bb21cbabeee99aee6e0974af8f4c28fec08808529619d",
"public/build/assets/zone-attachments-7y6jZP5h.js": "0b71ccb6133233a834ad0778be24b7a290ad383090327c56627b4b1d5dfd8359",
"public/build/assets/zone-DMnJ6wvO.js": "326815cf0e47e7894cdf0237e514a1c5bb52e1d3a67f6cb349ce0af03d16c17a",
"public/build/assets/zone-map-CuEGb2Cc.js": "e88e5d70ffd2e8941b7d7512f464436dbd7b8cb6b9082428c5baf8a772b8d176",
"public/build/assets/zone-relations-BBS8eeIE.js": "ec0d21b722f1cde6923f4c74ee2be429b92f11bf6b0890e3a4683003e251a71b",
"public/build/assets/zones-BgoRGKoo.js": "a06dff8650aa34de832daed9bb5263b83a69cc6daf481b9d3d660db3695883b0"
},
"protected": {
".env": "ea2fa5a0d707245a89d51533f5e0daa6ff85b1a7b011f4bb998899f0975c8955",
"composer.lock": "af90565c70188372ea1744c65bceb1d71c0400c6a028cda610fea0730b81b296",
"package-lock.json": "88f5ce8bb55056331476d0eaf8a2278fff4a8b98c0e5e1663765e2b2eb725490"
}
}
@@ -0,0 +1,10 @@
{
"date": "2026-10-16",
"origin": "Current explicit user instruction: O passo seguinte é executar o lote mínimo em QA; Avança em QA",
"authorized": true,
"active_authorized": false,
"scope": "Five CAE nodes A/01/011/0112/01120, editorial CLU-01 chain, technical uniqueness, both consumers, authenticated preparation path, compatible reversal, candidate/proofs/one future proposal",
"documentary_divergence_600_579": "open; non-blocking for the five-node slice",
"accepted_tests": "do not repeat",
"prior_plan": "outputs/investmoz-referencias-economicas-mapa-20261016/DOC01"
}
@@ -0,0 +1,164 @@
{
"levels": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"value": "A",
"code": "A",
"name": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA",
"locale": "pt-MZ",
"parent_id": null,
"sector_id": null,
"version_no": 1,
"level": 1,
"path": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA"
}
],
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"divergence": "600/579 documentalmente aberta"
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"value": "01",
"code": "01",
"name": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS",
"locale": "pt-MZ",
"parent_id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"sector_id": 1,
"version_no": 1,
"level": 2,
"path": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA"
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS"
}
],
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"divergence": "600/579 documentalmente aberta"
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"value": "011",
"code": "011",
"name": "CULTURAS TEMPORÁRIAS",
"label": "CULTURAS TEMPORÁRIAS",
"locale": "pt-MZ",
"parent_id": "af45b335-61a5-53da-a029-a8fab91cf624",
"sector_id": 1,
"version_no": 1,
"level": 3,
"path": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA"
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS"
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"code": "011",
"label": "CULTURAS TEMPORÁRIAS"
}
],
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"divergence": "600/579 documentalmente aberta"
},
{
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"value": "0112",
"code": "0112",
"name": "CULTURA DE ARROZ",
"label": "CULTURA DE ARROZ",
"locale": "pt-MZ",
"parent_id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"sector_id": 1,
"version_no": 1,
"level": 4,
"path": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA"
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS"
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"code": "011",
"label": "CULTURAS TEMPORÁRIAS"
},
{
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"code": "0112",
"label": "CULTURA DE ARROZ"
}
],
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"divergence": "600/579 documentalmente aberta"
},
{
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"value": "01120",
"code": "01120",
"name": "CULTURA DE ARROZ",
"label": "CULTURA DE ARROZ",
"locale": "pt-MZ",
"parent_id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"sector_id": 1,
"version_no": 1,
"level": 5,
"path": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA"
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"label": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS"
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"code": "011",
"label": "CULTURAS TEMPORÁRIAS"
},
{
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"code": "0112",
"label": "CULTURA DE ARROZ"
},
{
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"code": "01120",
"label": "CULTURA DE ARROZ"
}
],
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"divergence": "600/579 documentalmente aberta"
}
]
}
@@ -0,0 +1,24 @@
{
"files": [
"app/Services/EconomicReferenceCatalog.php",
"app/Services/EconomicReferenceInstallation.php",
"app/Http/Controllers/EconomicReferenceController.php",
"app/Services/OpportunityCanonicalContract.php",
"app/Services/OpportunityClassification.php",
"app/Services/ExistingBusinessClassification.php",
"app/Http/Controllers/Api/V1/ReferenceCatalogController.php",
"resources/js/components/opportunity-canonical-fields.tsx",
"resources/js/components/opportunity-classification.tsx",
"resources/js/pages/management/economic-references.tsx",
"routes/web.php",
"database/migrations/2026_10_16_120000_extend_economic_reference_hierarchy.php",
"database/data/economic-references-lot-01.json"
],
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3",
"manifest_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"publication": "published"
}
@@ -0,0 +1,888 @@
[
{
"id": 13,
"title": "QA dashboard opportunity b43c5640 edited",
"status": "draft",
"owner": null,
"category": null,
"context_keys": []
},
{
"id": 14,
"title": "QA contrato imobiliário incompleto",
"status": "draft",
"owner": null,
"category": "real_estate",
"context_keys": []
},
{
"id": 15,
"title": "Synthetic QA edited by authorized organization colleague",
"status": "draft",
"owner": 21,
"category": "investment_project",
"context_keys": [
"contributors",
"policy_version",
"request_archive"
]
},
{
"id": 16,
"title": "Oportunidade sintética QA investment_project",
"status": "draft",
"owner": 21,
"category": "investment_project",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 17,
"title": "Oportunidade sintética QA investment_project",
"status": "submitted",
"owner": 21,
"category": "investment_project",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 18,
"title": "Oportunidade sintética QA investment_project",
"status": "suspended",
"owner": 21,
"category": "investment_project",
"context_keys": [
"sla",
"events",
"assignment",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 19,
"title": "Oportunidade sintética QA real_estate",
"status": "suspended",
"owner": 21,
"category": "real_estate",
"context_keys": [
"sla",
"appeal",
"events",
"rejection",
"assignment",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"appeal_task_id",
"policy_version",
"review_task_id",
"content_revision",
"decision_history",
"publication_task_id"
]
},
{
"id": 20,
"title": "Oportunidade sintética QA land_rights",
"status": "approved",
"owner": 21,
"category": "land_rights",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"publication_task_id"
]
},
{
"id": 21,
"title": "Oportunidade sintética QA business_sale",
"status": "submitted",
"owner": 21,
"category": "business_sale",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 22,
"title": "Oportunidade sintética QA business_partnership",
"status": "submitted",
"owner": 21,
"category": "business_partnership",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 23,
"title": "Oportunidade sintética QA franchise",
"status": "submitted",
"owner": 21,
"category": "franchise",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 24,
"title": "Oportunidade sintética QA concession",
"status": "draft",
"owner": 21,
"category": "concession",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 25,
"title": "Oportunidade sintética QA financing",
"status": "draft",
"owner": 21,
"category": "financing",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 26,
"title": "Oportunidade sintética QA supply",
"status": "draft",
"owner": 21,
"category": "supply",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 27,
"title": "Oportunidade sintética QA other",
"status": "draft",
"owner": 21,
"category": "other",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 28,
"title": "Oportunidade sintética QA investment_project",
"status": "suspended",
"owner": 21,
"category": "investment_project",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 29,
"title": "Oportunidade sintética QA real_estate",
"status": "rejected",
"owner": 21,
"category": "real_estate",
"context_keys": [
"sla",
"events",
"rejection",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 30,
"title": "Oportunidade sintética QA investment_project",
"status": "published",
"owner": 21,
"category": "investment_project",
"context_keys": [
"sla",
"events",
"reviews",
"opinions",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"request_archive",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 31,
"title": "Oportunidade sintética QA real_estate — revisão editorial QA",
"status": "published",
"owner": 21,
"category": "real_estate",
"context_keys": [
"sla",
"events",
"reviews",
"assignment",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"force_review",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"review_baseline",
"content_revision",
"decision_history",
"publication_history",
"publication_task_id",
"review_task_binding_history"
]
},
{
"id": 32,
"title": "Oportunidade sintética QA land_rights",
"status": "published",
"owner": 21,
"category": "land_rights",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"request_archive",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 33,
"title": "Oportunidade sintética QA business_sale",
"status": "published",
"owner": 21,
"category": "business_sale",
"context_keys": [
"sla",
"events",
"reviews",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"content_revision",
"decision_history",
"publication_history",
"publication_task_id"
]
},
{
"id": 34,
"title": "Oportunidade sintética QA business_partnership",
"status": "published",
"owner": 21,
"category": "business_partnership",
"context_keys": [
"sla",
"appeal",
"events",
"reviews",
"rejection",
"assignment",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"force_review",
"review_cycle",
"last_decision",
"working_state",
"appeal_task_id",
"policy_version",
"review_task_id",
"canonical_items",
"review_baseline",
"content_revision",
"decision_history",
"publication_history",
"publication_task_id"
]
},
{
"id": 35,
"title": "Oportunidade sintética QA franchise",
"status": "published",
"owner": 21,
"category": "franchise",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"conditions",
"submission",
"materiality",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"content_revision",
"decision_history",
"publication_history",
"publication_task_id"
]
},
{
"id": 36,
"title": "Oportunidade sintética QA concession",
"status": "draft",
"owner": 21,
"category": "concession",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 37,
"title": "Oportunidade sintética QA financing",
"status": "draft",
"owner": 21,
"category": "financing",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 38,
"title": "Oportunidade sintética QA supply",
"status": "draft",
"owner": 21,
"category": "supply",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 39,
"title": "Oportunidade sintética QA other",
"status": "draft",
"owner": 21,
"category": "other",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 40,
"title": "Synthetic QA response semantics 40",
"status": "submitted",
"owner": 21,
"category": "land_rights",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 41,
"title": "Synthetic QA response semantics 41",
"status": "submitted",
"owner": 21,
"category": "business_sale",
"context_keys": [
"sla",
"events",
"submission",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision"
]
},
{
"id": 42,
"title": "Synthetic QA modular 42",
"status": "published",
"owner": 21,
"category": "concession",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 43,
"title": "Synthetic QA modular 43",
"status": "published",
"owner": 21,
"category": "concession",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 44,
"title": "Synthetic QA modular 44",
"status": "published",
"owner": 21,
"category": "financing",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 45,
"title": "Synthetic QA modular 45",
"status": "published",
"owner": 21,
"category": "financing",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 46,
"title": "Synthetic QA modular 46",
"status": "published",
"owner": 21,
"category": "supply",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 47,
"title": "Synthetic QA modular 47",
"status": "published",
"owner": 21,
"category": "supply",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 48,
"title": "Synthetic QA modular 48",
"status": "published",
"owner": 21,
"category": "other",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"decision_history",
"correction_cycles",
"correction_task_id",
"publication_history",
"publication_task_id"
]
},
{
"id": 49,
"title": "Synthetic QA modular 49",
"status": "published",
"owner": 21,
"category": "business_sale",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 50,
"title": "QA dashboard Promotor — 2026-10-10T16-51-04-508Z",
"status": "archived",
"owner": 21,
"category": "investment_project",
"context_keys": [
"events",
"contributors",
"last_decision",
"working_state",
"policy_version",
"request_archive",
"content_revision"
]
},
{
"id": 51,
"title": "QA integração territorial — 2026-10-10T17-36-23-948Z",
"status": "draft",
"owner": 21,
"category": "investment_project",
"context_keys": [
"contributors",
"policy_version",
"content_revision"
]
},
{
"id": 52,
"title": "QA visual workflow — revisão independente",
"status": "published",
"owner": 21,
"category": "investment_project",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"publication",
"contributors",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 54,
"title": "Arrendamento — SIMULAÇÃO QA 11\/10\/2026, sem efeito jurídico",
"status": "published",
"owner": 21,
"category": "real_estate",
"context_keys": [
"sla",
"events",
"reviews",
"approval",
"assignment",
"submission",
"materiality",
"publication",
"contributors",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"content_revision",
"correction_items",
"correction_cycles",
"correction_task_id",
"publication_task_id"
]
},
{
"id": 55,
"title": "SIMULAÇÃO QA — variante em preparação, não incluída na submissão",
"status": "draft",
"owner": 21,
"category": "real_estate",
"context_keys": [
"contributors",
"policy_version",
"canonical_items",
"content_revision"
]
},
{
"id": 56,
"title": "Franquia sintética QA 56 — variante de encargos",
"status": "published",
"owner": 21,
"category": "franchise",
"context_keys": [
"sla",
"events",
"reviews",
"assignment",
"submission",
"materiality",
"publication",
"contributors",
"force_review",
"review_cycle",
"last_decision",
"working_state",
"policy_version",
"review_task_id",
"canonical_items",
"review_baseline",
"content_revision",
"decision_history",
"publication_history",
"publication_task_id"
]
}
]
@@ -0,0 +1,31 @@
{
"id": 16,
"source_image_opportunity": 56,
"copies": [
{
"document": "7c5f3c04-0ae5-47b1-8731-dbffe67168e8",
"name": "qa-consumer-original-20261012.png",
"hash": "b4d659f6c363d8820b3e6b9532371b5807ef824fd7d83100525fe6c41388be62"
},
{
"document": "666066da-bd0b-4f61-8752-9bb876826f04",
"name": "image-320.webp",
"hash": "a90efe7609b3c58fa98bd397e55a9a8a8f3d17aa44ca56a330d63ef33ca61f24"
},
{
"document": "4b618992-64d0-49ed-aaa6-bfef4ce19464",
"name": "image-640.webp",
"hash": "0124df4318f20f1ea6bfb11c1e2509b9ac826ba6f6ce8cc06657dc0aab23827b"
},
{
"document": "aa492906-ffd6-4acb-93c0-a04c2c9b5a9d",
"name": "image-1280.webp",
"hash": "0e37a0afa0a29010ae2985a6a2d10d1aef0b3bec1bc9a3de7fe96d99082fb321"
}
],
"new_document_uploads": 0,
"new_resource_links": 1,
"scope": "Only isolated clone fixture: supply missing milestone metadata and reuse existing synthetic image for public projection; no claims about previous workflow or historical legacy content.",
"approval_fixture": false,
"active_changes": 0
}
@@ -0,0 +1,405 @@
[
{
"id": 15,
"status": "draft",
"owner": 21,
"category": "investment_project",
"canonical_keys": [],
"version": null,
"canonical_sector": null,
"subsector": null,
"activity": null,
"documents": []
},
{
"id": 16,
"status": "draft",
"owner": 21,
"category": "investment_project",
"canonical_keys": [
"risks",
"assets",
"markets",
"currency",
"licenses",
"products",
"documents",
"evidences",
"locations",
"sector_id",
"employment",
"milestones",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"funding_sought",
"maturity_stage",
"official_title",
"demand_statement",
"geographic_scope",
"opportunity_type",
"total_investment",
"executive_summary",
"impact_indicators",
"investor_profiles",
"secured_financing",
"truth_declaration",
"internal_contact_id",
"economic_activity_id",
"environmental_social",
"investment_breakdown",
"opportunity_category",
"competitive_advantage",
"investment_modalities",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"af73fe88-66dc-4c99-a7b3-79f7ba690065"
]
},
{
"id": 17,
"status": "submitted",
"owner": 21,
"category": "investment_project",
"canonical_keys": [
"risks",
"assets",
"markets",
"currency",
"licenses",
"products",
"documents",
"evidences",
"locations",
"sector_id",
"employment",
"milestones",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"funding_sought",
"maturity_stage",
"official_title",
"demand_statement",
"geographic_scope",
"opportunity_type",
"total_investment",
"executive_summary",
"impact_indicators",
"investor_profiles",
"secured_financing",
"truth_declaration",
"internal_contact_id",
"economic_activity_id",
"environmental_social",
"investment_breakdown",
"opportunity_category",
"competitive_advantage",
"investment_modalities",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"6bf8d120-9266-44ce-9baa-ed12b4b50fd8"
]
},
{
"id": 18,
"status": "suspended",
"owner": 21,
"category": "investment_project",
"canonical_keys": [
"risks",
"assets",
"markets",
"currency",
"licenses",
"products",
"documents",
"evidences",
"locations",
"sector_id",
"employment",
"milestones",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"funding_sought",
"maturity_stage",
"official_title",
"demand_statement",
"geographic_scope",
"opportunity_type",
"total_investment",
"executive_summary",
"impact_indicators",
"investor_profiles",
"secured_financing",
"truth_declaration",
"internal_contact_id",
"economic_activity_id",
"environmental_social",
"investment_breakdown",
"opportunity_category",
"competitive_advantage",
"investment_modalities",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"936e6053-2e12-4f7c-97eb-43424c85a6e8"
]
},
{
"id": 20,
"status": "approved",
"owner": 21,
"category": "land_rights",
"canonical_keys": [
"documents",
"evidences",
"locations",
"sector_id",
"visibility",
"land_rights",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"official_title",
"demand_statement",
"geographic_scope",
"executive_summary",
"truth_declaration",
"internal_contact_id",
"economic_activity_id",
"opportunity_category",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"ea18a6fb-5637-4f8c-b8c0-989b25181fcb"
]
},
{
"id": 21,
"status": "submitted",
"owner": 21,
"category": "business_sale",
"canonical_keys": [
"documents",
"evidences",
"locations",
"sector_id",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"official_title",
"demand_statement",
"geographic_scope",
"executive_summary",
"truth_declaration",
"internal_contact_id",
"business_transaction",
"economic_activity_id",
"opportunity_category",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"ce83b0e7-0358-4759-b796-a9075f50f6c7"
]
},
{
"id": 22,
"status": "submitted",
"owner": 21,
"category": "business_partnership",
"canonical_keys": [
"documents",
"evidences",
"locations",
"sector_id",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"official_title",
"demand_statement",
"geographic_scope",
"executive_summary",
"truth_declaration",
"internal_contact_id",
"business_transaction",
"economic_activity_id",
"opportunity_category",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"a23e3105-fdad-45e3-b1dc-ce77a321a288"
]
},
{
"id": 30,
"status": "published",
"owner": 21,
"category": "investment_project",
"canonical_keys": [
"risks",
"assets",
"markets",
"currency",
"licenses",
"products",
"documents",
"evidences",
"locations",
"sector_id",
"employment",
"milestones",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"funding_sought",
"maturity_stage",
"official_title",
"review_due_date",
"demand_statement",
"geographic_scope",
"opportunity_type",
"total_investment",
"executive_summary",
"impact_indicators",
"investor_profiles",
"secured_financing",
"truth_declaration",
"internal_contact_id",
"economic_activity_id",
"environmental_social",
"financial_indicators",
"investment_breakdown",
"opportunity_category",
"competitive_advantage",
"investment_modalities",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"0f86891c-4141-48f1-91d2-6eb3e6e06acd",
"47185cd8-107c-48dd-9c14-abb6283cacb9"
]
},
{
"id": 34,
"status": "published",
"owner": 21,
"category": "business_partnership",
"canonical_keys": [
"currency",
"documents",
"evidences",
"locations",
"sector_id",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"official_title",
"review_due_date",
"demand_statement",
"geographic_scope",
"executive_summary",
"truth_declaration",
"internal_contact_id",
"business_transaction",
"economic_activity_id",
"opportunity_category",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"95b9bb1e-7b7e-424e-830b-4f6b6cefc204"
]
},
{
"id": 56,
"status": "published",
"owner": 21,
"category": "franchise",
"canonical_keys": [
"images",
"currency",
"documents",
"evidences",
"locations",
"sector_id",
"visibility",
"promoter_id",
"subsector_id",
"location_mode",
"promoter_type",
"official_title",
"review_due_date",
"demand_statement",
"geographic_scope",
"executive_summary",
"truth_declaration",
"internal_contact_id",
"business_transaction",
"economic_activity_id",
"opportunity_category",
"publication_languages"
],
"version": null,
"canonical_sector": 13,
"subsector": "38b68b5c-1ef6-42ff-acdc-c92af94f7a4e",
"activity": "102513a5-d497-43d9-8794-9beab8709627",
"documents": [
"7615f127-c7e8-4412-b7b1-f5cc903e2d12",
"637bdda1-ab61-4713-bd0c-94f20fb71e2d",
"21dae751-99da-44a7-bbca-adb841982cdc",
"6e6aef78-0cee-43ab-9237-9793f508e492",
"ba616e20-36b0-427a-b7c0-207ad1e05635",
"7558810d-a3e6-4d75-b968-3b27811faa03"
]
}
]
@@ -0,0 +1,10 @@
{
"id": 16,
"scope": "Synthetic approval preconditions; only classification confirmation and explicit publisher action are observed in this increment.",
"snapshot_hash": "5b105b306732012d13f11839d3eb82e8acfd99567a834105f8bd90bafc87643d",
"gates": [
"technical_review",
"legal_territorial_review"
],
"active_changes": 0
}
@@ -0,0 +1,8 @@
{
"canonical_secondary": 15,
"canonical_existing_relations_before": 0,
"canonical_new_relations": 3,
"readable_business_drafts": [],
"legacy_cipher_unavailable_count": 0,
"active_changes": 0
}
@@ -0,0 +1,275 @@
{
"target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3",
"manifest_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"migration": "2026_10_16_120000_extend_economic_reference_hierarchy",
"installed": true,
"consistent": true,
"imported": true,
"publication": "published",
"rows": [
{
"table": "reference_catalog_versions",
"id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"code": "economic-activities-cae",
"status": "reuse",
"current_hash": "037832f0f8bfe07004373e0c1e58a5f2b5149baf2b1588339f5513202437ba66",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"status": "reuse",
"current_hash": "93f34a680f28c296f2eafa2e22883c66b010608fb96d6907dc4f24a9146d77db",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"status": "reuse",
"current_hash": "29e55b84a66c59ee5f21ccc184bb0c9082d33b19c1a28708ebfea6f24c78eb8c",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"code": "011",
"status": "reuse",
"current_hash": "ed56d7ff1340b543116954e41f3de37aa4397b609c8189872b4cbd5cd8599b3c",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"code": "0112",
"status": "reuse",
"current_hash": "562ff6b549093083bc5756315c5ced4974c0df10d7c142ec7303902a3e577ad5",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"code": "01120",
"status": "reuse",
"current_hash": "328a95a2d559cba59bd01e1f361b96243d59755e8372d73d2a9b6d0626ede1d9",
"current_visibility": "published"
},
{
"table": "value_chains",
"id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"code": "CLU01-INPUT",
"status": "reuse",
"current_hash": "16a0c370b63dc56decafe7c6bbb9cdc425400c9f31864bb39d70ae24dd3223d0",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"code": "CLU01-PRODUCTION",
"status": "reuse",
"current_hash": "2f0d36c9c6678476f46e4b8d3bfa7aa1053ff1e8f2508a946d6643c203bab871",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"code": "CLU01-PROCESSING",
"status": "reuse",
"current_hash": "947b933d2e0166e3cd71dcf68f049fe2195d6231ce485e28b5c1a82225f9df14",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"code": "CLU01-LOGISTICS",
"status": "reuse",
"current_hash": "0ad9df4e8528314b15c31c500e879febce0ef233dfabbc072373db7aa934903e",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "16d3e30c-3acc-598c-851b-92267342eaae",
"code": "CLU01-MARKET",
"status": "reuse",
"current_hash": "5419415cf098851e0207b2d17b4439824e89ba6df929089c4e5456f0bc2ad302",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "61be8cc1-7a17-5444-a79a-3007f201ef86",
"code": "CLU01-INPUT:CLU01-PRODUCTION",
"status": "reuse",
"current_hash": "8a2d208c535d28ce304586047904676760216b8bb2574c3d673be2d8f63db01d",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "c295605b-710c-57e8-9df6-57407d1a6bb8",
"code": "CLU01-PRODUCTION:CLU01-PROCESSING",
"status": "reuse",
"current_hash": "a266642a1152e9487e2ff94db98d7c471e3caf11527481ba9e31bad0a1e0cd96",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "a651e9cb-65c1-5812-8ffe-20b14a91a968",
"code": "CLU01-PROCESSING:CLU01-LOGISTICS",
"status": "reuse",
"current_hash": "bab83bff1ebd38d8d8dcae419e9ed4602dbb9a69c28b666b0ba695fcb925550f",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "f84a473a-1797-53bf-b054-bb29c4ebce3b",
"code": "CLU01-LOGISTICS:CLU01-MARKET",
"status": "reuse",
"current_hash": "82907687b50ccc9c53b4e160dfa2de6ad49fb2de998a4b1164db9bcaca15ca4d",
"current_visibility": "public"
}
],
"sources": [
{
"name": "CAE eBAU.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"bytes": 76699,
"ready": true
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"bytes": 1658773,
"ready": true
},
{
"name": "agronegócio 1.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"bytes": 15453,
"ready": true
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"bytes": 24358,
"ready": true
}
],
"scan": {
"at": "2026-10-16T09:26:37+00:00",
"manifest_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"files": [
{
"name": "manifesto",
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 35,
"detail": null
}
},
{
"name": "CAE eBAU.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 60,
"detail": null
}
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 78,
"detail": null
}
},
{
"name": "agronegócio 1.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 44,
"detail": null
}
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 56,
"detail": null
}
}
]
},
"divergence": {
"exemplar_subclasses": 600,
"prior_instruction_subclasses": 579,
"status": "documentary_open_nonblocking_for_slice"
},
"convention": {
"subsector": "01",
"activity": "01120",
"levels": 5
},
"common_reasons": [],
"operations": {
"schema": {
"ready": false,
"reasons": [
"Gestor de instalação ou titular da dupla necessário."
],
"hash": "c00764bf10d78700f86b1f69ef262ba741aaec7b8789be424b72c43a304c4e12",
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"import": {
"ready": true,
"reasons": [],
"hash": "a6ce0bd82351620c32e85d995633e14fe498360c543e52106f8667b339af9a84",
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"publish": {
"ready": true,
"reasons": [],
"hash": "3ada5e5635c3372c944767897eb736e2f4c62a7f043cbf3013cdc50664028dcb",
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"withdraw": {
"ready": true,
"reasons": [],
"hash": "901514f01da6f1f1c80c7b978e124ac9f17192c9b51197c65f342b915c6cc82d",
"backupDate": null,
"evidence_mode": "isolated_QA"
}
}
}
@@ -0,0 +1,11 @@
{
"database": "economic_references_20261016_test",
"synthetic_accounts_in_clone": 6,
"grants_changed": 0,
"new_businesses": 0,
"document": "025cce5b-73c1-43a3-b969-dc6e592bc28d",
"existing_clean_bytes_verified": true,
"active_changes": 0,
"role_assignments_unchanged": true,
"role_hash": "8334361fca313acfafe60c36ff8d5d9bc1af0f2a0d7f9482265a33a976df4aa6"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
{
"status": 422,
"expected": 200,
"path": "/management/economic-references/lot-01/withdraw",
"message": "Há referências anteriores já públicas reutilizadas: reconciliar o mapa de retirada antes de agir.",
"errors": null
}
@@ -0,0 +1 @@
{"data": [{"id": "a2000000-0000-4000-8000-000000000001", "value": "agronegocio", "code": "agronegocio", "name": "Agronegócio", "label": "Agronegócio", "locale": "pt-MZ", "parent_id": null, "sector_id": 1, "version_no": 1}, {"id": "a2000000-0000-4000-8000-000000000005", "value": "economia-azul", "code": "economia-azul", "name": "Economia Azul", "label": "Economia Azul", "locale": "pt-MZ", "parent_id": null, "sector_id": 5, "version_no": 1}, {"id": "a2000000-0000-4000-8000-000000000002", "value": "energia", "code": "energia", "name": "Energia e Mineração", "label": "Energia e Mineração", "locale": "pt-MZ", "parent_id": null, "sector_id": 2, "version_no": 1}, {"id": "a2000000-0000-4000-8000-000000000004", "value": "infraestruturas", "code": "infraestruturas", "name": "Infraestruturas", "label": "Infraestruturas", "locale": "pt-MZ", "parent_id": null, "sector_id": 4, "version_no": 1}, {"id": "a2000000-0000-4000-8000-000000000006", "value": "mercado-financeiro", "code": "mercado-financeiro", "name": "Mercado Financeiro", "label": "Mercado Financeiro", "locale": "pt-MZ", "parent_id": null, "sector_id": 6, "version_no": 1}, {"id": "a2000000-0000-4000-8000-000000000003", "value": "turismo", "code": "turismo", "name": "Turismo", "label": "Turismo", "locale": "pt-MZ", "parent_id": null, "sector_id": 3, "version_no": 1}], "links": {"next": null, "previous": null}, "next_page_url": null, "prev_page_url": null, "current_page": 1, "per_page": 20, "total": 6, "last_page": 1, "meta": {"catalog": "economic-activities", "version": 1, "locale": "pt-MZ", "source_version": "sector-seeder-v1", "valid_from": "2026-10-01", "valid_to": null, "current_page": 1, "per_page": 20, "total": 6, "last_page": 1}}
@@ -0,0 +1,18 @@
{
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"activities": {
"A": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"01": "af45b335-61a5-53da-a029-a8fab91cf624",
"011": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"0112": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"01120": "517ef71f-82a9-5233-afbf-741e6fe43dc6"
},
"chains": {
"CLU01-INPUT": "97ab2800-f863-5917-abb6-2ef20545b31e",
"CLU01-PRODUCTION": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"CLU01-PROCESSING": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"CLU01-LOGISTICS": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"CLU01-MARKET": "16d3e30c-3acc-598c-851b-92267342eaae"
},
"catalog": "21a8bbf7-efb3-55e5-ae26-f346848282a2"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,323 @@
{
"lot": "lot-01",
"version": 1,
"origin_version": "eBAU-sha256-97ef68346803",
"scope": "five-node rice slice and editorial CLU-01 chain; no normative edition conformity assertion",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"divergence": {
"exemplar_subclasses": 600,
"prior_instruction_subclasses": 579,
"status": "documentary_open_nonblocking_for_slice"
},
"convention": {
"subsector": "01",
"activity": "01120",
"levels": 5
},
"existing": {
"sector": {
"id": 1,
"slug": "agronegocio",
"code": null,
"source_system": null,
"external_id": null,
"name": "Agronegócio"
},
"cluster": {
"id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"slug": null,
"code": "CLU-01",
"source_system": "upgrade-v4",
"external_id": "CLU-01",
"name": "Agro-indústria e segurança alimentar"
}
},
"sources": [
{
"name": "CAE eBAU.xlsx",
"relative_path": "sources/97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"bytes": 76699,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar 97ef68346803"
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"relative_path": "sources/e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"bytes": 1658773,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar e1169a7743b1"
},
{
"name": "agronegócio 1.docx",
"relative_path": "sources/c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"bytes": 15453,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar c8033366e265"
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"relative_path": "sources/356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"bytes": 24358,
"publication": "private retained source; no library publication",
"source_version": "retained exemplar 356e46acd551"
}
],
"disclosure": {
"reference_designations_and_citations": "bounded editorial/reference slice authorised for QA; active requires explicit Tempo decision",
"source_originals": "private only"
},
"catalog": {
"id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"catalog_code": "economic-activities-cae",
"version_no": 1,
"locale": "pt-MZ",
"source_system": "retained-ebau-exemplar",
"source_version": "retained exemplar 97ef68346803",
"source_reference": "CAE eBAU.xlsx, folha CAE; cinco nós A/01/011/0112/01120, hash 97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545; edição normativa não determinada; 600/579 aberto.",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft"
},
"activities": [
{
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": null,
"sector_id": null,
"code": "A",
"label_pt_mz": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 1,
"source_record_id": "1",
"parent_source_record_id": null,
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 39,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "none",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"sector_id": 1,
"code": "01",
"label_pt_mz": "AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 2,
"source_record_id": "110",
"parent_source_record_id": "1",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 57,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "af45b335-61a5-53da-a029-a8fab91cf624",
"sector_id": 1,
"code": "011",
"label_pt_mz": "CULTURAS TEMPORÁRIAS",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 3,
"source_record_id": "200",
"parent_source_record_id": "110",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 124,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"sector_id": 1,
"code": "0112",
"label_pt_mz": "CULTURA DE ARROZ",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 4,
"source_record_id": "731",
"parent_source_record_id": "200",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 238,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
},
{
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"catalog_version_id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"parent_id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"sector_id": 1,
"code": "01120",
"label_pt_mz": "CULTURA DE ARROZ",
"description_pt_mz": "Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.",
"version_no": 1,
"valid_from": "2026-10-16",
"valid_to": null,
"status": "draft",
"metadata": {
"level": 5,
"source_record_id": "1049",
"parent_source_record_id": "731",
"source_sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"sheet": "CAE",
"row": 1122,
"lot": "lot-01",
"source_version": "retained exemplar 97ef68346803",
"edition": "not_determined",
"sector_mapping": "explicit bounded editorial mapping for rice slice",
"date_semantics": "catalog availability; not legal validity"
}
}
],
"chains": [
{
"id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-INPUT",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-INPUT",
"name": "Modelo editorial — Fornecimento agroindustrial",
"stage": "input"
},
{
"id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PRODUCTION",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-PRODUCTION",
"name": "Modelo editorial — Produção agrícola",
"stage": "production"
},
{
"id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PROCESSING",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-PROCESSING",
"name": "Modelo editorial — Transformação agroindustrial",
"stage": "processing"
},
{
"id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-LOGISTICS",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-LOGISTICS",
"name": "Modelo editorial — Logística agroindustrial",
"stage": "logistics"
},
{
"id": "16d3e30c-3acc-598c-851b-92267342eaae",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-MARKET",
"version_no": 1,
"data_classification": "internal",
"cluster_id": "2b37d84a-0b71-4b87-b577-6f550954c908",
"code": "CLU01-MARKET",
"name": "Modelo editorial — Comercialização agroindustrial",
"stage": "market"
}
],
"links": [
{
"id": "61be8cc1-7a17-5444-a79a-3007f201ef86",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-INPUT:CLU01-PRODUCTION",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"to_value_chain_id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"link_type": "supplies"
},
{
"id": "c295605b-710c-57e8-9df6-57407d1a6bb8",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PRODUCTION:CLU01-PROCESSING",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"to_value_chain_id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"link_type": "processes"
},
{
"id": "a651e9cb-65c1-5812-8ffe-20b14a91a968",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-PROCESSING:CLU01-LOGISTICS",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"to_value_chain_id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"link_type": "distributes"
},
{
"id": "f84a473a-1797-53bf-b054-bb29c4ebce3b",
"source_system": "economic-reference-lot-01",
"external_id": "CLU01-LOGISTICS:CLU01-MARKET",
"version_no": 1,
"data_classification": "internal",
"from_value_chain_id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"to_value_chain_id": "16d3e30c-3acc-598c-851b-92267342eaae",
"link_type": "distributes"
}
],
"citations": {
"activities": "CAE A1:F1; linhas 39,57,124,238,1122; SELF_ID explícito",
"chain_model": "Programação v6, §§534–543/631–635; modelo editorial genérico, sem operadores/capacidades/fluxos reais",
"context": "Agronegócio 1 §1; Corredores do Agronegócio §§4/10/23/29/39"
},
"new_reference_count": 15
}
@@ -0,0 +1,25 @@
{
"rows_total": 3402,
"rows_updated": [
"RF-CLU-001",
"RF-CLU-003",
"RF-PII-017",
"MASTER-9dee08d0-0070",
"OP-9f173ed3-0141",
"OP-FIELD-opportunity-subsector_id",
"OP-FIELD-opportunity-economic_activity_id"
],
"raw_other_rows_preserved": 3395,
"all_states_and_original_criteria_preserved": true,
"columns_updated": [
"Evidências atuais verificadas",
"Critérios cobertos pelas provas agrupadas",
"Limites das provas agrupadas",
"Esforço e pressupostos atuais"
],
"sha256_before": "70488d4d79d30b2d399b849ddd979334289c60c2d920a0a0288e77f5866bfc59",
"sha256_after": "b387357043f1ef33071a31d4160aeb30b97c1d6c3b4563a3ff01aa22f780c7db",
"authoring": "artifact-tool cells; raw non-target records preserved",
"independent_raw_and_cell_verification": true,
"backlog_sha256": "7b10b3e5abcf6f7cd7115508ce0de4265b353782e573583c9c97bbd8063c1873"
}
@@ -0,0 +1,271 @@
{
"target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3",
"manifest_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"migration": "2026_10_16_120000_extend_economic_reference_hierarchy",
"installed": true,
"consistent": true,
"imported": true,
"publication": "published",
"rows": [
{
"table": "reference_catalog_versions",
"id": "21a8bbf7-efb3-55e5-ae26-f346848282a2",
"code": "economic-activities-cae",
"status": "reuse",
"current_hash": "037832f0f8bfe07004373e0c1e58a5f2b5149baf2b1588339f5513202437ba66",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "a0fed2d8-154d-5464-822b-4b9d7e3e1ea5",
"code": "A",
"status": "reuse",
"current_hash": "93f34a680f28c296f2eafa2e22883c66b010608fb96d6907dc4f24a9146d77db",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "af45b335-61a5-53da-a029-a8fab91cf624",
"code": "01",
"status": "reuse",
"current_hash": "29e55b84a66c59ee5f21ccc184bb0c9082d33b19c1a28708ebfea6f24c78eb8c",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "9443bcbe-3325-5620-a84e-33fccba18fd6",
"code": "011",
"status": "reuse",
"current_hash": "ed56d7ff1340b543116954e41f3de37aa4397b609c8189872b4cbd5cd8599b3c",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "990f259b-d6fa-5ad1-ac23-6d117eab25c2",
"code": "0112",
"status": "reuse",
"current_hash": "562ff6b549093083bc5756315c5ced4974c0df10d7c142ec7303902a3e577ad5",
"current_visibility": "published"
},
{
"table": "economic_activities",
"id": "517ef71f-82a9-5233-afbf-741e6fe43dc6",
"code": "01120",
"status": "reuse",
"current_hash": "328a95a2d559cba59bd01e1f361b96243d59755e8372d73d2a9b6d0626ede1d9",
"current_visibility": "published"
},
{
"table": "value_chains",
"id": "97ab2800-f863-5917-abb6-2ef20545b31e",
"code": "CLU01-INPUT",
"status": "reuse",
"current_hash": "16a0c370b63dc56decafe7c6bbb9cdc425400c9f31864bb39d70ae24dd3223d0",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "b03f4ecb-e63b-5778-98f8-c2d2dc867c93",
"code": "CLU01-PRODUCTION",
"status": "reuse",
"current_hash": "2f0d36c9c6678476f46e4b8d3bfa7aa1053ff1e8f2508a946d6643c203bab871",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "01a84b2a-92eb-5c6e-836b-a8a1637ea544",
"code": "CLU01-PROCESSING",
"status": "reuse",
"current_hash": "947b933d2e0166e3cd71dcf68f049fe2195d6231ce485e28b5c1a82225f9df14",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "e0b59930-5753-5f95-a3e3-368d724a7dd2",
"code": "CLU01-LOGISTICS",
"status": "reuse",
"current_hash": "0ad9df4e8528314b15c31c500e879febce0ef233dfabbc072373db7aa934903e",
"current_visibility": "public"
},
{
"table": "value_chains",
"id": "16d3e30c-3acc-598c-851b-92267342eaae",
"code": "CLU01-MARKET",
"status": "reuse",
"current_hash": "5419415cf098851e0207b2d17b4439824e89ba6df929089c4e5456f0bc2ad302",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "61be8cc1-7a17-5444-a79a-3007f201ef86",
"code": "CLU01-INPUT:CLU01-PRODUCTION",
"status": "reuse",
"current_hash": "8a2d208c535d28ce304586047904676760216b8bb2574c3d673be2d8f63db01d",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "c295605b-710c-57e8-9df6-57407d1a6bb8",
"code": "CLU01-PRODUCTION:CLU01-PROCESSING",
"status": "reuse",
"current_hash": "a266642a1152e9487e2ff94db98d7c471e3caf11527481ba9e31bad0a1e0cd96",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "a651e9cb-65c1-5812-8ffe-20b14a91a968",
"code": "CLU01-PROCESSING:CLU01-LOGISTICS",
"status": "reuse",
"current_hash": "bab83bff1ebd38d8d8dcae419e9ed4602dbb9a69c28b666b0ba695fcb925550f",
"current_visibility": "public"
},
{
"table": "value_chain_links",
"id": "f84a473a-1797-53bf-b054-bb29c4ebce3b",
"code": "CLU01-LOGISTICS:CLU01-MARKET",
"status": "reuse",
"current_hash": "82907687b50ccc9c53b4e160dfa2de6ad49fb2de998a4b1164db9bcaca15ca4d",
"current_visibility": "public"
}
],
"sources": [
{
"name": "CAE eBAU.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"bytes": 76699,
"ready": true
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"bytes": 1658773,
"ready": true
},
{
"name": "agronegócio 1.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"bytes": 15453,
"ready": true
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"bytes": 24358,
"ready": true
}
],
"scan": {
"at": "2026-10-16T09:26:37+00:00",
"manifest_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"files": [
{
"name": "manifesto",
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 35,
"detail": null
}
},
{
"name": "CAE eBAU.xlsx",
"sha256": "97ef683468032d3153d89a23f78b97500c755c429694ef78b30197ad2e928545",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 60,
"detail": null
}
},
{
"name": "upgrade do portal de investimentos v6 programacao.docx",
"sha256": "e1169a7743b13ff6c950d3ffd4672a2afea32e81da84885e11154b7d8de9241e",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 78,
"detail": null
}
},
{
"name": "agronegócio 1.docx",
"sha256": "c8033366e265f51fff1ee8d72935c41d10db45020332fbbbd2bc77095461616e",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 44,
"detail": null
}
},
{
"name": "Corredores de Desenvolvimento do Agronegócio em Moçambique.docx",
"sha256": "356e46acd551fe3cafd63b08fcfc454eff24f75bfdce02f5f8183ccb4a300cc3",
"scan": {
"result": "clean",
"reason_code": null,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": "2026-10-16T08:24:17+00:00",
"duration_ms": 56,
"detail": null
}
}
]
},
"divergence": {
"exemplar_subclasses": 600,
"prior_instruction_subclasses": 579,
"status": "documentary_open_nonblocking_for_slice"
},
"convention": {
"subsector": "01",
"activity": "01120",
"levels": 5
},
"common_reasons": [],
"operations": {
"schema": {
"ready": false,
"reasons": [
"Gestor de instalação ou titular da dupla necessário."
],
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"import": {
"ready": true,
"reasons": [],
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"publish": {
"ready": true,
"reasons": [],
"backupDate": null,
"evidence_mode": "isolated_QA"
},
"withdraw": {
"ready": true,
"reasons": [],
"backupDate": null,
"evidence_mode": "isolated_QA"
}
}
}
@@ -0,0 +1,141 @@
{
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"url": "https://chatgpt.com/space/page_d6f090dba9048191a92c9175b3605dee",
"sequence": 23,
"candidate": "referencias-economicas-QA-966202f15577",
"old_blocks_preserved": 187,
"all_uploaded_hashes_match": true,
"sharing_changed": false,
"uploads": {
"ATUALIZACAO-MESMA-MATRIZ.json": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV9OdEZXclhwOFR0YTgxbnpzeEZPbVd3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "ATUALIZACAO-MESMA-MATRIZ-b84f015c05d84bf48053ad2459d298e4.json",
"mime_type": "application/json",
"byte_size": 931,
"sha256": "366ca6b811dfe5f8cbcd6c5a7bc5b511d61180ab956c236f70852e758872c0e7",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[ATUALIZACAO-MESMA-MATRIZ.json](library-file:fde1_bGliZmlsZV9OdEZXclhwOFR0YTgxbnpzeEZPbVd3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"MANIFESTO-ENTREGA.json": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV81Njh0UTdTWkF5ajlydENwNVdMWTJn_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "MANIFESTO-ENTREGA-294a271870564793867f8a522c22d2f9.json",
"mime_type": "application/json",
"byte_size": 37521,
"sha256": "a9e269a90a561e5ef2f462aa58cf2ae430c2904f948278b37f12dcc46273baf0",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[MANIFESTO-ENTREGA.json](library-file:fde1_bGliZmlsZV81Njh0UTdTWkF5ajlydENwNVdMWTJn_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"MANIFESTO-LOTE.json": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV85TUhNWHc3b1BKc3lfNndFSER1a3Nn_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "MANIFESTO-LOTE-6b6644f1753c40cda35747de6d57e6f3.json",
"mime_type": "application/json",
"byte_size": 12952,
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[MANIFESTO-LOTE.json](library-file:fde1_bGliZmlsZV85TUhNWHc3b1BKc3lfNndFSER1a3Nn_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"PROCEDIMENTO-EXATO.md": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV8yM0pjbnUzWEw1Q2F0cWl5MUdKVTNB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "PROCEDIMENTO-EXATO-af870f55f82d40a5a1ab06be77c5d573.md",
"mime_type": "text/markdown",
"byte_size": 8184,
"sha256": "58a11c82782bb1c06533ee7f59b91caa5c4a6a626126dec6039bf111a884c211",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[PROCEDIMENTO-EXATO.md](library-file:fde1_bGliZmlsZV8yM0pjbnUzWEw1Q2F0cWl5MUdKVTNB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"PROPOSTA-UNICA-TEMPO.md": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV9rOUF6ZWFrbHVtZlR5dFZPczVlZ0N3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "PROPOSTA-UNICA-TEMPO-c7006c8db3fa4c44913eb822230ac81a.md",
"mime_type": "text/markdown",
"byte_size": 4952,
"sha256": "3d7d977cb7efb9416c3305b56276a6da160bca1ac65fa3091b62f0faea29847c",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[PROPOSTA-UNICA-TEMPO.md](library-file:fde1_bGliZmlsZV9rOUF6ZWFrbHVtZlR5dFZPczVlZ0N3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"RELATORIO-QA.md": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV9jZ3RLMXBXRXlhZ25OOVFvWm95QmVB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "RELATORIO-QA-3c3d8dcabb224abc9d24fe97e171ffaf.md",
"mime_type": "text/markdown",
"byte_size": 7844,
"sha256": "477c6a070b307c9ac69d02821b1b6df5e858c6e45a61534735d8d4db4ef9d309",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[RELATORIO-QA.md](library-file:fde1_bGliZmlsZV9jZ3RLMXBXRXlhZ25OOVFvWm95QmVB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"REVERSAO-COMPATIVEL.md": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV8xY1pjNkx0MWF1Q3d4VkxjRDhwMnZR_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "REVERSAO-COMPATIVEL-c1b946bb38c4425dbf5943e7a4d00024.md",
"mime_type": "text/markdown",
"byte_size": 3571,
"sha256": "96e4e855bcae3492d394e3d8bb951ac6b30b12521ab283422f958da20a9e32bb",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[REVERSAO-COMPATIVEL.md](library-file:fde1_bGliZmlsZV8xY1pjNkx0MWF1Q3d4VkxjRDhwMnZR_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"RECIBO-INTEGRIDADE.json": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV9kUk9tM00xYVVrQTROOU9LV3pDeGZB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "RECIBO-INTEGRIDADE-28196a9aa4d04ae0adf112a946a8a7e6.json",
"mime_type": "application/json",
"byte_size": 2624,
"sha256": "598f54026fb643fc1d7de96e5cfd2fcf54e9db75aef6c03730d1fd0029f42931",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[RECIBO-INTEGRIDADE.json](library-file:fde1_bGliZmlsZV9kUk9tM00xYVVrQTROOU9LV3pDeGZB_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"referencias-economicas-QA-966202f15577.zip": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV90ajRJRXk3MlIzQkVsN3ZzVkJXUFV3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "referencias-economicas-QA-966202f15577-0855075b33b44112b1e5fcc6c5256e10.zip",
"mime_type": "application/zip",
"byte_size": 4384812,
"sha256": "2dd2b205abe34a9d986cc100bb6b5a3755b230dcaaded151e251375bbded1dc8",
"file_access_confirmed": true,
"is_image": false,
"markdown": "[referencias-economicas-QA-966202f15577.zip](library-file:fde1_bGliZmlsZV90ajRJRXk3MlIzQkVsN3ZzVkJXUFV3_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
},
"VISUAL-PROJECAO-FINAL.png": {
"page_id": "page_d6f090dba9048191a92c9175b3605dee",
"reference": "library-file:fde1_bGliZmlsZV9EX1dYeVo0UzJMMG90OEpaa2ZLOW5B_FileDrive_c902110ccc308191b2f4f6a2fc8c014a",
"file_name": "VISUAL-PROJECAO-FINAL-bd2c9f0569094c9f837b7e7056eb27fc.png",
"mime_type": "image/jpeg",
"byte_size": 108680,
"sha256": "3b2aa264934246b331a8f0e76d493ed894259773f575a204a657f038717ee1cc",
"file_access_confirmed": true,
"is_image": true,
"markdown": "![VISUAL-PROJECAO-FINAL.png](library-file:fde1_bGliZmlsZV9EX1dYeVo0UzJMMG90OEpaa2ZLOW5B_FileDrive_c902110ccc308191b2f4f6a2fc8c014a)",
"inserted": false,
"next_step": "Read the Page and use edit_page with its fresh guards to insert markdown."
}
}
}
@@ -0,0 +1,199 @@
{
"target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"checks": {
"sectors_old_id_1": true,
"sectors_old_id_2": true,
"sectors_old_id_3": true,
"sectors_old_id_4": true,
"sectors_old_id_5": true,
"sectors_old_id_6": true,
"sectors_old_id_7": true,
"sectors_old_id_8": true,
"sectors_old_id_9": true,
"sectors_old_id_10": true,
"sectors_old_id_11": true,
"sectors_old_id_12": true,
"sectors_old_id_13": true,
"sectors_old_id_14": true,
"sectors_old_id_15": true,
"reference_catalog_versions_old_id_a1000000-0000-4000-8000-000000000001": true,
"reference_catalog_versions_old_id_a1000000-0000-4000-8000-000000000002": true,
"reference_catalog_versions_old_id_a1000000-0000-4000-8000-000000000003": true,
"reference_catalog_versions_old_id_c220a719-f2a3-492c-a1ba-f8b17ab8fbc0": true,
"economic_activities_old_id_102513a5-d497-43d9-8794-9beab8709627": true,
"economic_activities_old_id_38b68b5c-1ef6-42ff-acdc-c92af94f7a4e": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000001": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000002": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000003": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000004": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000005": true,
"economic_activities_old_id_a2000000-0000-4000-8000-000000000006": true,
"economic_activities_old_id_d8b1da11-aabb-4c3b-bda5-e69e0a50eeed": true,
"economic_clusters_old_id_0db99a07-3c5c-407f-89e1-b18dcf8953f5": true,
"economic_clusters_old_id_13e15425-c0aa-4be9-9145-f81119a3b85f": true,
"economic_clusters_old_id_1579eab5-eab2-43a4-8c0c-3b6123edf230": true,
"economic_clusters_old_id_2b37d84a-0b71-4b87-b577-6f550954c908": true,
"economic_clusters_old_id_379c7d07-c767-4ab5-80db-3211f29eaf9e": true,
"economic_clusters_old_id_37fd560d-74ad-416d-8ad4-15db3a4739ba": true,
"economic_clusters_old_id_6c7da2d1-acd0-42aa-af39-9397fae9f557": true,
"economic_clusters_old_id_7f224d3a-3c82-42b1-bd18-ad9ab8afac1e": true,
"economic_clusters_old_id_e19235e0-0a36-4e65-8a61-07f1d52f07d1": true,
"portal_role_assignments_old_id_04f1addc-ead6-4f39-b716-7b24ed2a25cf": true,
"portal_role_assignments_old_id_0f3e11c6-d0bd-411f-aa51-9ced44e6dac3": true,
"portal_role_assignments_old_id_25f2718e-27cd-4fbe-817e-e0d1f5805f0b": true,
"portal_role_assignments_old_id_31efa64c-6a67-485c-8168-455de955a36a": true,
"portal_role_assignments_old_id_462e6a0c-af74-4c78-91ba-fb1ba2a31456": true,
"portal_role_assignments_old_id_49466ca7-0c39-4814-940f-6718b82e7b6d": true,
"portal_role_assignments_old_id_4cd8f2af-36fc-4755-8994-82ba1d85509b": true,
"portal_role_assignments_old_id_51bfdd9d-cc1a-4dbc-9066-3378eebd645e": true,
"portal_role_assignments_old_id_54b93965-51b8-431e-8872-dc5d2f9b7a31": true,
"portal_role_assignments_old_id_574394c4-3750-45fc-b4e3-25bec5fca3e3": true,
"portal_role_assignments_old_id_5768c7ce-4603-4e4c-994e-0dea392254f2": true,
"portal_role_assignments_old_id_5bd1f9d8-1ddb-4008-9414-551132755c6c": true,
"portal_role_assignments_old_id_5f825983-b75c-427f-862c-ab1db5b071a9": true,
"portal_role_assignments_old_id_5fe73ce9-9de4-42b1-8666-97274d4033f5": true,
"portal_role_assignments_old_id_696c5bd5-1d9e-4a0f-a438-c219e64d9ac8": true,
"portal_role_assignments_old_id_6d47cd90-a43e-4056-8c13-5f1775fd5765": true,
"portal_role_assignments_old_id_806cb16b-a996-4e6e-b85b-69ab57529c58": true,
"portal_role_assignments_old_id_82548503-1e60-4259-a642-290ac20c7388": true,
"portal_role_assignments_old_id_835c3bea-4e65-4237-ba4a-58d1e5b96369": true,
"portal_role_assignments_old_id_8d277473-7c70-4e63-84b2-dac996486bf5": true,
"portal_role_assignments_old_id_99dfa158-192b-43d9-b124-f49e442eaa76": true,
"portal_role_assignments_old_id_a7dbe756-62e6-418d-8e26-3c6b4d26b9cb": true,
"portal_role_assignments_old_id_b47c8922-b0a8-4fbf-ad57-0f3822d8da1d": true,
"portal_role_assignments_old_id_bfe0843d-92d0-4b3a-bf56-759fe5bacced": true,
"portal_role_assignments_old_id_cbe16237-b5b1-461d-ba97-5683e8633061": true,
"portal_role_assignments_old_id_d252a4de-4f99-4729-926b-4bb24a1a57e9": true,
"portal_role_assignments_old_id_d94a3289-a86c-4e72-8501-fe8df59de8de": true,
"portal_role_assignments_old_id_da91dc3c-e3e9-492c-9f11-a584e7015afb": true,
"portal_role_assignments_old_id_ded9eebd-c2df-4c1b-9919-93a664c0a149": true,
"portal_role_assignments_old_id_e7a82447-7872-48b9-a5be-78d28d93fe64": true,
"portal_role_assignments_old_id_ea8384f2-5499-46a8-800b-3bd4ef869ab4": true,
"portal_role_assignments_old_id_ed22ddd6-bc77-4710-ad15-d2195ce2647a": true,
"portal_role_assignments_old_id_fe7b519d-14a4-454b-bd6c-9039a4fff50f": true,
"portal_superuser_pair_old_id_1": true,
"business_workflow_transitions_old_id_02b9f95b-cb9a-4b42-bb53-4b6089de5556": true,
"business_workflow_transitions_old_id_10ef7bc8-dc67-4154-a7a4-28f14f25899f": true,
"business_workflow_transitions_old_id_295423fd-205b-4c0f-a7a9-df4aeb770d12": true,
"business_workflow_transitions_old_id_2ae3cc8b-9325-4e6f-86d5-a83a0baa946c": true,
"business_workflow_transitions_old_id_3497172d-a2ab-4d2b-9b04-0beef922280c": true,
"business_workflow_transitions_old_id_4601493a-0e85-4995-9cee-7325cc4cfad3": true,
"business_workflow_transitions_old_id_4a032ef9-47cd-48f3-9269-0315e8092d07": true,
"business_workflow_transitions_old_id_4e0d8856-f0f9-4a78-892d-82e2d8519815": true,
"business_workflow_transitions_old_id_50b35f7d-5e64-443b-b8b2-937905104d48": true,
"business_workflow_transitions_old_id_6080241a-addc-4f52-bdc3-d4cf180d93d4": true,
"business_workflow_transitions_old_id_713e5a50-b792-48fb-bb64-2ea55a363a86": true,
"business_workflow_transitions_old_id_759d4ce3-a8da-4be0-8653-e7d7234e8874": true,
"business_workflow_transitions_old_id_772cee71-a7c7-4cde-bc15-6c9b874678f9": true,
"business_workflow_transitions_old_id_7a6af1d3-41ae-444d-84cb-88e214e2ddd3": true,
"business_workflow_transitions_old_id_7ab5bb25-d262-4172-ac29-b3c5e6ba5396": true,
"business_workflow_transitions_old_id_81d5e596-5774-4da6-a325-218fb9e8029d": true,
"business_workflow_transitions_old_id_a13ba3a8-25d3-4c0d-9443-6e8c08f5cf6b": true,
"business_workflow_transitions_old_id_a4a5ddee-c0bd-4212-ad18-cade26b6ccff": true,
"business_workflow_transitions_old_id_b1d30f88-3b94-4b67-aeeb-11815be9462d": true,
"business_workflow_transitions_old_id_b81f2f52-c078-4f1d-ac3b-c0a5f59a385c": true,
"business_workflow_transitions_old_id_b95d73c7-9a67-43f6-9a20-67fa80728f56": true,
"business_workflow_transitions_old_id_c130b201-e7f3-472b-84e2-b55aefda4f25": true,
"business_workflow_transitions_old_id_cd3a8471-1159-40db-a6e2-15607c08152a": true,
"business_workflow_transitions_old_id_df412b7d-ad35-4591-9476-7d802cebc17a": true,
"business_workflow_transitions_old_id_dfd73e3d-e34b-4864-8d40-934ec2cee515": true,
"business_workflow_transitions_old_id_e4899774-71e7-461f-9f1e-acb6b746e373": true,
"business_workflow_transitions_old_id_e5adb242-b3a3-4fff-952d-3e144ab10249": true,
"business_workflow_transitions_old_id_ed473e82-ad91-4581-a1b0-626d53788ed0": true,
"business_workflow_transitions_old_id_f05ebc98-8cc9-4296-8a49-487ff01393b6": true,
"business_workflow_transitions_old_id_f41d85df-e5a9-46b8-87ee-f51b3a6cc0d3": true,
"reference_catalog_versions_exact_old_and_lot_UUIDs": true,
"economic_activities_exact_old_and_lot_UUIDs": true,
"value_chains_exact_old_and_lot_UUIDs": true,
"value_chain_links_exact_old_and_lot_UUIDs": true,
"four_nodes_same_existing_sector_allowed": true,
"no_new_business_records": true,
"no_new_canonical_opportunities": true,
"business_preserved_0a4f4c58-b39c-493b-9339-948660ceecb9": true,
"business_preserved_172aa874-98fc-4bf6-b78f-d2e9a386d345": true,
"business_preserved_4e931f7b-35e2-44b5-8322-0c0b76c90728": true,
"business_preserved_4f927885-4e30-42d6-a9ed-7c983f5af149": true,
"business_preserved_67d80699-1b0d-43e2-959d-5e1ad956dc74": true,
"business_preserved_7208ef2b-0693-49ba-b0e2-9e52938b1a99": true,
"business_preserved_f65c1d9d-5820-4030-8dc1-fe7ff3de0cd2": true,
"opportunity_preserved_1": true,
"opportunity_preserved_2": true,
"opportunity_preserved_3": true,
"opportunity_preserved_4": true,
"opportunity_preserved_5": true,
"opportunity_preserved_6": true,
"opportunity_preserved_7": true,
"opportunity_preserved_8": true,
"opportunity_preserved_9": true,
"opportunity_preserved_10": true,
"opportunity_preserved_11": true,
"opportunity_preserved_12": true,
"opportunity_preserved_13": true,
"opportunity_preserved_14": true,
"opportunity_preserved_17": true,
"opportunity_preserved_18": true,
"opportunity_preserved_19": true,
"opportunity_preserved_20": true,
"opportunity_preserved_21": true,
"opportunity_preserved_22": true,
"opportunity_preserved_23": true,
"opportunity_preserved_24": true,
"opportunity_preserved_25": true,
"opportunity_preserved_26": true,
"opportunity_preserved_27": true,
"opportunity_preserved_28": true,
"opportunity_preserved_29": true,
"opportunity_preserved_30": true,
"opportunity_preserved_31": true,
"opportunity_preserved_32": true,
"opportunity_preserved_33": true,
"opportunity_preserved_34": true,
"opportunity_preserved_35": true,
"opportunity_preserved_36": true,
"opportunity_preserved_37": true,
"opportunity_preserved_38": true,
"opportunity_preserved_39": true,
"opportunity_preserved_40": true,
"opportunity_preserved_41": true,
"opportunity_preserved_42": true,
"opportunity_preserved_43": true,
"opportunity_preserved_44": true,
"opportunity_preserved_45": true,
"opportunity_preserved_46": true,
"opportunity_preserved_47": true,
"opportunity_preserved_48": true,
"opportunity_preserved_49": true,
"opportunity_preserved_50": true,
"opportunity_preserved_51": true,
"opportunity_preserved_52": true,
"opportunity_preserved_53": true,
"opportunity_preserved_54": true,
"opportunity_preserved_55": true,
"opportunity_preserved_56": true,
"opportunity_preserved_57": true,
"reference_QA_untouched_sectors": true,
"reference_QA_untouched_reference_catalog_versions": true,
"reference_QA_untouched_economic_activities": true,
"reference_QA_untouched_economic_clusters": true,
"reference_QA_untouched_value_chains": true,
"reference_QA_untouched_value_chain_links": true,
"reference_QA_untouched_portal_role_assignments": true,
"reference_QA_untouched_portal_superuser_pair": true,
"reference_QA_untouched_existing_businesses": true,
"reference_QA_untouched_existing_business_revisions": true,
"reference_QA_untouched_business_workflow_transitions": true,
"reference_QA_untouched_opportunities": true,
"reference_QA_untouched_audit_events": true,
"original_reference_published_v12": true
},
"count": 184,
"original_reference": {
"status": "published",
"version_no": 12
},
"active_database_connections": 0,
"active_changes": 0
}
@@ -0,0 +1,14 @@
{
"source": "C:\\Users\\macbook\\.config\\investmoz\\referencias-economicas-QA-20261016\\source",
"private": "C:\\Users\\macbook\\.config\\investmoz\\referencias-economicas-QA-20261016",
"database": "economic_references_20261016_test",
"host": "127.0.0.1",
"port": 55441,
"url": "http://127.0.0.1:18531",
"reference_QA": "stability_consumers_20261011_084534_test:55441",
"reference_dump_sha256": "5ac003db13552ca686c519068fda2e342883bb95c1d247337adfb1c1e45c4b3a",
"QA_key": "Isolated existing synthetic QA key only; no active secrets",
"active_changes": 0,
"accepted_tests_repeated": false,
"started_at": "2026-10-16T08:51:44.244486+00:00"
}
@@ -0,0 +1,9 @@
{
"transaction_rolled_back": true,
"identity_conflict_detected": true,
"operation_disabled": true,
"visible_reasons": [
"Conflito de identidade\/versão: não será aplicado parcialmente."
],
"active_changes": 0
}
@@ -0,0 +1,36 @@
{
"target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"checks": {
"OpportunityManagement_is_exact_previous_source": true,
"ExistingBusinessDrafts_is_exact_previous_source": true,
"old_canonical_save_preserves_entire_payload": true,
"old_canonical_save_preserves_all_decisions": true,
"canonical_version_advances_normally": true,
"withdrawn_saved_taxonomy_remains_semantically_valid": true,
"withdrawn_refs_not_valid_for_new_taxonomy": true,
"destructive_down_after_usage_refused": true,
"old_business_editor_preserves_readable_original_payload": true,
"old_business_editor_recovers_entire_classification_journal": true,
"old_business_editor_advances_version": true,
"business_edit_fixture_reverted_to_published": true,
"all_role_grants_unchanged": true
},
"count": 13,
"type": "partial compatible rollback; additive schema and seven functional sources retained",
"canonical": {
"id": 15,
"real_old_service_save": true,
"committed": true
},
"business": {
"UUID": "172aa874-98fc-4bf6-b78f-d2e9a386d345",
"real_old_service_save": true,
"transaction_rolled_back": true,
"editable_state_is_fixture": true
},
"legacy_unreadable_draft_recovery": "not demonstrated; no original legacy draft decrypted or overwritten",
"active_changes": 0
}
@@ -0,0 +1,24 @@
{
"verified_at": "2026-10-16T09:34:14.278337+00:00",
"counts": {
"application_artifacts": 13,
"sources": 11,
"substitutions": 7,
"new_files": 6,
"compiled_files": 162,
"php_linted": 9,
"active_files_compared": 982,
"protected_files_compared": 3
},
"types_check": "passed",
"build": "passed; existing optional fontaine/chunk-size notices only",
"build_asset_references_checked": 164,
"active_sources_config_build_unchanged": true,
"active_database_connections": 0,
"QA_target": {
"database": "economic_references_20261016_test",
"port": 55441
},
"candidate": "referencias-economicas-QA-966202f15577",
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

@@ -0,0 +1,28 @@
Browser tab: 1168166510, Title: "Oportunidade sintética QA investment_project - InvesteMoz", URL: "http://127.0.0.1:18531/oportunidades/inv-mz-gen-5673010729603343".
The following is a diff from the previous accessibility tree with ~ and + representing changed and added elements, respectively. Removed elements are summarized by ID range.
Removed element IDs: 79
+ 131 heading Parcerias ligadas a este registo, Value: 2
+ 132 text Parcerias ligadas a este registo
+ 133 text Ainda não há parcerias publicadas com esta origem.
+ 134 link Description: Propor parceria a partir deste registo, Value: 127.0.0.1:18531/parcerias/criar?origin_type=investment&origin_id=16
+ 135 container
+ 136 container
+ 137 button Zoom in
+ 138 button Zoom out
+ 139 text 300 km
+ 140 container
+ 141 link Description: Leaflet, Help: A JavaScript library for interactive maps, Value: leafletjs.com/
+ 142 text ©
+ 143 link Description: OpenStreetMap, Value: openstreetmap.org/copyright
+ 144 text contributors
~ 76 text 0 locais com coordenadas disponíveis.
+ 145 text Sem limite administrativo acessível para este território neste perfil.
+ 146 container
+ 147 text 0 limites disponíveis na hierarquia selecionada. São contexto administrativo, não perímetro nem disponibilidade de investimento. A edição e a atualidade jurídica são informações distintas.
+ 148 container
+ 149 text 1 investimentos sem ponto público utilizável. Consulte as fichas para localizações documentadas sem coordenadas:
+ 150 content list
+ 151 link Description: Oportunidade sintética QA investment_project, Value: 127.0.0.1:18531/oportunidades/inv-mz-gen-5673010729603343
+ 152 container grammarly-integration
+ 153 text {"mode":"full","isActive":true,"isUserDisabled":false}
The focused UI element is 1 AXWebArea Oportunidade sintética QA investment_project - InvesteMoz, URL: 127.0.0.1:18531/oportunidades/inv-mz-gen-5673010729603343
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

@@ -0,0 +1,24 @@
Browser tab: 1168166510, Title: "Editar oportunidade INV-MZ-GEN-1964172608177406 - InvesteMoz", URL: "http://127.0.0.1:18531/minhas-oportunidades/15/edit".
The following is a diff from the previous accessibility tree with ~ and + representing changed and added elements, respectively. Removed elements are summarized by ID range.
Removed element IDs: 68
+ 742 container
+ 743 heading Subsector ou atividade — Confirmado, Value: 3
+ 744 text Subsector ou atividade — Confirmado
+ 745 text Referência: af45b335-61a5-53da-a029-a8fab91cf624 · Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01. · A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA. Ato externo: Não determinado . Disponibilidade de benefícios não inferida. Decisão indisponível nesta sessão: exige Validador no âmbito, responsabilidade correspondente, MFA e independência. Correspondência delimitada ao exemplar e ao modelo editorial do lote 01. · QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
+ 746 button (collapsed) Histórico desta versão, Secondary Actions: Expand
+ 747 text Histórico desta versão
+ 748 container
+ 749 heading Subsector ou atividade — Confirmado, Value: 3
+ 750 text Subsector ou atividade — Confirmado
+ 751 text Referência: 517ef71f-82a9-5233-afbf-741e6fe43dc6 · Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01. · A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA. Ato externo: Não determinado . Disponibilidade de benefícios não inferida. Decisão indisponível nesta sessão: exige Validador no âmbito, responsabilidade correspondente, MFA e independência. Correspondência delimitada ao exemplar e ao modelo editorial do lote 01. · QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
+ 752 button (collapsed) Histórico desta versão, Secondary Actions: Expand
+ 753 text Histórico desta versão
+ 754 container
+ 755 heading Cadeia de valor — Confirmado, Value: 3
+ 756 text Cadeia de valor — Confirmado
+ 757 text Referência: b03f4ecb-e63b-5778-98f8-c2d2dc867c93 · Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01. · A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA. Ato externo: Não determinado . Disponibilidade de benefícios não inferida. Decisão indisponível nesta sessão: exige Validador no âmbito, responsabilidade correspondente, MFA e independência. Correspondência delimitada ao exemplar e ao modelo editorial do lote 01. · QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
+ 758 button (collapsed) Histórico desta versão, Secondary Actions: Expand
+ 759 text Histórico desta versão
+ 760 container grammarly-integration
+ 761 text {"mode":"full","isActive":true,"isUserDisabled":false}
The focused UI element is 148 pop up button (collapsed, settable) Value: A → 01 → 011 → 0112 → 01120 — CULTURA DE ARROZ, Secondary Actions: Expand, Atividade económica A — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA → 01 — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS → 011 — CULTURAS TEMPORÁRIAS → 0112 — CULTURA DE ARROZ → 01120 — CULTURA DE ARROZ · Exemplar eBAU; edição normativa não determinada; divergência 600/579 aberta.
Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

@@ -0,0 +1,3 @@
Browser tab: 1168166510, Title: "Referências económicas — lote delimitado - InvesteMoz", URL: "http://127.0.0.1:18531/management/economic-references/lot-01".
There has been no change in the accessibility tree.
The focused UI element is 146 checkbox (settable, integer) Description: Confirmo somente a ação selecionada para este lote., Value: 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

@@ -0,0 +1,9 @@
Browser tab: 1168166510, Title: "SIMULAÇÃO QA — aceitação visual agrupada - InvesteMoz", URL: "http://127.0.0.1:18531/negocios/simulacao-qa-aceitacao-visual-agrupada-172aa87498".
The following is a diff from the previous accessibility tree with ~ and + representing changed and added elements, respectively. Removed elements are summarized by ID range.
+ 62 heading Parcerias ligadas a este registo, Value: 2
+ 63 text Parcerias ligadas a este registo
+ 64 text Ainda não há parcerias publicadas com esta origem.
+ 65 link Description: Propor parceria a partir deste registo, Value: 127.0.0.1:18531/parcerias/criar?origin_type=business&origin_id=172aa874-98fc-4bf6-b78f-d2e9a386d345
+ 66 container grammarly-integration
+ 67 text {"mode":"full","isActive":true,"isUserDisabled":false}
The focused UI element is 0 AXWebArea SIMULAÇÃO QA — aceitação visual agrupada - InvesteMoz, URL: 127.0.0.1:18531/negocios/simulacao-qa-aceitacao-visual-agrupada-172aa87498
Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

@@ -0,0 +1,738 @@
Browser tab: 1168166510, Title: "InvesteMoz QA referencias economicas", URL: "http://127.0.0.1:18531/minhas-oportunidades/15/edit".
1 AXWebArea Editar oportunidade INV-MZ-GEN-1964172608177406 - InvesteMoz, URL: 127.0.0.1:18531/minhas-oportunidades/15/edit
2 container app
3 container Atalho para o conteúdo
4 link Description: Saltar para o conteúdo, Value: 127.0.0.1:18531/minhas-oportunidades/15/edit#portal-content
5 container Caminho de navegação
6 link Description: Início, Value: 127.0.0.1:18531/
7 text Synthetic QA edited by authorized organization colleague
8 container portal-content
9 container Navegação da conta
10 container
11 content list
12 link Description: InvesteMoz QA referencias economicas, Value: 127.0.0.1:18531/dashboard
13 text Platform
14 content list
15 link Description: Explorar investimentos, Value: 127.0.0.1:18531/oportunidades
16 link Description: Preparar o projecto, Value: 127.0.0.1:18531/como-investir
17 link Description: Serviços e apoio, Value: 127.0.0.1:18531/balcao-virtual
18 link Description: Parcerias, Value: 127.0.0.1:18531/parcerias
19 link Description: A minha área, Value: 127.0.0.1:18531/investidor
20 link Description: Minhas oportunidades, Value: 127.0.0.1:18531/minhas-oportunidades
21 link Description: Nova oportunidade, Value: 127.0.0.1:18531/minhas-oportunidades/create
22 link Description: Autorizações de Promotor, Value: 127.0.0.1:18531/perfil/promotor
23 content list
24 pop up button (collapsed) P2 Promotor QA — conta sintética 21, ID: radix-_r_8_, Secondary Actions: Expand
25 text P2
26 text Promotor QA — conta sintética 21
27 image
28 container
29 button Toggle sidebar
30 image
31 text Toggle sidebar
32 link Description: InvesteMoz, Value: 127.0.0.1:18531/
33 text Iniciativa privada e independente de apoio ao investimento. Orientação e acompanhamento internos; decisões oficiais cabem às instituições competentes.
34 container Sessão da conta
35 container
36 text Sessão: Promotor QA — conta sintética 21
37 button Terminar sessão
38 container Áreas do portal
39 content list
40 button (collapsed) Explorar investimentos, Secondary Actions: Expand
41 button (collapsed) Preparar o projecto, Secondary Actions: Expand
42 button (collapsed) Serviços e apoio, Secondary Actions: Expand
43 button (collapsed) Parcerias, Secondary Actions: Expand
44 button (collapsed) A minha área, Secondary Actions: Expand
45 button (collapsed) Perfil e oportunidades Grupo actual, Secondary Actions: Expand
46 text Perfil e oportunidades
47 text Grupo actual
48 container Assistente do percurso do investidor
49 button (collapsed) Acompanhar o meu projecto neste portal, Secondary Actions: Expand
50 container Perfil e oportunidades
51 link Description: Minhas oportunidades, Value: 127.0.0.1:18531/minhas-oportunidades
52 link Description: Nova oportunidade, Value: 127.0.0.1:18531/minhas-oportunidades/create
53 link Description: Autorizações de Promotor, Value: 127.0.0.1:18531/perfil/promotor
54 heading Editar oportunidade INV-MZ-GEN-1964172608177406, Value: 1
55 text Editar oportunidade INV-MZ-GEN-1964172608177406
56 link Description: Minhas oportunidades, Value: 127.0.0.1:18531/minhas-oportunidades
57 container Âmbito desta entrega
58 heading Âmbito desta entrega, Value: 2
59 text Âmbito desta entrega
60 text Seis categorias base: projeto de investimento, imobiliário, fundiário, venda de negócio, parceria e franquia. Rascunho, correção, revisão independente e publicação são ações distintas; uma aprovação interna não atribui direitos nem substitui uma decisão externa.
61 text No imobiliário, a submissão inclui venda e arrendamento de imóvel concluído, desocupado e sem encargos ou limitações urbanísticas adicionais. Pode guardar e recuperar as outras variantes em preparação; a sua submissão permanece indisponível.
62 text Concessão, financiamento, fornecimento e outros, partilha individual de anexos, restauração de oportunidades e exportação normativa integral Response/§27 não estão incluídos. O Response disponível conserva o contrato de compatibilidade e o histórico.
63 text As restantes variantes económicas, societárias, territoriais, de contribuições e licenças exigem documentação e revisão aplicáveis. Esta entrega não certifica a viabilidade, a titularidade ou a decisão externa de cada caso.
64 container Confirmação das associações
65 heading Confirmação por associação, Value: 2
66 text Confirmação por associação
67 text Associação, publicação e ato externo têm estados separados. Localização ou proximidade não concedem licença, benefício, terreno ou capacidade. Dados ausentes permanecem por determinar. Os elos identificados como Modelo editorial não confirmam operadores, capacidade ou relações comerciais. O recorte CAE conserva cinco níveis; 600/579 permanece documentalmente aberto.
68 text A recuperar associações…
69 container Estado da oportunidade
70 text Estado da preparação: Rascunho . Sem versão disponibilizada; aprovação interna é uma etapa distinta . Pedido de arquivo registado; aguarda decisão independente. O Promotor solicita arquivo; não elimina nem restaura oportunidades.
71 text Classificação de origem: Origem ainda indeterminada . Esta classificação não cria associações territoriais.
72 container Preenchimento e revisões
73 container
74 text Preenchimento gravado: 16.67 % ( 3 / 18 campos aplicáveis). Não equivale a validação ou aprovação.
75 link Description: Abrir resposta canónica gravada, Value: 127.0.0.1:18531/minhas-oportunidades/15/response
76 container
77 text Motivo da alteração
78 text entry area (settable) Motivo da alteração
79 button Guardar rascunho
80 link Description: Imagens, documentos e localizações, Value: 127.0.0.1:18531/minhas-oportunidades/15/resources
81 button (collapsed) Cadastrar contacto do promotor, Secondary Actions: Expand
82 text Cadastrar contacto do promotor
83 container Contrato da oportunidade — investment_project
84 container
85 text Contrato da oportunidade — investment_project
86 text O rascunho pode ficar incompleto. A submissão verifica os campos aplicáveis e os recursos guardados. Validação interna não equivale a autorização externa.
87 text Título oficial
88 text entry area (settable) Título oficial, ID: canonical.official_title
89 text Tipo de Promotor
90 pop up button (collapsed, settable) Tipo de Promotor, Value: Por indicar, ID: canonical.promoter_type, Secondary Actions: Expand
91 menu
92 (selected) Por indicar
93 public
94 private
95 ppp
96 cooperative
97 association
98 community
99 other
100 container
101 text Contacto interno
102 pop up button (collapsed, settable) Contacto interno, Value: Por indicar, Secondary Actions: Expand
103 menu
104 (selected) Por indicar
105 Contacto sintético QA — oportunidade
106 Contacto QA auditoria
107 text Autoriza publicar o contacto?
108 pop up button (collapsed, settable) Autoriza publicar o contacto?, Value: Por indicar, ID: canonical.publish_contact, Secondary Actions: Expand
109 menu
110 (selected) Por indicar
111 Sim
112 Não
113 container
114 text Contacto para divulgação
115 pop up button (collapsed, settable) Contacto para divulgação, Value: Por indicar, Secondary Actions: Expand
116 menu
117 (selected) Por indicar
118 Contacto sintético QA — oportunidade
119 Contacto QA auditoria
120 container
121 text Sector
122 pop up button (collapsed, settable) Sector, Value: Agronegócio, Secondary Actions: Expand
123 menu
124 Por indicar
125 (selected) Agronegócio
126 Atividade sintética QA
127 Bens de Consumo e Franquias
128 Economia Azul
129 Energia
130 Energia e Mineração
131 Fintech
132 Imobiliário
133 Infraestruturas
134 Mercado Financeiro
135 Mineração
136 Sector sintético QA
137 Subsector sintético QA
138 Tecnologias de Informação
139 Turismo
140 container
141 text Subsector
142 pop up button (collapsed, settable) Subsector, Secondary Actions: Expand, Value: A → 01 — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS — histórico preservado
143 menu
144 Por indicar
145 (selected) A → 01 — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS — histórico preservado
146 container
147 text Atividade económica
148 pop up button (collapsed, settable) Value: A → 01 → 011 → 0112 → 01120 — CULTURA DE ARROZ — histórico preservado, Secondary Actions: Expand, Atividade económica A — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA → 01 — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS → 011 — CULTURAS TEMPORÁRIAS → 0112 — CULTURA DE ARROZ → 01120 — CULTURA DE ARROZ · Exemplar eBAU; edição normativa não determinada; divergência 600/579 aberta.
149 menu
150 Por indicar
151 (selected) A → 01 → 011 → 0112 → 01120 — CULTURA DE ARROZ — histórico preservado
152 text A — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA, FLORESTA E PESCA → 01 — AGRICULTURA, PRODUÇÃO ANIMAL, CAÇA E ACTIVIDADES DOS SERVIÇOS RELACIONADOS → 011 — CULTURAS TEMPORÁRIAS → 0112 — CULTURA DE ARROZ → 01120 — CULTURA DE ARROZ · Exemplar eBAU; edição normativa não determinada; divergência 600/579 aberta.
153 text Uma ou várias localizações
154 pop up button (collapsed, settable) Uma ou várias localizações, Value: Por indicar, ID: canonical.location_mode, Secondary Actions: Expand
155 menu
156 (selected) Por indicar
157 single
158 multiple
159 text Âmbito geográfico
160 pop up button (collapsed, settable) Âmbito geográfico, Value: Por indicar, ID: canonical.geographic_scope, Secondary Actions: Expand
161 menu
162 (selected) Por indicar
163 local
164 district
165 multi district
166 provincial
167 interprovincial
168 national
169 cross border
170 text Justificação territorial
171 text entry area (settable) Justificação territorial, ID: canonical.multi_district_rationale
172 container Localizações guardadas
173 text Localizações guardadas
174 checkbox (settable, integer) Description: QA contexto Cabo Delgado Ancuabe — 11/10/2026 coedição QA22, Value: 0
175 checkbox (settable, integer) Description: QA localização incompleta Portugal — 11/10/2026 coedição QA22, Value: 0
176 text Resumo executivo
177 text entry area (settable) Resumo executivo, ID: canonical.executive_summary
178 text Necessidade e proposta
179 text entry area (settable) Necessidade e proposta, ID: canonical.demand_statement
180 container canonical.demand_statement-length-help
181 text Descreva a necessidade e a finalidade da oportunidade. Para submeter: 100 a 2000 caracteres. Texto atual: 0 caracteres. Pode guardar o rascunho incompleto.
182 container Documentos guardados
183 text Documentos guardados
184 checkbox (settable, integer) Description: Documento sintético QA22 — ciclo documental 11/10/2026, Value: 0
185 container Evidências
186 text Evidências
187 button Adicionar linha
188 container Versões por idioma
189 text Versões por idioma
190 button Adicionar linha
191 text Visibilidade após publicação
192 pop up button (collapsed, settable) Visibilidade após publicação, Value: Por indicar, ID: canonical.visibility, Secondary Actions: Expand
193 menu
194 (selected) Por indicar
195 internal
196 authenticated
197 public
198 text Moeda
199 text entry area (settable) Moeda, ID: canonical.currency
200 text Data de revisão editorial
201 date field (settable) Data de revisão editorial, ID: canonical.review_due_date
202 container
203 stepper
204 stepper
205 stepper
206 pop up button Mostrar selecionador de data Mostrar selecionador de data
207 container Imagens guardadas
208 text Imagens guardadas
209 text Guarde primeiro em Recursos e regresse a este contrato.
210 text Declaração de veracidade
211 pop up button (collapsed, settable) Declaração de veracidade, Value: Por indicar, ID: canonical.truth_declaration, Secondary Actions: Expand
212 menu
213 (selected) Por indicar
214 Sim
215 Não
216 text Dimensão empresarial declarada (separada do setor)
217 text entry area (settable) Dimensão empresarial declarada (separada do setor), Value: Microempresa sintética QA, ID: canonical.enterprise_size
218 container Classificação multidimensional
219 heading Quatro dimensões da oportunidade, Value: 3
220 text Quatro dimensões da oportunidade
221 text Associação, publicação e ato externo têm estados separados. Localização ou proximidade não concedem licença, benefício, terreno ou capacidade. Dados ausentes permanecem por determinar. Os elos identificados como Modelo editorial não confirmam operadores, capacidade ou relações comerciais. O recorte CAE conserva cinco níveis; 600/579 permanece documentalmente aberto.
222 container Enquadramento territorial
223 text Enquadramento territorial
224 button Acrescentar relação — Enquadramento territorial
225 text Acrescentar relação —
226 text Enquadramento territorial
227 container Organização produtiva
228 text Organização produtiva
229 container Associação 3
230 container
231 text Associação 3
232 container
233 text Tipo
234 pop up button (collapsed, settable) Tipo, Value: Cadeia de valor, Secondary Actions: Expand
235 menu
236 Cluster
237 Projeto âncora
238 (selected) Cadeia de valor
239 Parque industrial — organização produtiva
240 container
241 text Referência existente
242 pop up button (collapsed, settable) Description: Referência existente, Value: Referência guardada, atualmente indisponível — b03f4ecb-e63b-5778-98f8-c2d2dc867c93, Secondary Actions: Expand
243 menu
244 Selecionar referência
245 (selected) Referência guardada, atualmente indisponível — b03f4ecb-e63b-5778-98f8-c2d2dc867c93
246 text A referência deixou de estar disponível para novas escolhas. A relação histórica permanece guardada; não selecione outro valor para a recuperar.
247 container
248 text Finalidade
249 pop up button (collapsed, settable) Finalidade, Value: Etapa da cadeia produtiva, Secondary Actions: Expand
250 menu
251 Selecionar finalidade
252 Localização
253 Abrangência documentada
254 Proximidade, sem pertença
255 Limite administrativo
256 Parcela referenciada
257 Conectividade e fluxos
258 Complementaridade produtiva
259 Especialização do cluster
260 Projeto âncora documentado
261 Localização na zona
262 Reconhecimento do regime
263 Admissão do empreendimento
264 Benefício específico
265 Operação do parque
266 Necessidade de financiamento
267 Pagamentos
268 Gestão de riscos
269 Instrumento financeiro
270 Serviço logístico
271 Ativo físico/capacidade
272 Atividade económica
273 (selected) Etapa da cadeia produtiva
274 container
275 text Estado solicitado
276 pop up button (collapsed, settable) Estado solicitado, Value: Preliminar, Secondary Actions: Expand
277 menu
278 Rascunho
279 (selected) Preliminar
280 Em validação
281 container
282 text Critérios
283 text entry area (settable) Critérios, Value: Correspondência delimitada ao exemplar e ao modelo editorial do lote 01.
284 container
285 text Justificação
286 text entry area (settable) Justificação, Value: QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
287 container
288 text Fonte identificada
289 text entry area (settable) Fonte identificada, Value: Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01.
290 container
291 text Artigo, página ou referência
292 text entry area (settable) Artigo, página ou referência, Value: A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA.
293 container
294 text Referência do ato externo
295 text entry area (settable) Referência do ato externo
296 container
297 text Etapa produtiva documentada
298 text entry area (settable) Etapa produtiva documentada, Value: Modelo editorial — Produção
299 container
300 text Documento de suporte
301 pop up button (collapsed, settable) Documento de suporte, Value: Por associar, se aplicável, Secondary Actions: Expand
302 menu
303 (selected) Por associar, se aplicável
304 Documento sintético QA22 — ciclo documental 11/10/2026
305 container
306 text Entidade competente
307 pop up button (collapsed, settable) Entidade competente, Value: Por determinar, Secondary Actions: Expand
308 menu
309 (selected) Por determinar
310 Entidade emissora sintética QA — sem competência real
311 container
312 text Estado do ato externo
313 pop up button (collapsed, settable) Estado do ato externo, Value: Não determinado, Secondary Actions: Expand
314 menu
315 (selected) Não determinado
316 Pendente
317 Ato de concessão documentado
318 Ato de recusa documentado
319 Caducado
320 container
321 text Divulgação após publicação editorial
322 pop up button (collapsed, settable) Divulgação após publicação editorial, Value: Pública: referência, fonte e citação, Secondary Actions: Expand
323 menu
324 Reservada
325 (selected) Pública: referência, fonte e citação
326 container
327 text Válida desde
328 date field (settable) Válida desde
329 container
330 stepper
331 stepper
332 stepper
333 pop up button Mostrar selecionador de data Mostrar selecionador de data
334 container
335 text Válida até
336 date field (settable) Válida até
337 container
338 stepper
339 stepper
340 stepper
341 pop up button Mostrar selecionador de data Mostrar selecionador de data
342 button Retirar esta associação do rascunho
343 button Acrescentar relação — Organização produtiva
344 text Acrescentar relação —
345 text Organização produtiva
346 container Regime regulatório
347 text Regime regulatório
348 button Acrescentar relação — Regime regulatório
349 text Acrescentar relação —
350 text Regime regulatório
351 container Atividade económica
352 text Atividade económica
353 container Associação 1
354 container
355 text Associação 1
356 container
357 text Tipo
358 pop up button (collapsed, settable) Tipo, Value: Subsector ou atividade, Secondary Actions: Expand
359 menu
360 Setor
361 (selected) Subsector ou atividade
362 container
363 text Referência existente
364 pop up button (collapsed, settable) Description: Referência existente, Value: Referência guardada, atualmente indisponível — af45b335-61a5-53da-a029-a8fab91cf624, Secondary Actions: Expand
365 menu
366 Selecionar referência
367 (selected) Referência guardada, atualmente indisponível — af45b335-61a5-53da-a029-a8fab91cf624
368 qa-level-0 → qa-level-1 → qa-level-2 — Atividade sintética QA
369 qa-level-0 → qa-level-1 — Subsector sintético QA
370 agronegocio — Agronegócio
371 energia — Energia e Mineração
372 turismo — Turismo
373 infraestruturas — Infraestruturas
374 economia-azul — Economia Azul
375 mercado-financeiro — Mercado Financeiro
376 qa-level-0 — Sector sintético QA
377 text A referência deixou de estar disponível para novas escolhas. A relação histórica permanece guardada; não selecione outro valor para a recuperar.
378 container
379 text Finalidade
380 pop up button (collapsed, settable) Finalidade, Value: Atividade económica, Secondary Actions: Expand
381 menu
382 Selecionar finalidade
383 Localização
384 Abrangência documentada
385 Proximidade, sem pertença
386 Limite administrativo
387 Parcela referenciada
388 Conectividade e fluxos
389 Complementaridade produtiva
390 Especialização do cluster
391 Projeto âncora documentado
392 Localização na zona
393 Reconhecimento do regime
394 Admissão do empreendimento
395 Benefício específico
396 Operação do parque
397 Necessidade de financiamento
398 Pagamentos
399 Gestão de riscos
400 Instrumento financeiro
401 Serviço logístico
402 Ativo físico/capacidade
403 (selected) Atividade económica
404 Etapa da cadeia produtiva
405 container
406 text Estado solicitado
407 pop up button (collapsed, settable) Estado solicitado, Value: Preliminar, Secondary Actions: Expand
408 menu
409 Rascunho
410 (selected) Preliminar
411 Em validação
412 container
413 text Critérios
414 text entry area (settable) Critérios, Value: Correspondência delimitada ao exemplar e ao modelo editorial do lote 01.
415 container
416 text Justificação
417 text entry area (settable) Justificação, Value: QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
418 container
419 text Fonte identificada
420 text entry area (settable) Fonte identificada, Value: Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01.
421 container
422 text Artigo, página ou referência
423 text entry area (settable) Artigo, página ou referência, Value: A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA.
424 container
425 text Referência do ato externo
426 text entry area (settable) Referência do ato externo
427 container
428 text Etapa produtiva documentada
429 text entry area (settable) Etapa produtiva documentada
430 container
431 text Documento de suporte
432 pop up button (collapsed, settable) Documento de suporte, Value: Por associar, se aplicável, Secondary Actions: Expand
433 menu
434 (selected) Por associar, se aplicável
435 Documento sintético QA22 — ciclo documental 11/10/2026
436 container
437 text Entidade competente
438 pop up button (collapsed, settable) Entidade competente, Value: Por determinar, Secondary Actions: Expand
439 menu
440 (selected) Por determinar
441 Entidade emissora sintética QA — sem competência real
442 container
443 text Estado do ato externo
444 pop up button (collapsed, settable) Estado do ato externo, Value: Não determinado, Secondary Actions: Expand
445 menu
446 (selected) Não determinado
447 Pendente
448 Ato de concessão documentado
449 Ato de recusa documentado
450 Caducado
451 container
452 text Divulgação após publicação editorial
453 pop up button (collapsed, settable) Divulgação após publicação editorial, Value: Pública: referência, fonte e citação, Secondary Actions: Expand
454 menu
455 Reservada
456 (selected) Pública: referência, fonte e citação
457 container
458 text Válida desde
459 date field (settable) Válida desde
460 container
461 stepper
462 stepper
463 stepper
464 pop up button Mostrar selecionador de data Mostrar selecionador de data
465 container
466 text Válida até
467 date field (settable) Válida até
468 container
469 stepper
470 stepper
471 stepper
472 pop up button Mostrar selecionador de data Mostrar selecionador de data
473 button Retirar esta associação do rascunho
474 container Associação 2
475 container
476 text Associação 2
477 container
478 text Tipo
479 pop up button (collapsed, settable) Tipo, Value: Subsector ou atividade, Secondary Actions: Expand
480 menu
481 Setor
482 (selected) Subsector ou atividade
483 container
484 text Referência existente
485 pop up button (collapsed, settable) Description: Referência existente, Value: Referência guardada, atualmente indisponível — 517ef71f-82a9-5233-afbf-741e6fe43dc6, Secondary Actions: Expand
486 menu
487 Selecionar referência
488 (selected) Referência guardada, atualmente indisponível — 517ef71f-82a9-5233-afbf-741e6fe43dc6
489 qa-level-0 → qa-level-1 → qa-level-2 — Atividade sintética QA
490 qa-level-0 → qa-level-1 — Subsector sintético QA
491 agronegocio — Agronegócio
492 energia — Energia e Mineração
493 turismo — Turismo
494 infraestruturas — Infraestruturas
495 economia-azul — Economia Azul
496 mercado-financeiro — Mercado Financeiro
497 qa-level-0 — Sector sintético QA
498 text A referência deixou de estar disponível para novas escolhas. A relação histórica permanece guardada; não selecione outro valor para a recuperar.
499 container
500 text Finalidade
501 pop up button (collapsed, settable) Finalidade, Value: Atividade económica, Secondary Actions: Expand
502 menu
503 Selecionar finalidade
504 Localização
505 Abrangência documentada
506 Proximidade, sem pertença
507 Limite administrativo
508 Parcela referenciada
509 Conectividade e fluxos
510 Complementaridade produtiva
511 Especialização do cluster
512 Projeto âncora documentado
513 Localização na zona
514 Reconhecimento do regime
515 Admissão do empreendimento
516 Benefício específico
517 Operação do parque
518 Necessidade de financiamento
519 Pagamentos
520 Gestão de riscos
521 Instrumento financeiro
522 Serviço logístico
523 Ativo físico/capacidade
524 (selected) Atividade económica
525 Etapa da cadeia produtiva
526 container
527 text Estado solicitado
528 pop up button (collapsed, settable) Estado solicitado, Value: Preliminar, Secondary Actions: Expand
529 menu
530 Rascunho
531 (selected) Preliminar
532 Em validação
533 container
534 text Critérios
535 text entry area (settable) Critérios, Value: Correspondência delimitada ao exemplar e ao modelo editorial do lote 01.
536 container
537 text Justificação
538 text entry area (settable) Justificação, Value: QA-PRIVATE-MARKER: relação sintética, sem operadores ou capacidade comercial confirmados.
539 container
540 text Fonte identificada
541 text entry area (settable) Fonte identificada, Value: Exemplar CAE 97ef68346803; programa v6 §543; modelo editorial CLU-01.
542 container
543 text Artigo, página ou referência
544 text entry area (settable) Artigo, página ou referência, Value: A/01/011/0112/01120; §543, aplicação editorial neste ensaio sintético QA.
545 container
546 text Referência do ato externo
547 text entry area (settable) Referência do ato externo
548 container
549 text Etapa produtiva documentada
550 text entry area (settable) Etapa produtiva documentada
551 container
552 text Documento de suporte
553 pop up button (collapsed, settable) Documento de suporte, Value: Por associar, se aplicável, Secondary Actions: Expand
554 menu
555 (selected) Por associar, se aplicável
556 Documento sintético QA22 — ciclo documental 11/10/2026
557 container
558 text Entidade competente
559 pop up button (collapsed, settable) Entidade competente, Value: Por determinar, Secondary Actions: Expand
560 menu
561 (selected) Por determinar
562 Entidade emissora sintética QA — sem competência real
563 container
564 text Estado do ato externo
565 pop up button (collapsed, settable) Estado do ato externo, Value: Não determinado, Secondary Actions: Expand
566 menu
567 (selected) Não determinado
568 Pendente
569 Ato de concessão documentado
570 Ato de recusa documentado
571 Caducado
572 container
573 text Divulgação após publicação editorial
574 pop up button (collapsed, settable) Divulgação após publicação editorial, Value: Pública: referência, fonte e citação, Secondary Actions: Expand
575 menu
576 Reservada
577 (selected) Pública: referência, fonte e citação
578 container
579 text Válida desde
580 date field (settable) Válida desde
581 container
582 stepper
583 stepper
584 stepper
585 pop up button Mostrar selecionador de data Mostrar selecionador de data
586 container
587 text Válida até
588 date field (settable) Válida até
589 container
590 stepper
591 stepper
592 stepper
593 pop up button Mostrar selecionador de data Mostrar selecionador de data
594 button Retirar esta associação do rascunho
595 button Acrescentar relação — Atividade económica
596 text Acrescentar relação —
597 text Atividade económica
598 text Tipo de investimento
599 text entry area (settable) Tipo de investimento, ID: canonical.opportunity_type
600 text Etapa de maturidade
601 pop up button (collapsed, settable) Etapa de maturidade, Value: Por indicar, ID: canonical.maturity_stage, Secondary Actions: Expand
602 menu
603 (selected) Por indicar
604 idea
605 concept
606 prefeasibility
607 feasibility
608 structured
609 investment ready
610 implementation
611 operational
612 container Modalidades de investimento
613 text Modalidades de investimento
614 button Adicionar linha
615 container Perfis de investidor
616 text Perfis de investidor
617 button Adicionar linha
618 container Produtos
619 text Produtos
620 button Adicionar linha
621 container Ativos
622 text Ativos
623 button Adicionar linha
624 container Insumos
625 text Insumos
626 button Adicionar linha
627 container Mercados
628 text Mercados
629 button Adicionar linha
630 text Vantagem competitiva
631 text entry area (settable) Vantagem competitiva, ID: canonical.competitive_advantage
632 container Emprego
633 text Emprego
634 text Tipo de emprego
635 text entry area (settable) Tipo de emprego, ID: canonical.employment.employment_type
636 text Empregos diretos
637 stepper (settable) Empregos diretos, ID: canonical.employment.direct_jobs
638 text indirect jobs
639 stepper (settable) indirect jobs, ID: canonical.employment.indirect_jobs
640 text female percentage
641 stepper (settable) female percentage, ID: canonical.employment.female_percentage
642 text youth percentage
643 stepper (settable) youth percentage, ID: canonical.employment.youth_percentage
644 container Impactos
645 text Impactos
646 button Adicionar linha
647 text Investimento total
648 stepper (settable) Investimento total, ID: canonical.total_investment
649 container Rubricas de investimento
650 text Rubricas de investimento
651 button Adicionar linha
652 container Financiamento assegurado
653 text Financiamento assegurado
654 button Adicionar linha
655 text Financiamento procurado
656 stepper (settable) Financiamento procurado, ID: canonical.funding_sought
657 container Indicadores financeiros
658 text Indicadores financeiros
659 text Valor atual líquido
660 stepper (settable) Valor atual líquido, ID: canonical.financial_indicators.npv
661 text Taxa interna de retorno (%)
662 stepper (settable) Taxa interna de retorno (%), ID: canonical.financial_indicators.irr
663 text Prazo de retorno (anos)
664 stepper (settable) Prazo de retorno (anos), ID: canonical.financial_indicators.payback_years
665 text Cenário identificado
666 text entry area (settable) Cenário identificado, ID: canonical.financial_indicators.scenario
667 text Horizonte (anos)
668 stepper (settable) Horizonte (anos), ID: canonical.financial_indicators.horizon_years
669 text Moeda
670 text entry area (settable) Moeda, ID: canonical.financial_indicators.currency
671 text Taxa de desconto (%)
672 stepper (settable) Taxa de desconto (%), ID: canonical.financial_indicators.discount_rate
673 text Modelo financeiro associado
674 pop up button (collapsed, settable) Modelo financeiro associado, Value: Por indicar, ID: canonical.financial_indicators.model_document_id, Secondary Actions: Expand
675 menu
676 (selected) Por indicar
677 Documento sintético QA22 — ciclo documental 11/10/2026
678 container Marcos
679 text Marcos
680 button Adicionar linha
681 container Licenças
682 text Licenças
683 button Adicionar linha
684 container Aspetos ambientais e sociais
685 text Aspetos ambientais e sociais
686 text Estado da avaliação
687 text entry area (settable) Estado da avaliação, ID: canonical.environmental_social.assessment_status
688 text Categoria ambiental
689 text entry area (settable) Categoria ambiental, ID: canonical.environmental_social.environmental_category
690 container social risks
691 text social risks
692 button Adicionar linha
693 text mitigation plan
694 text entry area (settable) mitigation plan, ID: canonical.environmental_social.mitigation_plan
695 container Riscos
696 text Riscos
697 button Adicionar linha
698 button Guardar contrato no rascunho
699 container Workflow interno
700 heading Workflow interno, Value: 2
701 text Workflow interno
702 text Guarde o contrato antes de submeter. Aprovação exige revisões especializadas desta versão; publicação exige outro utilizador autorizado. Uma decisão interna não substitui decisão externa.
703 text Aprovação interna confirma a revisão desta versão. Disponibilização restrita não aparece no catálogo público nem dá acesso a todas as contas. A publicação pública exige âmbito público e ação independente do Publicador; não representa uma decisão externa.
704 container
705 text Fundamentação
706 text entry area (settable) Fundamentação Explique o motivo desta ação: 20 a 1000 caracteres. Texto atual: 0 caracteres., ID: workflow-15-reason
707 text Explique o motivo desta ação: 20 a 1000 caracteres. Texto atual: 0 caracteres.
708 button Submeter para validação
709 button Solicitar arquivo
710 heading Acompanhamento interno — Rascunho, Value: 2
711 text Acompanhamento interno — Rascunho
712 text SLA: sem política/prazo aprovado; as tarefas podem ser preparadas em paralelo.
713 container Histórico de gestão
714 heading Histórico, Value: 2
715 text Histórico
716 container
717 text draft_updated · conta 21 · 2026-10-16 09:24:03.076892+00
718 container
719 text draft_updated · conta 21 · 2026-10-16 09:18:43.487495+00
720 container
721 text draft_updated · conta 21 · 2026-10-16 09:16:00.671322+00
722 container
723 text draft_updated · conta 21 · 2026-10-10 07:47:35.217431+00
724 container
725 text draft_updated · conta 21 · 2026-10-10 07:38:17.506402+00
726 container
727 text draft_updated · conta 21 · 2026-10-10 07:29:57.008307+00
728 container
729 text draft_updated · conta 22 · 2026-10-10 07:05:02.572703+00
730 container
731 text draft_created · conta 21 · 2026-10-10 07:04:58.405353+00
732 container Contacto de apoio ao investidor
733 link Description: Contactar Apoio ao Investidor, Value: 127.0.0.1:18531/apoio
734 container Notifications alt+T
735 container grammarly-integration
The focused UI element is 1 AXWebArea Editar oportunidade INV-MZ-GEN-1964172608177406 - InvesteMoz, URL: 127.0.0.1:18531/minhas-oportunidades/15/edit
@@ -0,0 +1,78 @@
from pathlib import Path
import json
out=Path(__file__).resolve().parent;q=Path(json.loads((out/'QA-ISOLAMENTO.json').read_text('utf-8'))['source'])
def edit(name,old,new):
p=q/name;t=p.read_text('utf-8');assert t.count(old)==1,(name,old[:80],t.count(old));p.write_text(t.replace(old,new),'utf-8')
edit('app/Services/OpportunityClassification.php',"return $kind === 'sector' ? $query->whereNull('deleted_at')->where('is_active', true) : $query->where('status', 'published');","return $kind === 'sector' ? $query->whereNull('deleted_at')->where('is_active', true) : app(EconomicReferenceCatalog::class)->constrain($query->where('status', 'published'), 'activity');")
edit('app/Services/OpportunityClassification.php',"return $query->where('data_classification', 'public');","return app(EconomicReferenceCatalog::class)->constrain($query->where('data_classification', 'public'), $kind);")
edit('app/Services/OpportunityClassification.php',"$targets[$kind] = $this->targets($kind)->orderBy($label)->get(['id', $label.' as label']);","$targets[$kind] = $kind === 'activity'\n ? app(EconomicReferenceCatalog::class)->activities()->map(fn ($r) => (object) ['id' => $r->id, 'label' => $r->display_label, 'code' => $r->code, 'level' => $r->level, 'path' => $r->path, 'source_version' => $r->source_version, 'edition' => $r->edition])\n : $this->targets($kind)->orderBy($label)->get(['id', $label.' as label']);")
edit('app/Services/OpportunityClassification.php',"if (! isset(self::TARGETS[$kind]) || ! $this->targets($kind)->where('id', (string) ($row['related_id'] ?? ''))->exists()) {","$previousRows = $record->exists ? (app(OpportunityManagement::class)->values($record)['canonical']['relations'] ?? []) : [];\n if (! isset(self::TARGETS[$kind]) || ! $this->canRetainReference($kind, $id, $row, $previousRows)) {")
anchor=' public function hash(array $row): string'
new=''' /** Exact persisted relation retention is not permission to choose a withdrawn target anew. */
public function canRetainReference(string $kind, string $id, array $row, array $previousRows): bool
{
if ($this->targets($kind)->where('id', $id)->exists()) { return true; }
if (! app(EconomicReferenceCatalog::class)->historicalTarget($kind, $id)) { return false; }
$content = fn ($r) => array_intersect_key($r, array_flip(['related_id', 'relation_type', 'classification']));
return collect($previousRows)->contains(fn ($old) => OpportunityCanonicalValue::hash($content($old)) === OpportunityCanonicalValue::hash($content($row)));
}
'''+anchor
edit('app/Services/OpportunityClassification.php',anchor,new)
edit('app/Services/ExistingBusinessClassification.php',"if (! app(OpportunityClassification::class)->targets($kind)->where('id', $row['related_id'])->exists()) {","if (! app(OpportunityClassification::class)->canRetainReference($kind, $row['related_id'], $row, $this->context($business)['relations'])) {")
# Public facts get safe path/version only; never copy metadata, actor, internal criteria or documents.
edit('app/Services/ExistingBusinessClassification.php',"'label' => $target->{OpportunityClassification::TARGETS[$kind][1]}, 'purpose'", "'label' => $target->{OpportunityClassification::TARGETS[$kind][1]}, 'target_code' => $target->code ?? null,\n 'reference_path' => $kind === 'activity' ? (app(EconomicReferenceCatalog::class)->activities()->firstWhere('id', $target->id)?->path ?? []) : [], 'purpose'")
edit('app/Services/OpportunityClassification.php',"'physical_category' => $target->physical_category ?? null,", "'reference_path' => $kind === 'activity' ? (app(EconomicReferenceCatalog::class)->activities()->firstWhere('id', $target->id)?->path ?? []) : [],\n 'physical_category' => $target->physical_category ?? null,")
p=q/'app/Services/OpportunityCanonicalContract.php';t=p.read_text('utf-8');start=t.index(" $sector = DB::table('sectors')->where('id', $payload['sector_id'])");end=t.index(" foreach (['internal_contact_id'",start)
t=t[:start]+''' $previous = app(OpportunityManagement::class)->values($record)['canonical'] ?? [];
$sameTaxonomy = ($previous['sector_id'] ?? null) === ($payload['sector_id'] ?? null)
&& ($previous['subsector_id'] ?? null) === ($payload['subsector_id'] ?? null)
&& ($previous['economic_activity_id'] ?? null) === ($payload['economic_activity_id'] ?? null);
$check(app(EconomicReferenceCatalog::class)->validHierarchy((int) $payload['sector_id'], $payload['subsector_id'] ?? null, $payload['economic_activity_id'] ?? null, $sameTaxonomy),
'economic_activity_id', 'Sector, subsector e atividade devem corresponder à hierarquia/versão publicada; os cinco níveis originais são conservados.');
'''+t[end:];p.write_text(t,'utf-8')
edit('app/Services/OpportunityCanonicalContract.php',"'activities' => DB::table('economic_activities')->where('status', 'published')->get(['id', 'parent_id', 'sector_id', 'label_pt_mz', 'catalog_version_id']),","'activities' => app(EconomicReferenceCatalog::class)->activities($record ? array_values(array_filter(array_intersect_key(app(OpportunityManagement::class)->values($record)['canonical'] ?? [], array_flip(['subsector_id', 'economic_activity_id'])))) : []),")
edit('app/Http/Controllers/Api/V1/ReferenceCatalogController.php',"$rules['sector_id'] = ['nullable', 'integer', 'exists:sectors,id'];","$rules['sector_id'] = ['nullable', 'integer', 'exists:sectors,id'];\n $rules['origin'] = ['nullable', 'in:portal,cae'];")
edit('app/Http/Controllers/Api/V1/ReferenceCatalogController.php',"$versionQuery = DB::table('reference_catalog_versions')->where('catalog_code', $catalog)->where('locale', 'pt-MZ');","$cae = $catalog === 'economic-activities' && ($data['origin'] ?? 'portal') === 'cae';\n $versionQuery = DB::table('reference_catalog_versions')->where('catalog_code', $cae ? 'economic-activities-cae' : $catalog)->where('locale', 'pt-MZ');\n if ($cae && ! app(\\App\\Services\\EconomicReferenceCatalog::class)->available()) { $versionQuery->whereRaw('false'); }")
edit('app/Http/Controllers/Api/V1/ReferenceCatalogController.php',"$items = collect($page->items())->map(fn (object $row): array => $this->present($catalog, (array) $row))->values();","$items = collect($page->items())->map(fn (object $row): array => $this->present($catalog, (array) $row))->values();\n if ($cae) {\n $paths = app(\\App\\Services\\EconomicReferenceCatalog::class)->activities()->keyBy('id');\n $items = $items->map(fn ($row) => [...$row, 'level' => $paths[$row['id']]->level, 'path' => $paths[$row['id']]->path, 'source_version' => $paths[$row['id']]->source_version, 'edition' => 'not_determined', 'divergence' => '600/579 documentalmente aberta']);\n }")
# The query/origin are in data (and its ETag); default portal response stays byte-compatible.
edit('resources/js/components/opportunity-canonical-fields.tsx',"sector_id: number;\n label_pt_mz: string;","sector_id: number | null;\n code?: string;\n level?: number | null;\n path?: { id: string; code: string; label: string }[];\n display_label?: string;\n historical_only?: boolean;\n source_version?: string | null;\n edition?: string | null;\n label_pt_mz: string;")
p=q/'resources/js/components/opportunity-canonical-fields.tsx';t=p.read_text('utf-8');start=t.index(" .filter((a) =>\n key === 'subsector_id'");end=t.index(" return (",start)
t=t[:start]+''' .filter((a) => {
if (a.id === value[key]) return true;
if (a.historical_only) return false;
if (a.level) {
return key === 'subsector_id'
? a.level === 2 && a.code === '01' && a.sector_id === Number(value.sector_id)
: a.level === 5 && a.code === '01120' && !!a.path?.some((p) => p.id === value.subsector_id);
}
return key === 'subsector_id'
? options.activities.some((root) => root.sector_id === Number(value.sector_id) && a.parent_id === root.id)
: a.parent_id === value.subsector_id;
})
.map((a) => ({ id: a.id, label: (a.display_label ?? a.label_pt_mz) + (a.historical_only ? ' — histórico preservado' : '') }));
'''+t[end:];p.write_text(t,'utf-8')
edit('resources/js/components/opportunity-canonical-fields.tsx'," {rows.map((r) => (\n <option key={r.id} value={r.id}>"," {rows.map((r) => (\n <option key={r.id} value={r.id}>") if False else None
# Put the path next to the activity control: visible without opening a native select.
needle=''' </select>
</label>
);
}
if (['locations', 'documents', 'images'].includes(key))'''
replacement=''' </select>
{key === 'economic_activity_id' && options.activities.find((a) => a.id === value[key])?.level && (
<p className="mt-1 text-sm" data-economic-path="five-levels">
{options.activities.find((a) => a.id === value[key])?.path?.map((p) => `${p.code} — ${p.label}`).join(' → ')}
{' · Exemplar eBAU; edição normativa não determinada; divergência 600/579 aberta.'}
</p>
)}
</label>
);
}
if (['locations', 'documents', 'images'].includes(key))'''
edit('resources/js/components/opportunity-canonical-fields.tsx',needle,replacement)
edit('resources/js/components/opportunity-classification.tsx',"targets: Record<string, { id: string | number; label: string }[]>;","targets: Record<string, { id: string | number; label: string; code?: string; level?: number | null; path?: { id: string; code: string; label: string }[]; source_version?: string | null; edition?: string | null }[]>;")
# Add a bounded explanation to the common editor (both consumers use it).
edit('resources/js/components/opportunity-classification.tsx',"'Associação, publicação e ato externo têm estados separados. Localização ou proximidade não concedem licença, benefício, terreno ou capacidade. Dados ausentes permanecem por determinar.';","'Associação, publicação e ato externo têm estados separados. Localização ou proximidade não concedem licença, benefício, terreno ou capacidade. Dados ausentes permanecem por determinar. Os elos identificados como Modelo editorial não confirmam operadores, capacidade ou relações comerciais. O recorte CAE conserva cinco níveis; 600/579 permanece documentalmente aberto.';")
print(json.dumps({'consumers_adapted':True,'active_changes':0,'private_QA_source':str(q)}))
@@ -0,0 +1,16 @@
<?php
$source='C:/Users/macbook/.config/investmoz/referencias-economicas-QA-20261016/source';
require dirname(__DIR__,2).'/vendor/autoload.php';
foreach(Dotenv\Dotenv::parse(file_get_contents($source.'/.env'))as$k=>$v)if($v!==null){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
foreach(['APP_BASE_PATH'=>$source,'APP_CONFIG_CACHE'=>$source.'/bootstrap/cache/config.php','APP_ROUTES_CACHE'=>$source.'/bootstrap/cache/routes-v7.php']as$k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
$loader=require $source.'/vendor/autoload.php';$loader->setPsr4('App\\',$source.'/app');$map=[];
foreach($loader->getClassMap()as$class=>$file)if(str_starts_with($class,'App\\')){$p=$source.'/app/'.str_replace('\\','/',substr($class,4)).'.php';if(is_file($p))$map[$class]=$p;}$loader->addClassMap($map);
$app=require $source.'/bootstrap/app.php';$app->useStoragePath($source.'/storage');$app->usePublicPath($source.'/public');
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.'.config('database.default'));
if($c['driver']!=='pgsql'||!empty($c['url'])||$c['host']!=='127.0.0.1'||(int)$c['port']!==55441||$c['database']!=='economic_references_20261016_test'||$app->configurationIsCached())throw new RuntimeException('Isolated QA required before providers');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$c['database'],'postgres','');if($pdo->query('SELECT current_database()')->fetchColumn()!==$c['database']||(int)$pdo->query('SELECT inet_server_port()')->fetchColumn()!==55441)throw new RuntimeException('Actual QA identity');
$app->afterBootstrapping(Illuminate\Foundation\Bootstrap\LoadConfiguration::class,function()use($source){config(['app.env'=>'testing','inertia.ssr.enabled'=>false,'suitecrm.enabled'=>false,'investmoz_ai.enabled'=>false,'portal.notifications_enabled'=>false,'portal.profile_access_enabled'=>true,'portal.profile_administration_enabled'=>true,'existing-business.enabled'=>true,'existing-business.compatibility_shadow'=>false,'filesystems.disks.local.root'=>$source.'/storage/app/private','session.driver'=>'file','session.files'=>$source.'/storage/framework/sessions','view.compiled'=>$source.'/storage/framework/views','cache.default'=>'array']);});
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
if(!str_starts_with(str_replace('\\','/',(new ReflectionClass(App\Models\ExistingBusiness::class))->getFileName()),$source.'/app/'))throw new RuntimeException('Private QA source required');
$target=['database'=>$c['database'],'port'=>55441];
@@ -0,0 +1,15 @@
<?php
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
$record=App\Models\Opportunity::findOrFail(16);$values=app(App\Services\OpportunityManagement::class)->values($record);
$reference=base_path().'/NOT-USED';$reference=dirname(__DIR__,2).'/storage/app/private/investmoz-v2/portal-audit/portal-stability-source-20261011_083742/storage/app/private';
$files=[];
foreach(['documents','images']as$kind)foreach($values['canonical'][$kind]??[]as$id){
$resource=DB::table('opportunity_'.$kind)->where('id',$id)->where('opportunity_id',16)->first();$doc=DB::table('documents')->where('id',$resource->document_id)->first();
$from=$reference.'/'.$doc->storage_key;if(!is_file($from))throw new RuntimeException('Missing existing synthetic original');$raw=file_get_contents($from);$bytes=$doc->storage_encryption==='laravel'?Crypt::decryptString($raw):$raw;
if(hash('sha256',$bytes)!==trim($doc->sha256))throw new RuntimeException('Original mismatch');$to=storage_path('app/private/'.$doc->storage_key);if(!is_dir(dirname($to)))mkdir(dirname($to),0700,true);file_put_contents($to,$raw);
$files[]=['resource_id'=>$id,'name'=>$doc->file_name,'hash'=>trim($doc->sha256),'existing_clean'=>$doc->malware_scan_status==='clean'];
}
file_put_contents(dirname($source).'/canonical-16-before.json',json_encode(['record'=>$record->getRawOriginal(),'values'=>$values],JSON_THROW_ON_ERROR));
echo json_encode(['id'=>16,'slug'=>$record->slug,'existing_files'=>$files,'canonical_keys'=>array_keys($values['canonical']),'relations'=>$values['canonical']['relations']??[]],JSON_UNESCAPED_UNICODE);
@@ -0,0 +1,15 @@
<?php
ini_set('zend.exception_ignore_args','1');
require __DIR__.'/boot-QA.php';
Illuminate\Support\Facades\Auth::setUser(App\Models\User::findOrFail(24));
request()->setUserResolver(fn () => App\Models\User::findOrFail(24));
$o=App\Models\Opportunity::findOrFail(16);if($o->status!=='draft')throw new RuntimeException('Existing isolated draft required');
$contract=app(App\Services\OpportunityCanonicalContract::class);
try{$snapshot=$contract->validateSubmission($o);$contract->validatePublication($snapshot);}catch(Illuminate\Validation\ValidationException $e){echo json_encode(['validation_errors'=>$e->errors()],JSON_UNESCAPED_UNICODE);exit(1);}
$ctx=$o->workflow_context??[];$ctx['submission']=$snapshot;$gates=[];
foreach($contract->gates($o)as$gate)$gates[$gate]=['decision'=>'approved','hash'=>$snapshot['hash'],'actor_id'=>24,'at'=>now()->toIso8601String(),'reason'=>'Synthetic QA precondition, not a replay or acceptance of approval workflow.'];
$ctx['approval']=['hash'=>$snapshot['hash'],'actor_id'=>24,'gates'=>$gates,'at'=>now()->toIso8601String()];$ctx['working_state']='approved';
$ctx['economic_reference_QA_fixture']=['scope'=>'Publication preconditions only in isolated clone; reviews/approval are fixtures, not observed workflow decisions.','original_status'=>'draft'];
$o->workflow_context=$ctx;$o->save();
file_put_contents(__DIR__.'/CANONICAL-PUBLICATION-PRECONDITIONS.json',json_encode(['id'=>16,'scope'=>'Synthetic approval preconditions; only classification confirmation and explicit publisher action are observed in this increment.','snapshot_hash'=>$snapshot['hash'],'gates'=>array_keys($gates),'active_changes'=>0],JSON_PRETTY_PRINT));
echo json_encode(['synthetic_preconditions_ready'=>true,'hash'=>$snapshot['hash'],'etag'=>app(App\Services\OpportunityManagement::class)->etag($o)]);
@@ -0,0 +1,21 @@
<?php
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
$o=App\Models\Opportunity::findOrFail(16);$before=$o->getRawOriginal();$v=app(App\Services\OpportunityManagement::class)->values($o);$p=$v['canonical'];
if($o->status!=='draft'||isset($p['images']))throw new RuntimeException('Preserve existing test state');
$image=DB::table('opportunity_images')->where('opportunity_id',56)->whereNull('deleted_at')->first();if(!$image)throw new RuntimeException('Prepared synthetic image required');
$meta=json_decode($image->payload,true);$files=[$image->document_id];foreach($meta['derivatives']??[]as$d)$files[]=$d['document_id'];
$reference=dirname(__DIR__,2).'/storage/app/private/investmoz-v2/portal-audit/portal-stability-source-20261011_083742/storage/app/private';$copies=[];
foreach(array_unique($files)as$id){$doc=DB::table('documents')->where('id',$id)->first();$from=$reference.'/'.$doc->storage_key;$raw=file_get_contents($from);$bytes=$doc->storage_encryption==='laravel'?Crypt::decryptString($raw):$raw;
if(hash('sha256',$bytes)!==trim($doc->sha256)||$doc->malware_scan_status!=='clean')throw new RuntimeException('Existing synthetic image integrity');$to=storage_path('app/private/'.$doc->storage_key);if(!is_dir(dirname($to)))mkdir(dirname($to),0700,true);file_put_contents($to,$raw);$copies[]=['document'=>$id,'name'=>$doc->file_name,'hash'=>trim($doc->sha256)];}
$new=(array)$image;$new['id']=(string)Illuminate\Support\Str::uuid();$new['opportunity_id']=16;$new['created_by']=21;$new['created_at']=$new['updated_at']=now();$new['version']=1;
$meta['is_cover']=true;$new['payload']=json_encode($meta,JSON_THROW_ON_ERROR);
DB::table('opportunity_images')->insert($new);
$p['images']=[$new['id']];$p['visibility']='public';
foreach($p['milestones']as&$milestone){$milestone['start_date']??='2026-11-01';$milestone['end_date']??='2026-12-01';$milestone['responsible_name']??='Responsável sintético QA';}unset($milestone);
foreach($p['relations']as&$row)foreach(['external_act_reference','production_stage']as$key)if(($row['classification'][$key]??null)===null)unset($row['classification'][$key]);unset($row);
$v['canonical']=$p;$o->management_draft=$v;$o->save();
file_put_contents(dirname($source).'/canonical-fixture-completion-before.json',json_encode($before,JSON_THROW_ON_ERROR));
file_put_contents(__DIR__.'/CANONICAL-FIXTURE-COMPLETION.json',json_encode(['id'=>16,'source_image_opportunity'=>56,'copies'=>$copies,'new_document_uploads'=>0,'new_resource_links'=>1,'scope'=>'Only isolated clone fixture: supply missing milestone metadata and reuse existing synthetic image for public projection; no claims about previous workflow or historical legacy content.','approval_fixture'=>false,'active_changes'=>0],JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
echo json_encode(['fixture_only'=>true,'synthetic_originals_reused'=>count($copies),'new_document_uploads'=>0]);
@@ -0,0 +1,2 @@
<?php
require __DIR__.'/boot-QA.php';$o=App\Models\Opportunity::findOrFail(16);$v=app(App\Services\OpportunityManagement::class)->values($o);if(isset($v['canonical']['review_due_date']))throw new RuntimeException('Preserve date');$v['canonical']['review_due_date']='2027-01-15';$o->management_draft=$v;$o->save();echo 'Synthetic future review date set in clone only.';
@@ -0,0 +1,171 @@
from pathlib import Path
import json,hashlib,shutil,datetime,subprocess,zipfile
out=Path(__file__).resolve().parent;root=out.parents[1];private=Path('C:/Users/macbook/.config/investmoz/referencias-economicas-QA-20261016');source=private/'source';review=out/'para-revisao';review.mkdir(exist_ok=True)
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
state=json.loads((out/'CANDIDATE-STATE.json').read_text('utf-8'));verify=json.loads((out/'VERIFICACAO-LOCAL.json').read_text('utf-8'));http=json.loads((out/'HTTP-QA.json').read_text('utf-8'));lot=json.loads((out/'MANIFESTO-LOTE.json').read_text('utf-8'));candidate=verify['candidate'];assert candidate.endswith(state['code_hash'][:12])
retained=['app/Services/EconomicReferenceCatalog.php','app/Services/OpportunityCanonicalContract.php','app/Services/OpportunityClassification.php','app/Services/ExistingBusinessClassification.php','app/Http/Controllers/Api/V1/ReferenceCatalogController.php','resources/js/components/opportunity-canonical-fields.tsx','resources/js/components/opportunity-classification.tsx','database/migrations/2026_10_16_120000_extend_economic_reference_hierarchy.php','database/data/economic-references-lot-01.json']
application=[]
for name in state['files']:
application.append({'path':name,'sha256':sha(source/name),'bytes':(source/name).stat().st_size,'before_sha256':sha(root/name) if (root/name).is_file() else None,'preflight':'match_previous_hash' if (root/name).is_file() else 'must_be_absent','compatible_rollback':'retain' if name in retained else ('restore_fresh_previous' if (root/name).is_file() else 'remove_only_if_candidate_hash_matches')})
build=[{'path':p.relative_to(source).as_posix(),'sha256':sha(p),'bytes':p.stat().st_size}for p in sorted((source/'public/build').rglob('*'))if p.is_file()]
originals=[]
for s in lot['sources']:
p=source/'storage/app/private/investmoz-v2/economic-references/lot-01'/s['relative_path'];assert sha(p)==s['sha256'];originals.append({'path':p.relative_to(source).as_posix(),'sha256':sha(p),'bytes':p.stat().st_size,'disclosure':'private retained exemplar only; never publish original'})
manifest={'candidate':candidate,'revision':'QA01','code_hash':state['code_hash'],'data_manifest_sha256':state['manifest_sha256'],'application':application,'build':build,'private_originals':originals,'counts':verify['counts'],'references':{'catalogs':1,'CAE_nodes':5,'editorial_stages':5,'editorial_links':4,'total':15},'active_authorized':False,'compatible_rollback':{'retained_artifacts':retained,'retained_functional_sources':7,'restore':['routes/web.php'],'remove':['app/Services/EconomicReferenceInstallation.php','app/Http/Controllers/EconomicReferenceController.php','resources/js/pages/management/economic-references.tsx'],'build':'retain the entire coherent candidate build; operational page module becomes unreachable after route removal','schema':'retain migration, ledger and all new references/decisions after usage'}}
(review/'MANIFESTO-ENTREGA.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n','utf-8');shutil.copy2(out/'MANIFESTO-LOTE.json',review/'MANIFESTO-LOTE.json')
filetable='\n'.join(f"| `{r['path']}` | {'Substituição' if r['before_sha256'] else 'Novo'} | {r['compatible_rollback']} |"for r in application)
report=f'''# Referências económicas e cadeia de valor em QA
Candidata **{candidate}**, preparação concluída em QA isolada. O ativo não foi alterado e não houve ligação à sua base. O incremento cobre somente o ramo CAE A/01/011/0112/01120 e o modelo editorial CLU-01, nos consumidores existentes.
## Convenções e rastreabilidade
Divisão 01 como subsector e subclasse 01120 como atividade apenas neste recorte. Os cinco níveis, SELF_ID, códigos textuais, pais, linhas do exemplar e hash/versão permanecem no manifesto. O nó A não é equiparado integralmente ao setor Agronegócio: sector_id nulo na secção e setor 1 nos quatro descendentes. A edição normativa continua não determinada. A divergência 600/579 é documental e permanece aberta. A data valid_from do catálogo regista disponibilidade desta versão no portal, não vigência normativa presumida.
Os cinco elos e quatro ligações no CLU-01 existente são apresentados como modelo editorial, sem operadores, capacidades, direitos ou relações comerciais confirmados. Não foram criados setores, clusters, oportunidades ou anúncios. Os quatro exemplares de suporte são conservados privadamente; esta candidata não os publica na biblioteca.
## Resultado das provas dirigidas
| Prova | Resultado |
|---|---|
| Arranque e isolamento | Clone restaurado economic_references_20261016_test:55441, servidor 18531; guarda de identidade antes dos providers |
| Instalação nominal | POST autenticado pelo titular QA27 da dupla existente; gestão normal QA2 não consegue instalar o esquema |
| Prévia e importação | Prévia sem escrita de referências; 15 ausências importadas privadamente; repetição da mesma chave e nova importação reutilizam os mesmos UUID |
| Scan e publicação | ClamAV real nos quatro exemplares e manifesto; publicação expressa posterior, distinta da importação |
| Recusas | Ator/manifesto arbitrários, hash incorreto, manifesto alterado, bytes divergentes, conflito de conteúdo, Auditor, âmbito estranho e sessão sem MFA |
| CAE e consumidores anteriores | Cinco níveis recuperados pela API hierárquica; resposta editorial anterior igual; quatro nós no mesmo setor sem unicidade indevida |
| /negocios | Mesmo UUID no clone publicado/v12 de partida; três relações preparadas, confirmadas por QA24 e divulgadas por QA25; conteúdo e workflow preservados |
| Cadastro canónico | Oportunidade existente 16; atividade e cadeia recuperadas, confirmação independente, publicação HTTP expressa por QA25 |
| Pesquisa pública | Atividade + cadeia combinadas nos dois consumidores; caso positivo e negativo; dados de suporte, justificação e decisões privadas ausentes |
| Retirada e recuperação | Retirada expressa oculta as novas referências e relações públicas; conserva histórico e seletores; só republicação expressa as repõe |
| Reversão após uso | Serviço anterior e rotas anteriores executados em QA; edição HTTP conserva taxonomia, relações e decisões; down destrutivo recusado |
| Preservação | 184 verificações de IDs, dados anteriores, papéis e QA de referência; original 172aa874-98fc-4bf6-b78f-d2e9a386d345 permanece publicado/v12 |
| Compilação | TypeScript, nove lints PHP e build passaram; 162 ficheiros, referências de assets verificadas |
HTTP-QA.json reúne **{len(http['checks'])} verificações** e **{len(http['events'])} pedidos**, incluindo recusas, observações e tentativas de diagnóstico. Não são {len(http['events'])} casos de aceitação distintos. REVERSAO-QA.json tem 13 verificações dirigidas; PRESERVACAO-QA.json tem 184. Há observação visual desktop das duas projeções, seletores recuperados, instalador e referências retiradas. Não houve nova ronda dos 12 critérios aceites.
## Ajustes encontrados durante a execução
Acrescentado ExistingBusinessClassification.php ao mapa inicial de 12 artefactos: a retenção de relações retiradas também precisa de funcionar no suplemento de /negocios. São agora **13 artefactos: 11 fontes, uma migration e um manifesto**, sete substituições e seis ficheiros novos, além da compilação. A reversão conserva sete fontes funcionais, em vez de seis.
A repetição de importação após publicação foi corrigida para distinguir referências criadas pelo próprio importador de referências públicas anteriores de outra origem. A retirada funciona após repetição; referências públicas alheias ao lote continuam protegidas. Uma taxonomia retirada não pode ser introduzida por um novo save e depois validada como se fosse histórica. Os seletores mostram a relação guardada e o motivo da indisponibilidade, sem pedir ao utilizador que volte a selecionar ou guardar para recuperar valores.
As primeiras verificações foram retomadas pontualmente após corrigir expectativas do instrumento: a API devolve cada nível por parent_id, as linhas privadas envolvem relation e uma sessão MFA expirou durante a prova. As provas finais usam a revisão identificada no manifesto; não se repetiram percursos aceites.
## Limitações concretas
1. Os cinco nós não demonstram completude CAE nem reconciliam 600/579 ou a edição normativa. Não generalizar 01/01120 a outros setores.
2. O caso canónico usa o rascunho sintético existente 16. As pré-condições editoriais de aprovação são fixtures isolados, não novas decisões observadas. Foram completados metadados de marcos/data e reutilizada uma imagem sintética já existente para tornar possível observar a projeção pública. A confirmação das três relações e a ação HTTP do Publicador foram reais. Não se repetiu nem se declara reaceite o workflow integral.
3. O save canónico de compatibilidade foi persistido no rascunho secundário 15. O save pelo editor anterior de negócios foi exercido no UUID legível do clone, com estado editável preparado numa transação revertida no fim. Demonstra conservação do conteúdo legível e do suplemento, não recuperação dos rascunhos legados cuja chave pré-QA falta, nem nova transição funcional para edição.
4. A reversão é parcial e compatível: mantém schema, dados, sete fontes funcionais, manifesto e build coerente. A publicação não é retirada só por trocar código. Reutilização de referências públicas de outra origem exige reconciliação específica antes da retirada; este lote foi provado com as 15 referências inicialmente ausentes.
5. Sem ensaio volumétrico. A operação autenticada futura foi demonstrada em QA; backup/restauro fresco, sessão real e decisão do ativo continuam necessários na execução futura.
## Saldo e estimativa
Preparação QA concluída, saldo funcional e operacional QA **zero** neste recorte. As 12–18 h iniciais eram estimativa funcional; DOC01 somou 2–4 h para o mecanismo operacional, total 14–22 h. O ficheiro adicional de compatibilidade foi absorvido nesse trabalho, sem novo aumento de previsão. Não são horas ainda por executar.
Disponibilização futura: **2–4 h**, separadas: 45–90 min para preflight/backup/restauro/arranque, 20–40 min para fontes/build e instalação nominal, 25–50 min para importação/scan/publicação e 30–60 min para conferência operacional/recibo. As parcelas somam 120–240 min. Dependem da janela e dos intervenientes já autorizados, não de novos papéis ou cadastros.
Mesma matriz, sete requisitos complementados sem alterar estados ou critérios originais. B, COUNTRY02, entregas anteriores e a observação UUID no ativo não demonstrada/não bloqueante permanecem nos estados atuais. Ficha integral dos parques, duplicados e regulação Fintech continuam separados. A referência económica geral não é encerrada por este ramo. A próxima decisão é a disponibilização delimitada descrita na proposta única.
'''
(review/'RELATORIO-QA.md').write_text(report,'utf-8')
proposal=f'''# Proposta única à Tempo
Submeter à decisão **{candidate}**, código SHA-256 `{state['code_hash']}` e manifesto de dados SHA-256 `{state['manifest_sha256']}`. Preparação QA concluída; **não existe autorização de alteração do ativo para esta candidata**.
## Decisão concreta proposta
Autorizar, numa única entrega, os 13 artefactos e os 162 ficheiros de compilação identificados no manifesto/recibo, com backup/restauro fresco e reversão compatível. Pelo caminho autenticado `/management/economic-references/lot-01`, instalar somente a migration 2026_10_16_120000_extend_economic_reference_hierarchy, se ausente e coerente; importar privadamente somente as referências ausentes; verificar scan/metadados e publicar expressamente as 15 referências: um catálogo, cinco nós CAE, cinco elos editoriais e quatro ligações.
A migration remove apenas economic_activities_sector_uq, cria índice não único sector_id, permite sector_id nulo e acrescenta metadata jsonb. Mantém os IDs, FKs, unicidade por catálogo/código e a imutabilidade dos registos publicados. Não inclui migrations pendentes de outros módulos.
Aceitar o uso de divisão 01/subclasse 01120 apenas neste recorte e dos cinco elos como modelo editorial, mantendo aberta a divergência documental 600/579 e a edição normativa. Publicação das referências não publica documentos originais nem associa investimentos. **Não classificar anúncios reais, não divulgar relações de negócio, não transportar fixtures QA, não criar ou alterar grants, flags, setores ou clusters.** Preservar B, COUNTRY02, documentos, permissões, classificações, dados e histórico anteriores.
Os limites de prova são os descritos no relatório: pré-condições editoriais canónicas sintéticas, ensaio de edição legado transacional, ausência de recuperação do conteúdo legado cifrado e de volume, e reversão parcial após uso. A correção de retirada depois de importação repetida integra esta revisão. O acréscimo de ExistingBusinessClassification.php fecha a compatibilidade do segundo consumidor, sem nova regra organizacional.
## Dependências já resolvidas e restantes
Implementados e demonstrados em QA: instalador nominal, prévia, importação privada, scan real, repetição, publicação, retirada, filtros e os dois consumidores. Quatro originais privados por hash acompanham o pacote, com destino privado explícito. Não há importação documental em falta a descobrir depois da aceitação.
Na execução futura faltam somente decisão específica deste pacote, janela, backup/restauro fresco do destino e sessão real já autorizada. Schema usa os titulares de instalação da dupla existente; importação/publicação usam gestão autorizada com MFA. O recibo QA não substitui a prova fresca do ativo. Preflight exige **sete hashes anteriores e seis ausências**, mais o conjunto do build anterior; qualquer diferença exige reconciliação antes da troca, sem sobrescrever dados ou fontes divergentes.
Previsão operacional 2–4 h, discriminada no relatório. Nenhuma ronda funcional aceite será repetida. A conferência no ativo será de arranque, prévia/recibos, referências públicas novas e preservação; sem guardar investimentos. Parques, duplicados e regulação Fintech mantêm-se abertos, e o restante CAE aguarda reconciliação documental.
## Artefactos a decidir
| Ficheiro | Entrega | Reversão após uso |
|---|---|---|
{filetable}
O recibo confirma hashes dos documentos, fontes, build, exemplares e ZIP verificado localmente por CRC e por entrada. Esta proposta apresenta um resultado revisável; não regista aceitação visual ou inspeção do ZIP pela Tempo.
'''
(review/'PROPOSTA-UNICA-TEMPO.md').write_text(proposal,'utf-8')
procedure=f'''# Procedimento exato de disponibilização
Aplicável somente após decisão expressa da Tempo sobre **{candidate}**. Alvo previsto: aplicação `C:\\laragon\\www\\portal-investidor`, base `investemoz:5432`, nunca a QA 18531/55441. Este procedimento não foi executado no ativo nesta preparação.
## 1 Conferir a revisão e o destino sem escrita
Verificar o SHA do ZIP contra RECIBO-INTEGRIDADE.json, CRC e SHA de cada entrada contra MANIFESTO-INTEGRIDADE.json interno. Conferir os 13 artefactos contra MANIFESTO-ENTREGA.json: sete hashes anteriores e seis ausências. Conferir integralmente o build anterior e as três proteções .env/composer.lock/package-lock.json da fotografia do destino; não copiar ficheiros QA .env, cache, credenciais, sessões, fixtures ou dados de negócio.
Pelo diagnóstico autenticado existente, confirmar current_database()/inet_server_port(), ledger e esquema. Estado prévio previsto: economic_activities_sector_uq existente, sector_id NOT NULL, metadata e novo índice ausentes. Se já instalado, os cinco elementos precisam de ser coerentes: ledger nominal presente, metadata presente, constraint ausente, sector nullable e índice presente. A prévia recusa drift, identidade/versão divergente, exemplar em falta ou hash diferente. Nenhum nome semelhante permite associar um mestre.
Registar decisão, revisão, sessão responsável e hash do manifesto. A interface resolve o ator pela sessão; não recebe actor_id nem caminho/manifesto arbitrário. A dupla autorizada para DDL é a existente no destino, não os números de contas sintéticas QA.
## 2 Preparar backup e restauro frescos
Usar o mecanismo de backup/restauro já existente, imediatamente antes da execução: dump completo do destino e cópia fresca das fontes/build/configurações/ficheiros privados afetados, com hashes, ledger e contagens. Restaurar em base nova com sufixo _test na instância isolada 55441. Confirmar identidade antes dos providers, conteúdo/ficheiros e arranque HTTP em leitura. Não restaurar sobre a QA de referência nem sobre dados ativos posteriores. Manter a cache de dados.
Preparar readiness.json privado a partir dessas provas e da decisão, com timestamp até 24 h antes da operação, paths/hashes reais do dump e do backup de ficheiros, alvo ativo, alvo do restauro isolado, code_hash `{state['code_hash']}`, manifest_sha256 `{state['manifest_sha256']}`, restore_verified, files_verified, qa_passed e compatibility_verified. active_authorization contém decision_record, os mesmos dois hashes e apenas operations autorizadas: schema/import/publish/withdraw. A janela de 24 h é uma guarda técnica de frescura, não um novo papel ou regra organizacional; se expirar, renovar a prova em vez de contornar a guarda.
O formato completo e o verificador estão em EconomicReferenceInstallation::evidence. Não marcar qualquer confirmação verdadeira sem a prova correspondente. Nesta preparação não se produziu readiness ativo nem se fez backup da base ativa.
## 3 Entregar fontes e compilação em manutenção
Executar `php artisan down` no destino confirmado. Copiar apenas os 13 artefactos para os caminhos relativos do manifesto. Trocar o conjunto completo public/build pelos 162 ficheiros da compilação, com cópia anterior fresca; validar resolução absoluta dentro do diretório public/build antes de qualquer movimentação. Conferir todos os hashes após copiar.
Colocar os quatro exemplares nos caminhos privados exatos do manifesto, preservando qualquer ficheiro idêntico; divergência não é sobrescrita. Não criar registos na biblioteca nem URLs de download público. As fontes não dependem de DDL nova para continuar a servir o catálogo anterior; esse estado intermédio foi observado no clone antes da instalação nominal, e a adaptação conserva os consumidores anteriores.
Se necessário pelas caches presentes, executar **somente** `php artisan config:clear`, `php artisan route:clear` e `php artisan view:clear`. Não usar optimize:clear nem cache:clear. Não executar migrate genérico, db:seed, importadores documentais, npm no destino ou comandos de outras entregas. Reiniciar/recarregar o processo PHP conforme o serviço real e conferir a revisão efetivamente servida. Na troca de rotas QA houve uma resposta transitória com rotas anteriores, resolvida na leitura seguinte; a causa não foi isolada e não se atribui uma causa demonstrada ao bytecode.
## 4 Sair de manutenção e instalar pela ação autenticada
Executar `php artisan up` antes de abrir o instalador. Entrar com a conta real autorizada e concluir MFA na própria sessão. Abrir `/management/economic-references/lot-01`; conferir alvo, code_hash, manifesto, identidades e motivos. Todas as fases mostram disponibilidade própria. Não está previsto executar a interface durante manutenção.
Para esquema, o titular existente da dupla clica **Instalar apenas o esquema**, com motivo e confirmação. A ação POST `/management/economic-references/lot-01/schema` executa somente a migration nominal se ausente; sem dados importados. Guardar o recibo e conferir ledger/schema. Se estiver coerentemente instalado, a repetição não reinstala. Não atribuir privilégios para desbloquear uma conta.
## 5 Importação privada com scan e repetição
Gestão autorizada com MFA, na mesma página, abre nova prévia após a instalação. Confirmar as 15 linhas: inserir ausências, reutilizar identidades/versões idênticas, recusar conflitos. Clicar **Importar referências privadamente**. A ação POST `/import` analisa efetivamente o manifesto e os quatro exemplares pelo scanner configurado, confere novamente bytes e grava referências privadas numa transação com recibo/auditoria. As fontes originais continuam privadas.
Guardas: hash HMAC ligado ao ator/sessão/operação/estado, CSRF, MFA atual, autorização efetiva, bloqueio do lote e nova conferência após locks. Sem scan clean ou com drift, a fase falha com motivo; não publica nem aplica lote parcial. O botão **Repetir pedido anterior, sem duplicar** reutiliza a mesma chave/payload; obtém o recibo original. Nova importação usa nova prévia/chave e reutiliza os UUID existentes sem duplicar ou substituir dados. Uma repetição não retira nem repete uma publicação por si própria.
## 6 Publicação expressa das referências
Só após importação integral e scan/metadados conferidos, obter nova prévia e clicar **Publicar expressamente as referências**. POST `/publish` exige confirmação própria, novo scan e prova fresca; publica apenas as referências do manifesto. Catálogo/CAE passam de draft a published; elos/ligações do lote a public. Não publica exemplares originais, oportunidades, relações preparadas, nem uma decisão comercial.
Guardar recibo e conferir contagens/UUID. API pública `/api/v1/catalogs/economic-activities?origin=cae` mostra A; cada parent_id recupera o nível seguinte até 01120. A API sem origin conserva o catálogo editorial anterior. Os seletores mostram a divisão 01, a subclasse 01120 e os cinco níveis; os elos mantêm o rótulo Modelo editorial. Não generalizar convenções ou preencher associações reais neste passo.
## 7 Conferência operacional e fecho
Conferir apenas GET/arranque/assets, revisão servida, prévia/recibos, cinco níveis novos e os elos editoriais consultáveis. Conferir hashes de fontes/build e preservação dos IDs/dados anteriores, B, COUNTRY02, documentos, papéis, classificações e histórico. Não criar anúncio para teste, não guardar um investimento e não repetir os 12 critérios ou os percursos aceites. Registar limitações e o recibo final no mesmo registo/matriz.
Em caso de erro, seguir REVERSAO-COMPATIVEL.md. A decisão futura deve abranger expressamente a disponibilização dos 13 artefactos/build, instalação nominal, importação privada e publicação das 15 referências, com backup/restauro fresco e reversão; a autorização QA atual não abrange essas ações no ativo.
'''
(review/'PROCEDIMENTO-EXATO.md').write_text(procedure,'utf-8')
rollback='''# Reversão parcial compatível após utilização
Esta reversão preserva referências, relações, decisões, histórico e uma edição posterior pelo serviço anterior. Não repõe integralmente todos os ficheiros anteriores nem executa down depois de uso.
1. Com a camada operacional ainda presente, abrir a prévia autenticada e, se a decisão de reversão incluir retirada, executar expressamente **Retirar a disponibilização do lote**. A retirada é auditada e separada da troca de código. Preserva os seis registos imutáveis publicados de catálogo/CAE e os UUID; oculta a sua nova escolha/projeção pelo contrato compatível e volta a internal os nove elos/ligações criados por este importador. Não retira referências públicas anteriores de outra origem. Uma importação repetida do próprio lote não cria uma restrição falsa de retirada.
2. Em manutenção, conferir o hash atual antes de substituir ou remover cada ficheiro. Repor apenas routes/web.php da cópia fresca do próprio destino, se corresponder à base do manifesto. Remover por hash somente EconomicReferenceInstallation.php, EconomicReferenceController.php e a fonte management/economic-references.tsx. Se houver outra revisão, parar a troca e reconciliar; não apagar código alheio.
3. **Conservar nove artefactos**: sete fontes funcionais (EconomicReferenceCatalog, OpportunityCanonicalContract, OpportunityClassification, ExistingBusinessClassification, ReferenceCatalogController e os dois componentes React partilhados), manifesto de dados e migration. Conservar a migration no ledger, metadata, sector nullable, índice não único, todas as referências e decisões. O down recusa uso existente.
4. **Conservar o build completo e coerente da candidata**, com 162 ficheiros. Este é o build de compatibilidade verificado; o módulo estático da página operacional fica sem rota acessível. Não misturar manifests/chunks ou restaurar um build antigo que desconheça os seletores e rótulos históricos. A manutenção deixa a aplicação servir novamente o percurso anterior com contrato funcional de compatibilidade. Limpar apenas config/rotas/vistas quando necessário, preservando cache de dados, e recarregar PHP antes de up.
5. Abrir e recuperar sem gravar dados reais. Uma edição posterior conserva a taxonomia/relações previamente guardadas. Referências retiradas aparecem identificadas como históricas/indisponíveis, não em branco; conservar uma relação idêntica não autoriza criá-la ou alterá-la de novo com referência retirada. Alterações a conteúdo seguem o workflow anterior.
Sem instalação/migration nem utilização, é possível repor integralmente a cópia fresca de ficheiros/build anterior e retirar apenas os seis ficheiros novos por hash. Após instalar ou gravar dados, usar a reversão compatível acima. Um restauro integral da base só é recuperação de desastre, em alvo isolado primeiro e com reconciliação de dados posteriores; nunca é a reversão rotineira desta entrega.
Provas QA: troca efetiva para rotas anteriores e edição HTTP canónica bem-sucedida; serviço OpportunityManagement anterior preservou payload e decisões no rascunho 15. ExistingBusinessDrafts anterior preservou o payload legível e o diário do suplemento numa transação QA revertida, com estado editável preparado. O ensaio não demonstra recuperação de conteúdos legados cuja chave pré-QA não existe, nem nova aceitação da transição para edição. A QA de referência publicada/v12 e o ativo permanecem intactos.
'''
(review/'REVERSAO-COMPATIVEL.md').write_text(rollback,'utf-8')
print(json.dumps({'candidate':candidate,'application':len(application),'build':len(build),'private_originals':len(originals),'review_documents':6}))
@@ -0,0 +1,2 @@
<?php
require __DIR__.'/boot-QA.php';$s=app(App\Services\EconomicReferenceInstallation::class);$out=['files'=>$s->files(),'code_hash'=>$s->fingerprint(),'manifest_sha256'=>App\Services\EconomicReferenceCatalog::MANIFEST_SHA256,'target'=>$target,'publication'=>app(App\Services\EconomicReferenceCatalog::class)->publicationState()];file_put_contents(__DIR__.'/CANDIDATE-STATE.json',json_encode($out,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));echo json_encode(['files'=>count($out['files']),'hash'=>$out['code_hash']]);
@@ -0,0 +1,22 @@
from pathlib import Path
import json,hashlib,subprocess,datetime
out=Path(__file__).resolve().parent;root=out.parents[1];private=Path('C:/Users/macbook/.config/investmoz/referencias-economicas-QA-20261016');source=private/'source';sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
baseline=json.loads((out/'ATIVO-ANTES.json').read_text('utf-8'));actual={p.relative_to(root).as_posix():sha(p) for folder in ['app','config','routes','database','resources','public/build'] for p in (root/folder).rglob('*') if p.is_file()}
assert actual==baseline['files'],'Active sources or build changed'
assert all(sha(root/n)==h for n,h in baseline['protected'].items()),'Protected active config/locks changed'
state=json.loads((out/'CANDIDATE-STATE.json').read_text('utf-8'));assert state['publication']=='published'
php='C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe';lint=[]
for name in state['files']:
if name.endswith('.php'):
r=subprocess.run([php,'-l',str(source/name)],capture_output=True,text=True);assert r.returncode==0,name;lint.append(name)
assert 'error TS' not in (out/'TYPES-CHECK.log').read_text('utf-16')
buildlog=(out/'BUILD.log').read_text('utf-16');assert 'built in' in buildlog
build=source/'public/build';manifest=json.loads((build/'manifest.json').read_text('utf-8'));refs=[]
for k,v in manifest.items():
for name in [v['file'],*v.get('css',[]),*v.get('assets',[])]:assert (build/name).is_file(),name;refs.append(name)
assert any('economic-references' in k for k in manifest)
entry=next(v['file'] for k,v in manifest.items() if k=='resources/js/app.tsx');assert 'InvesteMoz' in (build/entry).read_text('utf-8')
counts={'application_artifacts':len(state['files']),'sources':len(state['files'])-2,'substitutions':sum((root/n).exists() for n in state['files']),'new_files':sum(not(root/n).exists() for n in state['files']),'compiled_files':sum(p.is_file()for p in build.rglob('*')),'php_linted':len(lint),'active_files_compared':len(actual),'protected_files_compared':len(baseline['protected'])}
assert counts['application_artifacts']==13 and counts['substitutions']==7 and counts['new_files']==6
result={'verified_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'counts':counts,'types_check':'passed','build':'passed; existing optional fontaine/chunk-size notices only','build_asset_references_checked':len(refs),'active_sources_config_build_unchanged':True,'active_database_connections':0,'QA_target':state['target'],'candidate':'referencias-economicas-QA-'+state['code_hash'][:12],'code_hash':state['code_hash']}
(out/'VERIFICACAO-LOCAL.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n','utf-8');print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,38 @@
<?php
ini_set('zend.exception_ignore_args','1');
set_exception_handler(function(Throwable $e){fwrite(STDERR,'QA fixture stopped: '.$e::class.' line '.$e->getLine().PHP_EOL);exit(1);});
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
$private=dirname($source);$file=$private.'/fixture-private.json';if(is_file($file))throw new RuntimeException('Preserve fixture');
$tables=['sectors','reference_catalog_versions','economic_activities','economic_clusters','value_chains','value_chain_links','portal_role_assignments','portal_superuser_pair','existing_businesses','existing_business_revisions','business_workflow_transitions','opportunities','audit_events'];
$before=[];
foreach($tables as$t){$before[$t]=DB::table($t)->orderBy('id')->get()->toArray();}
file_put_contents($private.'/database-before.json',json_encode($before,JSON_THROW_ON_ERROR));
$actors=[];
foreach([2=>'manager',21=>'owner',24=>'reviewer',25=>'publisher',23=>'outsider',31=>'auditor']as$id=>$role){
$password=bin2hex(random_bytes(20));$alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';$secret='';for($i=0;$i<32;$i++)$secret.=$alphabet[random_int(0,31)];
$email='qa-economic-'.$id.'@example.invalid';
DB::table('users')->where('id',$id)->update(['email'=>$email,'email_verified_at'=>now(),'password'=>Hash::make($password),'two_factor_secret'=>Crypt::encrypt($secret),'two_factor_recovery_codes'=>Crypt::encrypt('[]'),'two_factor_confirmed_at'=>now(),'remember_token'=>null]);
$actors[$role]=['id'=>$id,'email'=>$email,'password'=>$password,'secret'=>$secret];
}
$extra="PORTAL_MANAGER_EMAILS=qa-economic-2@example.invalid,qa-economic-31@example.invalid\nPORTAL_OPPORTUNITY_SPECIALIZED_DRAFTS_ENABLED=true\n";
file_put_contents($source.'/.env',$extra,FILE_APPEND);
$document=DB::table('documents')->where('id','025cce5b-73c1-43a3-b969-dc6e592bc28d')->first();
if(!$document||$document->file_name!=='synthetic-qa-proof.txt'||$document->status!=='active'||$document->malware_scan_status!=='clean'||trim($document->sha256)!==trim($document->malware_scanned_sha256))throw new RuntimeException('Synthetic QA scanned support required');
$reference=dirname(__DIR__,2).'/storage/app/private/investmoz-v2/portal-audit/portal-stability-source-20261011_083742/storage/app/private';
$stored=file_get_contents($reference.'/'.$document->storage_key);$bytes=$document->storage_encryption==='laravel'?Crypt::decryptString($stored):$stored;
if(hash('sha256',$bytes)!==trim($document->sha256))throw new RuntimeException('Synthetic bytes mismatch');
$dest=$source.'/storage/app/private/'.$document->storage_key;if(!is_dir(dirname($dest)))mkdir(dirname($dest),0700,true);file_put_contents($dest,$stored);
$businessId='172aa874-98fc-4bf6-b78f-d2e9a386d345';$b=App\Models\ExistingBusiness::findOrFail($businessId);if($b->status!=='published'||$b->version_no!==12)throw new RuntimeException('Published QA v12 required');
$link=DB::table('existing_business_document_links')->where('existing_business_id',$businessId)->where('document_id',$document->id)->value('id');
if(!$link)DB::table('existing_business_document_links')->insert(['id'=>(string)Illuminate\Support\Str::uuid(),'existing_business_id'=>$businessId,'document_id'=>$document->id,'uploaded_by'=>21,'created_at'=>now(),'updated_at'=>now()]);
$opportunities=DB::table('opportunities')->where('title','like','%QA%')->orderBy('id')->get(['id','title','status','owner_user_id','opportunity_category','workflow_context']);
$selection=[];
foreach($opportunities as$o){$ctx=json_decode($o->workflow_context,true);$selection[]=['id'=>$o->id,'title'=>$o->title,'status'=>$o->status,'owner'=>$o->owner_user_id,'category'=>$o->opportunity_category,'context_keys'=>array_keys($ctx??[])];}
file_put_contents(__DIR__.'/CANONICAL-CANDIDATES-QA.json',json_encode($selection,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
$f=['url'=>'http://127.0.0.1:18531','database'=>'economic_references_20261016_test','actors'=>$actors,'business_id'=>$businessId,'business_slug'=>$b->public_slug,'document_id'=>$document->id];
file_put_contents($file,json_encode($f,JSON_THROW_ON_ERROR));
file_put_contents(__DIR__.'/FIXTURE-QA.json',json_encode(['database'=>$f['database'],'synthetic_accounts_in_clone'=>6,'grants_changed'=>0,'new_businesses'=>0,'document'=>$document->id,'existing_clean_bytes_verified'=>true,'active_changes'=>0],JSON_PRETTY_PRINT));
echo json_encode(['fixture'=>'private values retained locally','opportunity_candidates'=>count($selection),'business_version'=>$b->version_no,'role_assignments_unchanged'=>DB::table('portal_role_assignments')->orderBy('id')->get()->toArray()===$before['portal_role_assignments']]);
@@ -0,0 +1,70 @@
{
"candidate": "referencias-economicas-QA-966202f15577",
"verified_at": "2026-10-16T09:35:25.728842+00:00",
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3",
"manifest_data_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"documents": {
"ATUALIZACAO-MESMA-MATRIZ.json": {
"sha256": "366ca6b811dfe5f8cbcd6c5a7bc5b511d61180ab956c236f70852e758872c0e7",
"bytes": 931
},
"MANIFESTO-ENTREGA.json": {
"sha256": "a9e269a90a561e5ef2f462aa58cf2ae430c2904f948278b37f12dcc46273baf0",
"bytes": 37521
},
"MANIFESTO-LOTE.json": {
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"bytes": 12952
},
"PROCEDIMENTO-EXATO.md": {
"sha256": "281181a83b288d9a6f7f5beca9cc932ace911791bce4c99a356b7e92e7798c36",
"bytes": 8137
},
"PROPOSTA-UNICA-TEMPO.md": {
"sha256": "3d7d977cb7efb9416c3305b56276a6da160bca1ac65fa3091b62f0faea29847c",
"bytes": 4952
},
"RELATORIO-QA.md": {
"sha256": "477c6a070b307c9ac69d02821b1b6df5e858c6e45a61534735d8d4db4ef9d309",
"bytes": 7844
},
"REVERSAO-COMPATIVEL.md": {
"sha256": "96e4e855bcae3492d394e3d8bb951ac6b30b12521ab283422f958da20a9e32bb",
"bytes": 3571
}
},
"package": {
"name": "referencias-economicas-QA-966202f15577.zip",
"sha256": "8af1f9ed0826311d776a800c95767162af14a96837bc34708317deb78c213343",
"bytes": 4282396,
"entries": 376,
"CRC": "passed",
"all_entry_SHA256": "passed",
"internal_integrity_manifest_sha256": "cf621fffcb37338472824ec04da780db69203037a82bce13bb56f278a15367af"
},
"verification": {
"HTTP_checks": 83,
"HTTP_requests": 170,
"compatibility_checks": 13,
"preservation_checks": 184,
"raw_unrelated_matrix_rows_preserved": 3395,
"all_matrix_states_and_criteria_preserved": true,
"types": "passed",
"PHP_lint": 9,
"build_files": 162,
"active_sources_and_build_identical": 982,
"active_config_locks_identical": 3,
"active_DB_connections": 0
},
"limits": [
"600/579 and normative edition open",
"editorial model only",
"canonical approval preconditions synthetic",
"legacy business edit transactional; no unavailable legacy payload recovery",
"no volumetric test",
"partial compatible rollback retains additive schema and seven functional sources"
],
"active_authorized": false,
"active_actions_executed": 0,
"reviewer_independent_ZIP_inspection": "not asserted"
}
@@ -0,0 +1,70 @@
{
"candidate": "referencias-economicas-QA-966202f15577",
"verified_at": "2026-10-16T09:36:06.318649+00:00",
"code_hash": "966202f15577e25223480c35449f8a4693914afb3cf1526c93366460a55049c3",
"manifest_data_sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"documents": {
"ATUALIZACAO-MESMA-MATRIZ.json": {
"sha256": "366ca6b811dfe5f8cbcd6c5a7bc5b511d61180ab956c236f70852e758872c0e7",
"bytes": 931
},
"MANIFESTO-ENTREGA.json": {
"sha256": "a9e269a90a561e5ef2f462aa58cf2ae430c2904f948278b37f12dcc46273baf0",
"bytes": 37521
},
"MANIFESTO-LOTE.json": {
"sha256": "ba1bb3406fd55e39c19fd2a2755f3dfc2a1160b67eee8b3b6e12cd43f4223b04",
"bytes": 12952
},
"PROCEDIMENTO-EXATO.md": {
"sha256": "58a11c82782bb1c06533ee7f59b91caa5c4a6a626126dec6039bf111a884c211",
"bytes": 8184
},
"PROPOSTA-UNICA-TEMPO.md": {
"sha256": "3d7d977cb7efb9416c3305b56276a6da160bca1ac65fa3091b62f0faea29847c",
"bytes": 4952
},
"RELATORIO-QA.md": {
"sha256": "477c6a070b307c9ac69d02821b1b6df5e858c6e45a61534735d8d4db4ef9d309",
"bytes": 7844
},
"REVERSAO-COMPATIVEL.md": {
"sha256": "96e4e855bcae3492d394e3d8bb951ac6b30b12521ab283422f958da20a9e32bb",
"bytes": 3571
}
},
"package": {
"name": "referencias-economicas-QA-966202f15577.zip",
"sha256": "3170431f6d840325b29ac1202f90ec69a1ffe871d901920170a9e561f88dcb2b",
"bytes": 4282407,
"entries": 376,
"CRC": "passed",
"all_entry_SHA256": "passed",
"internal_integrity_manifest_sha256": "aba9106ea57aea0f95ebe84dcff853b933804eac8fd10dd8b858e18ce3deb6b1"
},
"verification": {
"HTTP_checks": 83,
"HTTP_requests": 170,
"compatibility_checks": 13,
"preservation_checks": 184,
"raw_unrelated_matrix_rows_preserved": 3395,
"all_matrix_states_and_criteria_preserved": true,
"types": "passed",
"PHP_lint": 9,
"build_files": 162,
"active_sources_and_build_identical": 982,
"active_config_locks_identical": 3,
"active_DB_connections": 0
},
"limits": [
"600/579 and normative edition open",
"editorial model only",
"canonical approval preconditions synthetic",
"legacy business edit transactional; no unavailable legacy payload recovery",
"no volumetric test",
"partial compatible rollback retains additive schema and seven functional sources"
],
"active_authorized": false,
"active_actions_executed": 0,
"reviewer_independent_ZIP_inspection": "not asserted"
}
@@ -0,0 +1,43 @@
from pathlib import Path
import json,urllib.request,urllib.error,urllib.parse,http.cookiejar,hmac,hashlib,base64,struct,time,uuid
out=Path(__file__).resolve().parent
private=Path('C:/Users/macbook/.config/investmoz/referencias-economicas-QA-20261016')
f=json.loads((private/'fixture-private.json').read_text('utf-8'))
proof_path=out/'HTTP-QA.json'
proof=json.loads(proof_path.read_text('utf-8')) if proof_path.exists() else {'target':f['database']+':55441','checks':{},'events':[],'active_changes':0,'accepted_tests_repeated':False}
def save():proof_path.write_text(json.dumps(proof,ensure_ascii=False,indent=2)+'\n','utf-8')
def check(name,value):
assert value,name
proof['checks'][name]=True;save()
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self,*a,**k):return None
def session(role=None):
jar=http.cookiejar.LWPCookieJar(str(private/('session-'+(role or 'anonymous')+'.cookies')))
if Path(jar.filename).exists():jar.load(ignore_discard=True,ignore_expires=True)
return jar,urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar),NoRedirect())
def call(s,path,data=None,expected=200,method=None,headers=None):
jar,op=s;hs={'Accept':'application/json',**(headers or {})};body=None
if data is not None:
body=json.dumps(data,ensure_ascii=False).encode();hs.update({'Content-Type':'application/json','X-XSRF-TOKEN':next((urllib.parse.unquote(c.value)for c in jar if c.name=='XSRF-TOKEN'),'')})
hs.update(headers or {})
try:r=op.open(urllib.request.Request(f['url']+path,data=body,headers=hs,method=method),timeout=80)
except urllib.error.HTTPError as e:r=e
raw=r.read();assert r.headers.get('X-QA-Target')==f['database']+':55441','QA response guard'
try:v=json.loads(raw)
except ValueError:v={}
proof['events'].append({'method':method or ('POST' if data is not None else 'GET'),'path':path,'status':r.status,'body_sha256':hashlib.sha256(raw).hexdigest()});jar.save(ignore_discard=True,ignore_expires=True);save()
valid=r.status in expected if isinstance(expected,tuple) else r.status==expected
if not valid:
(out/'HTTP-UNEXPECTED.json').write_text(json.dumps({'status':r.status,'expected':expected,'path':path,'message':v.get('message'),'errors':v.get('errors')},ensure_ascii=False,indent=2),'utf-8')
assert valid,f'HTTP {r.status} expected {expected}; see HTTP-UNEXPECTED.json'
return v
def login(role):
s=session(role);s[0].clear();a=f['actors'][role];call(s,'/login');v=call(s,'/login',{'email':a['email'],'password':a['password']},expected=(200,204,302))
b=hmac.new(base64.b32decode(a['secret']),struct.pack('>Q',int(time.time()/30)),hashlib.sha1).digest();i=b[-1]&15;code=str((struct.unpack('>I',b[i:i+4])[0]&0x7fffffff)%1000000).zfill(6)
call(s,'/two-factor-challenge',{'code':code},expected=(200,204,302));check(role+'_normal_Fortify_MFA',True);return s
base='/management/economic-references/lot-01'
def plan(s):return call(s,base)['plan']
def operation(s,op,expected=200,**extra):
p=plan(s);payload={'hash':p['operations'][op]['hash'],'idempotency_key':str(uuid.uuid4()),'confirm':True,'reason':'Ensaio QA delimitado das referências económicas do lote 01.',**extra}
v=call(s,base+'/'+op,payload,expected=expected)
return v.get('receipt',v),payload
@@ -0,0 +1,4 @@
<?php
require __DIR__.'/boot-QA.php';$result=[];
foreach(App\Models\ExistingBusiness::where('status','draft')->get()as$b){$readable=false;try{$payload=$b->payload;$readable=is_array($payload)&&!empty($payload['title']);}catch(Throwable){}$allowed=[];foreach([2,21]as$id)if(Illuminate\Support\Facades\Gate::forUser(App\Models\User::find($id))->allows('update',$b))$allowed[]=$id;$result[]=['id'=>$b->id,'owner'=>$b->owner_user_id,'readable'=>$readable,'allowed'=>$allowed];}
echo json_encode($result);
@@ -0,0 +1,5 @@
<?php
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
$o=App\Models\Opportunity::findOrFail(30);$p=app(App\Services\OpportunityManagement::class)->values($o)['canonical'];
echo json_encode(['status'=>$o->status,'working'=>$o->workflow_context['working_state']??null,'visibility'=>$p['visibility'],'milestone_fields'=>array_map('array_keys',$p['milestones']),'images'=>$p['images'],'slug'=>$o->slug,'approval_keys'=>array_keys($o->workflow_context['approval']??[])],JSON_UNESCAPED_UNICODE);
@@ -0,0 +1,12 @@
<?php
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
$before=json_decode(file_get_contents(dirname($source).'/database-before.json'),true);
$roles=DB::table('portal_role_assignments')->orderBy('id')->get()->toJson();
$same=hash('sha256',$roles)===hash('sha256',json_encode($before['portal_role_assignments']));
if(!$same)throw new RuntimeException('Role data changed');
$proof=json_decode(file_get_contents(__DIR__.'/FIXTURE-QA.json'),true);$proof['role_assignments_unchanged']=true;$proof['role_hash']=hash('sha256',$roles);file_put_contents(__DIR__.'/FIXTURE-QA.json',json_encode($proof,JSON_PRETTY_PRINT));
$pair=DB::table('portal_superuser_pair')->first(['first_user_id','second_user_id']);
$canonical=[];foreach([15,16,17,18,20,21,22,30,34,56]as$id){$o=App\Models\Opportunity::find($id);if(!$o)continue;$v=app(App\Services\OpportunityManagement::class)->values($o);$canonical[]=['id'=>$id,'status'=>$o->status,'owner'=>$o->owner_user_id,'category'=>$o->opportunity_category,'canonical_keys'=>array_keys($v['canonical']??[]),'version'=>$o->version_no,'canonical_sector'=>$v['canonical']['sector_id']??null,'subsector'=>$v['canonical']['subsector_id']??null,'activity'=>$v['canonical']['economic_activity_id']??null,'documents'=>$v['canonical']['documents']??[]];}
file_put_contents(__DIR__.'/CANONICAL-INSPECTION.json',json_encode($canonical,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
echo json_encode(['roles_unchanged'=>true,'pair'=>$pair,'canonical'=>$canonical,'scanner'=>app(App\Services\Malware\MalwareScanner::class)->health()],JSON_UNESCAPED_UNICODE);
@@ -0,0 +1,16 @@
<?php
require __DIR__.'/boot-QA.php';
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
$path=dirname($source).'/fixture-private.json';$fixture=json_decode(file_get_contents($path),true);
if(isset($fixture['actors']['installer']))throw new RuntimeException('Installer already prepared');
$pair=DB::table('portal_superuser_pair')->where('id',1)->first();$id=(int)$pair->first_user_id;
if($id!==27)throw new RuntimeException('Unexpected existing QA pair');
$password=bin2hex(random_bytes(20));$alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';$secret='';for($i=0;$i<32;$i++)$secret.=$alphabet[random_int(0,31)];
$email='qa-economic-'.$id.'@example.invalid';
DB::table('users')->where('id',$id)->update(['email'=>$email,'email_verified_at'=>now(),'password'=>Hash::make($password),'two_factor_secret'=>Crypt::encrypt($secret),'two_factor_recovery_codes'=>Crypt::encrypt('[]'),'two_factor_confirmed_at'=>now(),'remember_token'=>null]);
$fixture['actors']['installer']=['id'=>$id,'email'=>$email,'password'=>$password,'secret'=>$secret];
file_put_contents($path,json_encode($fixture,JSON_THROW_ON_ERROR));
file_put_contents($source.'/.env',"\nPORTAL_MANAGER_EMAILS=qa-economic-2@example.invalid,qa-economic-31@example.invalid,qa-economic-27@example.invalid\n",FILE_APPEND);
echo json_encode(['QA_installer_existing_pair'=>$id,'grants_changed'=>0]);
@@ -0,0 +1,25 @@
from pathlib import Path
import json,hashlib,uuid,shutil
root=Path(__file__).resolve().parents[2];out=Path(__file__).resolve().parent
q=json.loads((out/'QA-ISOLAMENTO.json').read_text('utf-8'));source=Path(q['source']);private=Path(q['private'])
plan=root/'outputs/investmoz-referencias-economicas-mapa-20261016'
lot=json.loads((plan/'DOC01/LOTE-PROPOSTO.json').read_text('utf-8'));refs=json.loads((plan/'ESTADO-QA-READONLY.json').read_text('utf-8'))['targets']['restored_destination']['tables']
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
ident=lambda k:str(uuid.uuid5(uuid.NAMESPACE_URL,'investmoz:economic-reference:lot-01:20261016:'+k))
files=[];extraction=json.loads((plan/'FONTES-EXTRAIDAS.json').read_text('utf-8'))['selection']
names=['CAE eBAU.xlsx','upgrade do portal de investimentos v6 programacao.docx','agronegócio 1.docx','Corredores de Desenvolvimento do Agronegócio em Moçambique.docx']
for name in names:
item=next(x for x in extraction if Path(x['path']).name==name);p=Path(item['path']);assert sha(p)==item['sha256']
relative='sources/'+item['sha256']+p.suffix.lower();dest=source/'storage/app/private/investmoz-v2/economic-references/lot-01'/relative;dest.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(p,dest)
files.append({'name':name,'relative_path':relative,'sha256':item['sha256'],'bytes':p.stat().st_size,'publication':'private retained source; no library publication','source_version':'retained exemplar '+item['sha256'][:12]})
sector=next(x for x in refs['sectors']['rows'] if x['id']==1);cluster=next(x for x in refs['economic_clusters']['rows'] if x['code']=='CLU-01')
meta={k:{f:r.get(f) for f in ['id','slug','code','source_system','external_id','name']} for k,r in [('sector',sector),('cluster',cluster)]}
catalog=ident('catalog');activities=[]
for r in lot['activities']:
activities.append({'id':ident('activity:'+r['code']),'catalog_version_id':catalog,'parent_id':ident('activity:'+next(x['code'] for x in lot['activities'] if x['source_id']==r['parent_source_id'])) if r['parent_source_id'] else None,'sector_id':None if r['level']=='1' else 1,'code':r['code'],'label_pt_mz':r['label'],'description_pt_mz':'Recorte do exemplar eBAU, sem certificação de conformidade normativa integral.','version_no':1,'valid_from':'2026-10-16','valid_to':None,'status':'draft','metadata':{'level':int(r['level']),'source_record_id':r['source_id'],'parent_source_record_id':r['parent_source_id'],'source_sha256':lot['source_sha256'],'sheet':'CAE','row':r['sheet_row'],'lot':'lot-01','source_version':files[0]['source_version'],'edition':'not_determined','sector_mapping':'none' if r['level']=='1' else 'explicit bounded editorial mapping for rice slice','date_semantics':'catalog availability; not legal validity'}})
chains=[{'id':ident('chain:'+r['code']),'source_system':'economic-reference-lot-01','external_id':r['code'],'version_no':1,'data_classification':'internal','cluster_id':cluster['id'],'code':r['code'],'name':r['name'],'stage':r['stage']} for r in lot['chain_stages']]
links=[{'id':ident('link:'+r['from']+':'+r['to']),'source_system':'economic-reference-lot-01','external_id':r['from']+':'+r['to'],'version_no':1,'data_classification':'internal','from_value_chain_id':ident('chain:'+r['from']),'to_value_chain_id':ident('chain:'+r['to']),'link_type':r['type']} for r in lot['chain_links']]
manifest={'lot':'lot-01','version':1,'origin_version':'eBAU-sha256-'+lot['source_sha256'][:12],'scope':'five-node rice slice and editorial CLU-01 chain; no normative edition conformity assertion','source_sha256':lot['source_sha256'],'divergence':{'exemplar_subclasses':600,'prior_instruction_subclasses':579,'status':'documentary_open_nonblocking_for_slice'},'convention':{'subsector':'01','activity':'01120','levels':5},'existing':meta,'sources':files,'disclosure':{'reference_designations_and_citations':'bounded editorial/reference slice authorised for QA; active requires explicit Tempo decision','source_originals':'private only'},'catalog':{'id':catalog,'catalog_code':'economic-activities-cae','version_no':1,'locale':'pt-MZ','source_system':'retained-ebau-exemplar','source_version':files[0]['source_version'],'source_reference':'CAE eBAU.xlsx, folha CAE; cinco nós A/01/011/0112/01120, hash '+lot['source_sha256']+'; edição normativa não determinada; 600/579 aberto.','source_sha256':lot['source_sha256'],'valid_from':'2026-10-16','valid_to':None,'status':'draft'},'activities':activities,'chains':chains,'links':links,'citations':{'activities':'CAE A1:F1; linhas 39,57,124,238,1122; SELF_ID explícito','chain_model':'Programação v6, §§534–543/631–635; modelo editorial genérico, sem operadores/capacidades/fluxos reais','context':'Agronegócio 1 §1; Corredores do Agronegócio §§4/10/23/29/39'},'new_reference_count':15}
p=source/'database/data/economic-references-lot-01.json';assert not p.exists();p.write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n','utf-8')
(out/'MANIFESTO-LOTE.json').write_bytes(p.read_bytes());(out/'MANIFESTO-HASH.json').write_text(json.dumps({'sha256':sha(p),'activities':{r['code']:r['id'] for r in activities},'chains':{r['code']:r['id'] for r in chains},'catalog':catalog},indent=2)+'\n','utf-8')
print(json.dumps({'manifest_sha256':sha(p),'records':15,'sources':len(files),'private_source_bytes':sum(x['bytes'] for x in files)}))
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because one or more lines are too long
@@ -0,0 +1,752 @@
{
"hoistPattern": [
"*"
],
"included": {
"dependencies": true,
"devDependencies": false,
"optionalDependencies": true
},
"injectedDeps": {},
"ignoredBuilds": [],
"layoutVersion": 5,
"hoistedLocations": {
"@napi-rs/canvas@0.1.100": [
"node_modules\\@napi-rs\\canvas"
],
"@viz-js/viz@3.25.0": [
"node_modules\\@viz-js\\viz"
],
"docx@9.6.1": [
"node_modules\\docx"
],
"jpeg-js@0.4.4": [
"node_modules\\jpeg-js"
],
"live-server@1.2.2": [
"node_modules\\live-server"
],
"lucide@1.8.0": [
"node_modules\\lucide"
],
"marked@17.0.5": [
"node_modules\\marked"
],
"pdf-lib@1.17.1": [
"node_modules\\pdf-lib"
],
"pdfjs-dist@5.6.205": [
"node_modules\\pdfjs-dist"
],
"pixelmatch@7.2.0": [
"node_modules\\pixelmatch"
],
"pngjs@7.0.0": [
"node_modules\\pngjs"
],
"pnpm@11.25.0": [
"node_modules\\pnpm"
],
"@types/node@22.20.1": [
"node_modules\\pptxgenjs\\node_modules\\@types\\node"
],
"undici-types@6.21.0": [
"node_modules\\pptxgenjs\\node_modules\\undici-types"
],
"sharp@0.35.5(@types/node@25.9.5)": [
"node_modules\\sharp"
],
"tesseract.js@7.0.0": [
"node_modules\\tesseract.js"
],
"@napi-rs/canvas-win32-arm64-msvc@0.1.100": [
"node_modules\\@napi-rs\\canvas-win32-arm64-msvc"
],
"@types/node@25.9.5": [
"node_modules\\@types\\node"
],
"hash.js@1.1.7": [
"node_modules\\hash.js"
],
"jszip@3.10.1": [
"node_modules\\jszip"
],
"nanoid@5.1.16": [
"node_modules\\nanoid"
],
"xml@1.0.1": [
"node_modules\\xml"
],
"xml-js@1.6.11": [
"node_modules\\xml-js"
],
"is-glob@4.0.3": [
"node_modules\\chokidar\\node_modules\\is-glob"
],
"normalize-path@3.0.0": [
"node_modules\\chokidar\\node_modules\\normalize-path"
],
"colors@1.4.0": [
"node_modules\\colors"
],
"connect@3.7.0": [
"node_modules\\connect"
],
"cors@2.8.6": [
"node_modules\\cors"
],
"event-stream@3.3.4": [
"node_modules\\event-stream"
],
"faye-websocket@0.11.4": [
"node_modules\\faye-websocket"
],
"http-auth@3.1.3": [
"node_modules\\http-auth"
],
"morgan@1.12.0": [
"node_modules\\morgan"
],
"object-assign@4.1.1": [
"node_modules\\object-assign"
],
"opn@6.0.0": [
"node_modules\\opn"
],
"proxy-middleware@0.15.0": [
"node_modules\\proxy-middleware"
],
"debug@4.4.3": [
"node_modules\\send\\node_modules\\debug"
],
"encodeurl@2.0.0": [
"node_modules\\send\\node_modules\\encodeurl"
],
"mime-types@3.0.2": [
"node_modules\\send\\node_modules\\mime-types"
],
"statuses@2.0.2": [
"node_modules\\send\\node_modules\\statuses",
"node_modules\\http-errors\\node_modules\\statuses"
],
"http-errors@1.8.1": [
"node_modules\\serve-index\\node_modules\\http-errors"
],
"depd@1.1.2": [
"node_modules\\serve-index\\node_modules\\depd"
],
"@pdf-lib/standard-fonts@1.0.0": [
"node_modules\\@pdf-lib\\standard-fonts"
],
"@pdf-lib/upng@1.0.1": [
"node_modules\\@pdf-lib\\upng"
],
"pako@1.0.11": [
"node_modules\\pako"
],
"tslib@1.14.1": [
"node_modules\\tslib"
],
"node-readable-to-web-readable-stream@0.4.2": [
"node_modules\\node-readable-to-web-readable-stream"
],
"playwright-core@1.62.1": [
"node_modules\\playwright-core"
],
"https@1.0.0": [
"node_modules\\https"
],
"image-size@1.2.1": [
"node_modules\\image-size"
],
"@img/colour@1.1.0": [
"node_modules\\@img\\colour"
],
"detect-libc@2.1.2": [
"node_modules\\detect-libc"
],
"semver@7.8.5": [
"node_modules\\semver"
],
"@img/sharp-win32-arm64@0.35.5": [
"node_modules\\@img\\sharp-win32-arm64"
],
"bmp-js@0.1.0": [
"node_modules\\bmp-js"
],
"idb-keyval@6.3.0": [
"node_modules\\idb-keyval"
],
"is-url@1.2.4": [
"node_modules\\is-url"
],
"node-fetch@2.7.0": [
"node_modules\\node-fetch"
],
"opencollective-postinstall@2.0.3": [
"node_modules\\opencollective-postinstall"
],
"regenerator-runtime@0.13.11": [
"node_modules\\regenerator-runtime"
],
"tesseract.js-core@7.0.0": [
"node_modules\\tesseract.js-core"
],
"wasm-feature-detect@1.9.0": [
"node_modules\\wasm-feature-detect"
],
"zlibjs@0.3.1": [
"node_modules\\zlibjs"
],
"undici-types@7.24.6": [
"node_modules\\undici-types"
],
"inherits@2.0.4": [
"node_modules\\inherits"
],
"minimalistic-assert@1.0.1": [
"node_modules\\minimalistic-assert"
],
"lie@3.3.0": [
"node_modules\\lie"
],
"readable-stream@2.3.8": [
"node_modules\\readable-stream"
],
"setimmediate@1.0.5": [
"node_modules\\setimmediate"
],
"sax@1.6.1": [
"node_modules\\sax"
],
"anymatch@2.0.0": [
"node_modules\\anymatch"
],
"async-each@1.0.6": [
"node_modules\\async-each"
],
"braces@2.3.2": [
"node_modules\\braces"
],
"glob-parent@3.1.0": [
"node_modules\\glob-parent"
],
"is-binary-path@1.0.1": [
"node_modules\\is-binary-path"
],
"path-is-absolute@1.0.1": [
"node_modules\\path-is-absolute"
],
"readdirp@2.2.1": [
"node_modules\\readdirp"
],
"upath@1.2.0": [
"node_modules\\upath"
],
"is-extglob@2.1.1": [
"node_modules\\is-extglob"
],
"ms@2.0.0": [
"node_modules\\debug\\node_modules\\ms"
],
"on-finished@2.3.0": [
"node_modules\\finalhandler\\node_modules\\on-finished"
],
"parseurl@1.3.3": [
"node_modules\\parseurl"
],
"utils-merge@1.0.1": [
"node_modules\\utils-merge"
],
"vary@1.1.2": [
"node_modules\\vary"
],
"duplexer@0.1.2": [
"node_modules\\duplexer"
],
"from@0.1.7": [
"node_modules\\from"
],
"map-stream@0.1.0": [
"node_modules\\map-stream"
],
"pause-stream@0.0.11": [
"node_modules\\pause-stream"
],
"split@0.3.3": [
"node_modules\\split"
],
"stream-combiner@0.0.4": [
"node_modules\\stream-combiner"
],
"through@2.3.8": [
"node_modules\\through"
],
"websocket-driver@0.7.5": [
"node_modules\\websocket-driver"
],
"apache-crypt@1.2.6": [
"node_modules\\apache-crypt"
],
"apache-md5@1.1.8": [
"node_modules\\apache-md5"
],
"bcryptjs@2.4.3": [
"node_modules\\bcryptjs"
],
"uuid@3.4.0": [
"node_modules\\uuid"
],
"basic-auth@2.0.1": [
"node_modules\\basic-auth"
],
"depd@2.0.0": [
"node_modules\\depd"
],
"on-finished@2.4.1": [
"node_modules\\on-finished"
],
"on-headers@1.1.0": [
"node_modules\\on-headers"
],
"is-wsl@1.1.0": [
"node_modules\\is-wsl"
],
"escape-html@1.0.3": [
"node_modules\\escape-html"
],
"etag@1.8.1": [
"node_modules\\etag"
],
"fresh@2.0.0": [
"node_modules\\fresh"
],
"ms@2.1.3": [
"node_modules\\ms"
],
"range-parser@1.3.0": [
"node_modules\\range-parser"
],
"mime-db@1.54.0": [
"node_modules\\mime-db"
],
"accepts@1.3.8": [
"node_modules\\accepts"
],
"batch@0.6.1": [
"node_modules\\batch"
],
"mime-db@1.52.0": [
"node_modules\\mime-types\\node_modules\\mime-db"
],
"setprototypeof@1.2.0": [
"node_modules\\setprototypeof"
],
"statuses@1.5.0": [
"node_modules\\statuses"
],
"toidentifier@1.0.1": [
"node_modules\\toidentifier"
],
"queue@6.0.2": [
"node_modules\\queue"
],
"whatwg-url@5.0.0": [
"node_modules\\whatwg-url"
],
"immediate@3.0.6": [
"node_modules\\immediate"
],
"core-util-is@1.0.3": [
"node_modules\\core-util-is"
],
"isarray@1.0.0": [
"node_modules\\isarray"
],
"process-nextick-args@2.0.1": [
"node_modules\\process-nextick-args"
],
"safe-buffer@5.1.2": [
"node_modules\\safe-buffer"
],
"string_decoder@1.1.1": [
"node_modules\\string_decoder"
],
"util-deprecate@1.0.2": [
"node_modules\\util-deprecate"
],
"define-property@2.0.2": [
"node_modules\\micromatch\\node_modules\\define-property",
"node_modules\\to-regex\\node_modules\\define-property",
"node_modules\\nanomatch\\node_modules\\define-property"
],
"extend-shallow@3.0.2": [
"node_modules\\micromatch\\node_modules\\extend-shallow",
"node_modules\\split-string\\node_modules\\extend-shallow",
"node_modules\\to-regex\\node_modules\\extend-shallow",
"node_modules\\nanomatch\\node_modules\\extend-shallow",
"node_modules\\regex-not\\node_modules\\extend-shallow"
],
"kind-of@6.0.3": [
"node_modules\\micromatch\\node_modules\\kind-of",
"node_modules\\nanomatch\\node_modules\\kind-of"
],
"is-extendable@1.0.1": [
"node_modules\\micromatch\\node_modules\\is-extendable",
"node_modules\\split-string\\node_modules\\is-extendable",
"node_modules\\to-regex\\node_modules\\is-extendable",
"node_modules\\nanomatch\\node_modules\\is-extendable",
"node_modules\\regex-not\\node_modules\\is-extendable",
"node_modules\\mixin-deep\\node_modules\\is-extendable"
],
"normalize-path@2.1.1": [
"node_modules\\normalize-path"
],
"arr-flatten@1.1.0": [
"node_modules\\arr-flatten"
],
"array-unique@0.3.2": [
"node_modules\\array-unique"
],
"extend-shallow@2.0.1": [
"node_modules\\extend-shallow"
],
"fill-range@4.0.0": [
"node_modules\\fill-range"
],
"isobject@3.0.1": [
"node_modules\\isobject"
],
"repeat-element@1.1.4": [
"node_modules\\repeat-element"
],
"snapdragon@0.8.2": [
"node_modules\\snapdragon"
],
"define-property@1.0.0": [
"node_modules\\snapdragon-node\\node_modules\\define-property",
"node_modules\\extglob\\node_modules\\define-property",
"node_modules\\base\\node_modules\\define-property"
],
"is-glob@3.1.0": [
"node_modules\\is-glob"
],
"path-dirname@1.0.2": [
"node_modules\\path-dirname"
],
"binary-extensions@1.13.1": [
"node_modules\\binary-extensions"
],
"graceful-fs@4.2.11": [
"node_modules\\graceful-fs"
],
"encodeurl@1.0.2": [
"node_modules\\encodeurl"
],
"unpipe@1.0.0": [
"node_modules\\unpipe"
],
"ee-first@1.1.1": [
"node_modules\\ee-first"
],
"http-parser-js@0.5.10": [
"node_modules\\http-parser-js"
],
"websocket-extensions@0.1.4": [
"node_modules\\websocket-extensions"
],
"unix-crypt-td-js@1.1.4": [
"node_modules\\unix-crypt-td-js"
],
"negotiator@0.6.3": [
"node_modules\\negotiator"
],
"tr46@0.0.3": [
"node_modules\\tr46"
],
"webidl-conversions@3.0.1": [
"node_modules\\webidl-conversions"
],
"arr-diff@4.0.0": [
"node_modules\\arr-diff"
],
"fragment-cache@0.2.1": [
"node_modules\\fragment-cache"
],
"object.pick@1.3.0": [
"node_modules\\object.pick"
],
"is-descriptor@1.0.4": [
"node_modules\\is-descriptor"
],
"assign-symbols@1.0.0": [
"node_modules\\assign-symbols"
],
"is-plain-object@2.0.4": [
"node_modules\\is-plain-object"
],
"remove-trailing-separator@1.1.0": [
"node_modules\\remove-trailing-separator"
],
"is-extendable@0.1.1": [
"node_modules\\is-extendable"
],
"is-number@3.0.0": [
"node_modules\\is-number"
],
"repeat-string@1.6.1": [
"node_modules\\repeat-string"
],
"to-regex-range@2.1.1": [
"node_modules\\to-regex-range"
],
"is-descriptor@0.1.8": [
"node_modules\\define-property\\node_modules\\is-descriptor"
],
"map-cache@0.2.2": [
"node_modules\\map-cache"
],
"source-map@0.5.7": [
"node_modules\\source-map"
],
"source-map-resolve@0.5.3": [
"node_modules\\source-map-resolve"
],
"use@3.1.1": [
"node_modules\\use"
],
"snapdragon-util@3.0.1": [
"node_modules\\snapdragon-util"
],
"safe-regex@1.1.0": [
"node_modules\\safe-regex"
],
"expand-brackets@2.1.4": [
"node_modules\\expand-brackets"
],
"is-windows@1.0.2": [
"node_modules\\is-windows"
],
"is-accessor-descriptor@1.0.2": [
"node_modules\\is-accessor-descriptor"
],
"is-data-descriptor@1.0.1": [
"node_modules\\is-data-descriptor"
],
"kind-of@3.2.2": [
"node_modules\\kind-of"
],
"cache-base@1.0.1": [
"node_modules\\cache-base"
],
"class-utils@0.3.6": [
"node_modules\\class-utils"
],
"component-emitter@1.3.1": [
"node_modules\\component-emitter"
],
"pascalcase@0.1.1": [
"node_modules\\pascalcase"
],
"atob@2.1.2": [
"node_modules\\atob"
],
"decode-uri-component@0.2.2": [
"node_modules\\decode-uri-component"
],
"resolve-url@0.2.1": [
"node_modules\\resolve-url"
],
"source-map-url@0.4.1": [
"node_modules\\source-map-url"
],
"urix@0.1.0": [
"node_modules\\urix"
],
"ret@0.1.15": [
"node_modules\\ret"
],
"posix-character-classes@0.1.1": [
"node_modules\\posix-character-classes"
],
"hasown@2.0.4": [
"node_modules\\hasown"
],
"is-buffer@1.1.6": [
"node_modules\\is-buffer"
],
"collection-visit@1.0.0": [
"node_modules\\collection-visit"
],
"get-value@2.0.6": [
"node_modules\\get-value"
],
"has-value@1.0.0": [
"node_modules\\has-value"
],
"set-value@2.0.1": [
"node_modules\\set-value"
],
"to-object-path@0.3.0": [
"node_modules\\to-object-path"
],
"union-value@1.0.1": [
"node_modules\\union-value"
],
"isobject@2.1.0": [
"node_modules\\unset-value\\node_modules\\has-value\\node_modules\\isobject"
],
"has-values@0.1.4": [
"node_modules\\unset-value\\node_modules\\has-values"
],
"arr-union@3.1.0": [
"node_modules\\arr-union"
],
"static-extend@0.1.2": [
"node_modules\\static-extend"
],
"for-in@1.0.2": [
"node_modules\\for-in"
],
"function-bind@1.1.2": [
"node_modules\\function-bind"
],
"map-visit@1.0.0": [
"node_modules\\map-visit"
],
"object-visit@1.0.1": [
"node_modules\\object-visit"
],
"kind-of@4.0.0": [
"node_modules\\has-values\\node_modules\\kind-of"
],
"object-copy@0.1.0": [
"node_modules\\object-copy"
],
"copy-descriptor@0.1.1": [
"node_modules\\copy-descriptor"
],
"playwright@1.62.1": [
"node_modules\\playwright"
],
"pptxgenjs@4.0.1": [
"node_modules\\pptxgenjs"
],
"chokidar@2.1.8": [
"node_modules\\chokidar"
],
"send@1.2.1": [
"node_modules\\send"
],
"serve-index@1.9.2": [
"node_modules\\serve-index"
],
"debug@2.6.9": [
"node_modules\\debug"
],
"finalhandler@1.1.2": [
"node_modules\\finalhandler"
],
"http-errors@2.0.1": [
"node_modules\\http-errors"
],
"mime-types@2.1.35": [
"node_modules\\mime-types"
],
"micromatch@3.1.10": [
"node_modules\\micromatch"
],
"snapdragon-node@2.1.1": [
"node_modules\\snapdragon-node"
],
"split-string@3.1.0": [
"node_modules\\split-string"
],
"to-regex@3.0.2": [
"node_modules\\to-regex"
],
"extglob@2.0.4": [
"node_modules\\extglob"
],
"nanomatch@1.2.13": [
"node_modules\\nanomatch"
],
"regex-not@1.0.2": [
"node_modules\\regex-not"
],
"base@0.11.2": [
"node_modules\\base"
],
"define-property@0.2.5": [
"node_modules\\define-property"
],
"mixin-deep@1.3.2": [
"node_modules\\mixin-deep"
],
"has-value@0.3.1": [
"node_modules\\unset-value\\node_modules\\has-value"
],
"has-values@1.0.0": [
"node_modules\\has-values"
],
"unset-value@1.0.0": [
"node_modules\\unset-value"
]
},
"nodeLinker": "hoisted",
"packageManager": "pnpm@11.25.0",
"pendingBuilds": [],
"publicHoistPattern": [],
"prunedAt": "Wed, 14 Oct 2026 03:38:23 GMT",
"skipped": [
"@emnapi/runtime@1.11.3",
"@img/sharp-darwin-arm64@0.35.5",
"@img/sharp-darwin-x64@0.35.5",
"@img/sharp-freebsd-wasm32@0.35.5",
"@img/sharp-libvips-darwin-arm64@1.3.4",
"@img/sharp-libvips-darwin-x64@1.3.4",
"@img/sharp-libvips-linux-arm64@1.3.4",
"@img/sharp-libvips-linux-arm@1.3.4",
"@img/sharp-libvips-linux-ppc64@1.3.4",
"@img/sharp-libvips-linux-riscv64@1.3.4",
"@img/sharp-libvips-linux-s390x@1.3.4",
"@img/sharp-libvips-linux-x64@1.3.4",
"@img/sharp-libvips-linuxmusl-arm64@1.3.4",
"@img/sharp-libvips-linuxmusl-x64@1.3.4",
"@img/sharp-linux-arm64@0.35.5",
"@img/sharp-linux-arm@0.35.5",
"@img/sharp-linux-ppc64@0.35.5",
"@img/sharp-linux-riscv64@0.35.5",
"@img/sharp-linux-s390x@0.35.5",
"@img/sharp-linux-x64@0.35.5",
"@img/sharp-linuxmusl-arm64@0.35.5",
"@img/sharp-linuxmusl-x64@0.35.5",
"@img/sharp-wasm32@0.35.5",
"@img/sharp-webcontainers-wasm32@0.35.5",
"@img/sharp-win32-ia32@0.35.5",
"@img/sharp-win32-x64@0.35.5",
"@napi-rs/canvas-android-arm64@0.1.100",
"@napi-rs/canvas-darwin-arm64@0.1.100",
"@napi-rs/canvas-darwin-x64@0.1.100",
"@napi-rs/canvas-linux-arm-gnueabihf@0.1.100",
"@napi-rs/canvas-linux-arm64-gnu@0.1.100",
"@napi-rs/canvas-linux-arm64-musl@0.1.100",
"@napi-rs/canvas-linux-riscv64-gnu@0.1.100",
"@napi-rs/canvas-linux-x64-gnu@0.1.100",
"@napi-rs/canvas-linux-x64-musl@0.1.100",
"@napi-rs/canvas-win32-x64-msvc@0.1.100",
"bindings@1.5.0",
"file-uri-to-path@1.0.0",
"fsevents@1.2.13",
"fsevents@2.3.2",
"nan@2.28.0",
"tslib@2.8.1"
],
"storeDir": "C:\\Users\\runneradmin\\AppData\\Local\\pnpm\\store\\v11",
"virtualStoreDir": "C:\\Users\\runneradmin\\AppData\\Local\\Temp\\codex-primary-runtime-KQGWUJ\\install\\node_modules\\.pnpm",
"virtualStoreDirMaxLength": 60,
"allowBuilds": {
"fsevents@1.2.13": false,
"tesseract.js@7.0.0": false
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,44 @@
{
"lastValidatedTimestamp": 1791949103910,
"projects": {
"C:\\Users\\runneradmin\\AppData\\Local\\Temp\\codex-primary-runtime-KQGWUJ\\install": {
"name": "@openai/codex-electron-bundled-runtimes",
"version": "0.0.0"
}
},
"pnpmfiles": [],
"settings": {
"enableGlobalVirtualStore": false,
"allowBuilds": {
"fsevents@1.2.13": false,
"tesseract.js@7.0.0": false
},
"autoInstallPeers": true,
"catalogs": {},
"dedupeDirectDeps": false,
"dedupeInjectedDeps": true,
"dedupePeerDependents": true,
"dedupePeers": false,
"dev": false,
"excludeLinksFromLockfile": false,
"hoistPattern": [
"*"
],
"hoistWorkspacePackages": true,
"injectWorkspacePackages": false,
"linkWorkspacePackages": false,
"minimumReleaseAge": "10080",
"minimumReleaseAgeStrict": true,
"minimumReleaseAgeIgnoreMissingTime": false,
"nodeLinker": "hoisted",
"optional": true,
"peersSuffixMaxLength": 1000,
"preferWorkspacePackages": false,
"production": true,
"publicHoistPattern": [],
"workspacePackagePatterns": [
"."
]
},
"filteredInstall": false
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
# Licensing
## color
Copyright (c) 2012 Heather Arthur
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## color-convert
Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.com>.
Copyright (c) 2016-2021 Josh Junon <josh@junon.me>.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## color-string
Copyright (c) 2011 Heather Arthur <fayearthur@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## color-name
The MIT License (MIT)
Copyright (c) 2015 Dmitry Ivanov
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
# `@img/colour`
The latest version of the
[color](https://www.npmjs.com/package/color)
package is now ESM-only,
however some JavaScript runtimes do not yet support this,
which includes versions of Node.js prior to 20.19.0.
This package converts the `color` package and its dependencies,
all of which are MIT-licensed, to CommonJS.
- [color](https://www.npmjs.com/package/color)
- [color-convert](https://www.npmjs.com/package/color-convert)
- [color-string](https://www.npmjs.com/package/color-string)
- [color-name](https://www.npmjs.com/package/color-name)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
module.exports = require("./color.cjs").default;
@@ -0,0 +1,929 @@
// Generated by dts-bundle-generator v9.5.1
type Channels = number;
type RGB = [
r: number,
g: number,
b: number
];
type HSL = [
h: number,
s: number,
l: number
];
type HSV = [
h: number,
s: number,
v: number
];
type CMYK = [
c: number,
m: number,
y: number,
k: number
];
type LAB = [
l: number,
a: number,
b: number
];
type LCH = [
l: number,
c: number,
h: number
];
type HCG = [
h: number,
c: number,
g: number
];
type HWB = [
h: number,
w: number,
b: number
];
type XYZ = [
x: number,
y: number,
z: number
];
type Apple = [
r16: number,
g16: number,
b16: number
];
type Gray = [
gray: number
];
type ANSI16 = number;
type ANSI256 = number;
type Keyword = string;
type HEX = string;
declare namespace route {
type rgb = {
hsl(from: RGB): HSL;
hsl(...from: RGB): HSL;
hsl(from: RGB): HSL;
hsl(...from: RGB): HSL;
hsv(from: RGB): HSV;
hsv(...from: RGB): HSV;
hwb(from: RGB): HWB;
hwb(...from: RGB): HWB;
cmyk(from: RGB): CMYK;
cmyk(...from: RGB): CMYK;
xyz(from: RGB): XYZ;
xyz(...from: RGB): XYZ;
lab(from: RGB): LAB;
lab(...from: RGB): LAB;
lch(from: RGB): LCH;
lch(...from: RGB): LCH;
hex(from: RGB): HEX;
hex(...from: RGB): HEX;
keyword(from: RGB): Keyword;
keyword(...from: RGB): Keyword;
ansi16(from: RGB): ANSI16;
ansi16(...from: RGB): ANSI16;
ansi256(from: RGB): ANSI256;
ansi256(...from: RGB): ANSI256;
hcg(from: RGB): HCG;
hcg(...from: RGB): HCG;
apple(from: RGB): Apple;
apple(...from: RGB): Apple;
gray(from: RGB): Gray;
gray(...from: RGB): Gray;
};
type hsl = {
rgb(from: HSL): RGB;
rgb(...from: HSL): RGB;
hsv(from: HSL): HSV;
hsv(...from: HSL): HSV;
hwb(from: HSL): HWB;
hwb(...from: HSL): HWB;
cmyk(from: HSL): CMYK;
cmyk(...from: HSL): CMYK;
xyz(from: HSL): XYZ;
xyz(...from: HSL): XYZ;
lab(from: HSL): LAB;
lab(...from: HSL): LAB;
lch(from: HSL): LCH;
lch(...from: HSL): LCH;
hex(from: HSL): HEX;
hex(...from: HSL): HEX;
keyword(from: HSL): Keyword;
keyword(...from: HSL): Keyword;
ansi16(from: HSL): ANSI16;
ansi16(...from: HSL): ANSI16;
ansi256(from: HSL): ANSI256;
ansi256(...from: HSL): ANSI256;
hcg(from: HSL): HCG;
hcg(...from: HSL): HCG;
apple(from: HSL): Apple;
apple(...from: HSL): Apple;
gray(from: HSL): Gray;
gray(...from: HSL): Gray;
};
type hsv = {
rgb(from: HSV): RGB;
rgb(...from: HSV): RGB;
hsl(from: HSV): HSL;
hsl(...from: HSV): HSL;
hwb(from: HSV): HWB;
hwb(...from: HSV): HWB;
cmyk(from: HSV): CMYK;
cmyk(...from: HSV): CMYK;
xyz(from: HSV): XYZ;
xyz(...from: HSV): XYZ;
lab(from: HSV): LAB;
lab(...from: HSV): LAB;
lch(from: HSV): LCH;
lch(...from: HSV): LCH;
hex(from: HSV): HEX;
hex(...from: HSV): HEX;
keyword(from: HSV): Keyword;
keyword(...from: HSV): Keyword;
ansi16(from: HSV): ANSI16;
ansi16(...from: HSV): ANSI16;
ansi256(from: HSV): ANSI256;
ansi256(...from: HSV): ANSI256;
hcg(from: HSV): HCG;
hcg(...from: HSV): HCG;
apple(from: HSV): Apple;
apple(...from: HSV): Apple;
gray(from: HSV): Gray;
gray(...from: HSV): Gray;
};
type hwb = {
rgb(from: HWB): RGB;
rgb(...from: HWB): RGB;
hsl(from: HWB): HSL;
hsl(...from: HWB): HSL;
hsv(from: HWB): HSV;
hsv(...from: HWB): HSV;
cmyk(from: HWB): CMYK;
cmyk(...from: HWB): CMYK;
xyz(from: HWB): XYZ;
xyz(...from: HWB): XYZ;
lab(from: HWB): LAB;
lab(...from: HWB): LAB;
lch(from: HWB): LCH;
lch(...from: HWB): LCH;
hex(from: HWB): HEX;
hex(...from: HWB): HEX;
keyword(from: HWB): Keyword;
keyword(...from: HWB): Keyword;
ansi16(from: HWB): ANSI16;
ansi16(...from: HWB): ANSI16;
ansi256(from: HWB): ANSI256;
ansi256(...from: HWB): ANSI256;
hcg(from: HWB): HCG;
hcg(...from: HWB): HCG;
apple(from: HWB): Apple;
apple(...from: HWB): Apple;
gray(from: HWB): Gray;
gray(...from: HWB): Gray;
};
type cmyk = {
rgb(from: CMYK): RGB;
rgb(...from: CMYK): RGB;
hsl(from: CMYK): HSL;
hsl(...from: CMYK): HSL;
hsv(from: CMYK): HSV;
hsv(...from: CMYK): HSV;
hwb(from: CMYK): HWB;
hwb(...from: CMYK): HWB;
xyz(from: CMYK): XYZ;
xyz(...from: CMYK): XYZ;
lab(from: CMYK): LAB;
lab(...from: CMYK): LAB;
lch(from: CMYK): LCH;
lch(...from: CMYK): LCH;
hex(from: CMYK): HEX;
hex(...from: CMYK): HEX;
keyword(from: CMYK): Keyword;
keyword(...from: CMYK): Keyword;
ansi16(from: CMYK): ANSI16;
ansi16(...from: CMYK): ANSI16;
ansi256(from: CMYK): ANSI256;
ansi256(...from: CMYK): ANSI256;
hcg(from: CMYK): HCG;
hcg(...from: CMYK): HCG;
apple(from: CMYK): Apple;
apple(...from: CMYK): Apple;
gray(from: CMYK): Gray;
gray(...from: CMYK): Gray;
};
type xyz = {
rgb(from: XYZ): RGB;
rgb(...from: XYZ): RGB;
hsl(from: XYZ): HSL;
hsl(...from: XYZ): HSL;
hsv(from: XYZ): HSV;
hsv(...from: XYZ): HSV;
hwb(from: XYZ): HWB;
hwb(...from: XYZ): HWB;
cmyk(from: XYZ): CMYK;
cmyk(...from: XYZ): CMYK;
lab(from: XYZ): LAB;
lab(...from: XYZ): LAB;
lch(from: XYZ): LCH;
lch(...from: XYZ): LCH;
hex(from: XYZ): HEX;
hex(...from: XYZ): HEX;
keyword(from: XYZ): Keyword;
keyword(...from: XYZ): Keyword;
ansi16(from: XYZ): ANSI16;
ansi16(...from: XYZ): ANSI16;
ansi256(from: XYZ): ANSI256;
ansi256(...from: XYZ): ANSI256;
hcg(from: XYZ): HCG;
hcg(...from: XYZ): HCG;
apple(from: XYZ): Apple;
apple(...from: XYZ): Apple;
gray(from: XYZ): Gray;
gray(...from: XYZ): Gray;
};
type lab = {
rgb(from: LAB): RGB;
rgb(...from: LAB): RGB;
hsl(from: LAB): HSL;
hsl(...from: LAB): HSL;
hsv(from: LAB): HSV;
hsv(...from: LAB): HSV;
hwb(from: LAB): HWB;
hwb(...from: LAB): HWB;
cmyk(from: LAB): CMYK;
cmyk(...from: LAB): CMYK;
xyz(from: LAB): XYZ;
xyz(...from: LAB): XYZ;
lch(from: LAB): LCH;
lch(...from: LAB): LCH;
hex(from: LAB): HEX;
hex(...from: LAB): HEX;
keyword(from: LAB): Keyword;
keyword(...from: LAB): Keyword;
ansi16(from: LAB): ANSI16;
ansi16(...from: LAB): ANSI16;
ansi256(from: LAB): ANSI256;
ansi256(...from: LAB): ANSI256;
hcg(from: LAB): HCG;
hcg(...from: LAB): HCG;
apple(from: LAB): Apple;
apple(...from: LAB): Apple;
gray(from: LAB): Gray;
gray(...from: LAB): Gray;
};
type lch = {
rgb(from: LCH): RGB;
rgb(...from: LCH): RGB;
hsl(from: LCH): HSL;
hsl(...from: LCH): HSL;
hsv(from: LCH): HSV;
hsv(...from: LCH): HSV;
hwb(from: LCH): HWB;
hwb(...from: LCH): HWB;
cmyk(from: LCH): CMYK;
cmyk(...from: LCH): CMYK;
xyz(from: LCH): XYZ;
xyz(...from: LCH): XYZ;
lab(from: LCH): LAB;
lab(...from: LCH): LAB;
hex(from: LCH): HEX;
hex(...from: LCH): HEX;
keyword(from: LCH): Keyword;
keyword(...from: LCH): Keyword;
ansi16(from: LCH): ANSI16;
ansi16(...from: LCH): ANSI16;
ansi256(from: LCH): ANSI256;
ansi256(...from: LCH): ANSI256;
hcg(from: LCH): HCG;
hcg(...from: LCH): HCG;
apple(from: LCH): Apple;
apple(...from: LCH): Apple;
gray(from: LCH): Gray;
gray(...from: LCH): Gray;
};
type hex = {
rgb(from: HEX): RGB;
hsl(from: HEX): HSL;
hsv(from: HEX): HSV;
hwb(from: HEX): HWB;
cmyk(from: HEX): CMYK;
xyz(from: HEX): XYZ;
lab(from: HEX): LAB;
lch(from: HEX): LCH;
keyword(from: HEX): Keyword;
ansi16(from: HEX): ANSI16;
ansi256(from: HEX): ANSI256;
hcg(from: HEX): HCG;
apple(from: HEX): Apple;
gray(from: HEX): Gray;
};
type keyword = {
rgb(from: Keyword): RGB;
hsl(from: Keyword): HSL;
hsv(from: Keyword): HSV;
hwb(from: Keyword): HWB;
cmyk(from: Keyword): CMYK;
xyz(from: Keyword): XYZ;
lab(from: Keyword): LAB;
lch(from: Keyword): LCH;
hex(from: Keyword): HEX;
ansi16(from: Keyword): ANSI16;
ansi256(from: Keyword): ANSI256;
hcg(from: Keyword): HCG;
apple(from: Keyword): Apple;
gray(from: Keyword): Gray;
};
type ansi16 = {
rgb(from: ANSI16): RGB;
hsl(from: ANSI16): HSL;
hsv(from: ANSI16): HSV;
hwb(from: ANSI16): HWB;
cmyk(from: ANSI16): CMYK;
xyz(from: ANSI16): XYZ;
lab(from: ANSI16): LAB;
lch(from: ANSI16): LCH;
hex(from: ANSI16): HEX;
keyword(from: ANSI16): Keyword;
ansi256(from: ANSI16): ANSI256;
hcg(from: ANSI16): HCG;
apple(from: ANSI16): Apple;
gray(from: ANSI16): Gray;
};
type ansi256 = {
rgb(from: ANSI256): RGB;
hsl(from: ANSI256): HSL;
hsv(from: ANSI256): HSV;
hwb(from: ANSI256): HWB;
cmyk(from: ANSI256): CMYK;
xyz(from: ANSI256): XYZ;
lab(from: ANSI256): LAB;
lch(from: ANSI256): LCH;
hex(from: ANSI256): HEX;
keyword(from: ANSI256): Keyword;
ansi16(from: ANSI256): ANSI16;
hcg(from: ANSI256): HCG;
apple(from: ANSI256): Apple;
gray(from: ANSI256): Gray;
};
type hcg = {
rgb(from: HCG): RGB;
rgb(...from: HCG): RGB;
hsl(from: HCG): HSL;
hsl(...from: HCG): HSL;
hsv(from: HCG): HSV;
hsv(...from: HCG): HSV;
hwb(from: HCG): HWB;
hwb(...from: HCG): HWB;
cmyk(from: HCG): CMYK;
cmyk(...from: HCG): CMYK;
xyz(from: HCG): XYZ;
xyz(...from: HCG): XYZ;
lab(from: HCG): LAB;
lab(...from: HCG): LAB;
lch(from: HCG): LCH;
lch(...from: HCG): LCH;
hex(from: HCG): HEX;
hex(...from: HCG): HEX;
keyword(from: HCG): Keyword;
keyword(...from: HCG): Keyword;
ansi16(from: HCG): ANSI16;
ansi16(...from: HCG): ANSI16;
ansi256(from: HCG): ANSI256;
ansi256(...from: HCG): ANSI256;
apple(from: HCG): Apple;
apple(...from: HCG): Apple;
gray(from: HCG): Gray;
gray(...from: HCG): Gray;
};
type apple = {
rgb(from: Apple): RGB;
rgb(...from: Apple): RGB;
hsl(from: Apple): HSL;
hsl(...from: Apple): HSL;
hsv(from: Apple): HSV;
hsv(...from: Apple): HSV;
hwb(from: Apple): HWB;
hwb(...from: Apple): HWB;
cmyk(from: Apple): CMYK;
cmyk(...from: Apple): CMYK;
xyz(from: Apple): XYZ;
xyz(...from: Apple): XYZ;
lab(from: Apple): LAB;
lab(...from: Apple): LAB;
lch(from: Apple): LCH;
lch(...from: Apple): LCH;
hex(from: Apple): HEX;
hex(...from: Apple): HEX;
keyword(from: Apple): Keyword;
keyword(...from: Apple): Keyword;
ansi16(from: Apple): ANSI16;
ansi16(...from: Apple): ANSI16;
ansi256(from: Apple): ANSI256;
ansi256(...from: Apple): ANSI256;
hcg(from: Apple): HCG;
hcg(...from: Apple): HCG;
gray(from: Apple): Gray;
gray(...from: Apple): Gray;
};
type gray = {
rgb(from: Gray): RGB;
rgb(...from: Gray): RGB;
hsl(from: Gray): HSL;
hsl(...from: Gray): HSL;
hsv(from: Gray): HSV;
hsv(...from: Gray): HSV;
hwb(from: Gray): HWB;
hwb(...from: Gray): HWB;
cmyk(from: Gray): CMYK;
cmyk(...from: Gray): CMYK;
xyz(from: Gray): XYZ;
xyz(...from: Gray): XYZ;
lab(from: Gray): LAB;
lab(...from: Gray): LAB;
lch(from: Gray): LCH;
lch(...from: Gray): LCH;
hex(from: Gray): HEX;
hex(...from: Gray): HEX;
keyword(from: Gray): Keyword;
keyword(...from: Gray): Keyword;
ansi16(from: Gray): ANSI16;
ansi16(...from: Gray): ANSI16;
ansi256(from: Gray): ANSI256;
ansi256(...from: Gray): ANSI256;
hcg(from: Gray): HCG;
hcg(...from: Gray): HCG;
apple(from: Gray): Apple;
apple(...from: Gray): Apple;
};
}
declare function route(fromModel: "rgb"): route.rgb;
declare function route(fromModel: "hsl"): route.hsl;
declare function route(fromModel: "hsv"): route.hsv;
declare function route(fromModel: "hwb"): route.hwb;
declare function route(fromModel: "cmyk"): route.cmyk;
declare function route(fromModel: "xyz"): route.xyz;
declare function route(fromModel: "lab"): route.lab;
declare function route(fromModel: "lch"): route.lch;
declare function route(fromModel: "hex"): route.hex;
declare function route(fromModel: "keyword"): route.keyword;
declare function route(fromModel: "ansi16"): route.ansi16;
declare function route(fromModel: "ansi256"): route.ansi256;
declare function route(fromModel: "hcg"): route.hcg;
declare function route(fromModel: "apple"): route.apple;
declare function route(fromModel: "gray"): route.gray;
type Convert = {
rgb: {
channels: Channels;
labels: "rgb";
hsl: {
(...rgb: RGB): HSL;
raw: (...rgb: RGB) => HSL;
};
hsv: {
(...rgb: RGB): HSV;
raw: (...rgb: RGB) => HSV;
};
hwb: {
(...rgb: RGB): HWB;
raw: (...rgb: RGB) => HWB;
};
hcg: {
(...rgb: RGB): HCG;
raw: (...rgb: RGB) => HCG;
};
cmyk: {
(...rgb: RGB): CMYK;
raw: (...rgb: RGB) => CMYK;
};
keyword: {
(...rgb: RGB): Keyword;
raw: (...rgb: RGB) => Keyword;
};
ansi16: {
(...rgb: RGB): ANSI16;
raw: (...rgb: RGB) => ANSI16;
};
ansi256: {
(...rgb: RGB): ANSI256;
raw: (...rgb: RGB) => ANSI256;
};
apple: {
(...rgb: RGB): Apple;
raw: (...rgb: RGB) => Apple;
};
hex: {
(...rgb: RGB): HEX;
raw: (...rgb: RGB) => HEX;
};
gray: {
(...rgb: RGB): Gray;
raw: (...rgb: RGB) => Gray;
};
} & route.rgb & {
[F in keyof route.rgb]: {
raw: route.rgb[F];
};
};
keyword: {
channels: Channels;
rgb: {
(keyword: Keyword): RGB;
raw: (keyword: Keyword) => RGB;
};
} & route.keyword & {
[F in keyof route.keyword]: {
raw: route.keyword[F];
};
};
hsl: {
channels: Channels;
labels: "hsl";
rgb: {
(...hsl: HSL): RGB;
raw: (...hsl: HSL) => RGB;
};
hsv: {
(...hsl: HSL): HSV;
raw: (...hsl: HSL) => HSV;
};
hcg: {
(...hsl: HSL): HCG;
raw: (...hsl: HSL) => HCG;
};
} & route.hsl & {
[F in keyof route.hsl]: {
raw: route.hsl[F];
};
};
hsv: {
channels: Channels;
labels: "hsv";
hcg: {
(...hsv: HSV): HCG;
raw: (...hsv: HSV) => HCG;
};
rgb: {
(...hsv: HSV): RGB;
raw: (...hsv: HSV) => RGB;
};
hsv: {
(...hsv: HSV): HSV;
raw: (...hsv: HSV) => HSV;
};
hsl: {
(...hsv: HSV): HSL;
raw: (...hsv: HSV) => HSL;
};
hwb: {
(...hsv: HSV): HWB;
raw: (...hsv: HSV) => HWB;
};
ansi16: {
(...hsv: HSV): ANSI16;
raw: (...hsv: HSV) => ANSI16;
};
} & route.hsv & {
[F in keyof route.hsv]: {
raw: route.hsv[F];
};
};
hwb: {
channels: Channels;
labels: "hwb";
hcg: {
(...hwb: HWB): HCG;
raw: (...hwb: HWB) => HCG;
};
rgb: {
(...hwb: HWB): RGB;
raw: (...hwb: HWB) => RGB;
};
} & route.hwb & {
[F in keyof route.hwb]: {
raw: route.hwb[F];
};
};
cmyk: {
channels: Channels;
labels: "cmyk";
rgb: {
(...cmyk: CMYK): RGB;
raw: (...cmyk: CMYK) => RGB;
};
} & route.cmyk & {
[F in keyof route.cmyk]: {
raw: route.cmyk[F];
};
};
xyz: {
channels: Channels;
labels: "xyz";
rgb: {
(...xyz: XYZ): RGB;
raw: (...xyz: XYZ) => RGB;
};
lab: {
(...xyz: XYZ): LAB;
raw: (...xyz: XYZ) => LAB;
};
} & route.xyz & {
[F in keyof route.xyz]: {
raw: route.xyz[F];
};
};
lab: {
channels: Channels;
labels: "lab";
xyz: {
(...lab: LAB): XYZ;
raw: (...lab: LAB) => XYZ;
};
lch: {
(...lab: LAB): LCH;
raw: (...lab: LAB) => LCH;
};
} & route.lab & {
[F in keyof route.lab]: {
raw: route.lab[F];
};
};
lch: {
channels: Channels;
labels: "lch";
lab: {
(...lch: LCH): LAB;
raw: (...lch: LCH) => LAB;
};
} & route.lch & {
[F in keyof route.lch]: {
raw: route.lch[F];
};
};
hex: {
channels: Channels;
labels: [
"hex"
];
rgb: {
(hex: HEX): RGB;
raw: (hex: HEX) => RGB;
};
} & route.hex & {
[F in keyof route.hex]: {
raw: route.hex[F];
};
};
ansi16: {
channels: Channels;
labels: [
"ansi16"
];
rgb: {
(ansi16: ANSI16): RGB;
raw: (ansi16: ANSI16) => RGB;
};
} & route.ansi16 & {
[F in keyof route.ansi16]: {
raw: route.ansi16[F];
};
};
ansi256: {
channels: Channels;
labels: [
"ansi256"
];
rgb: {
(ansi256: ANSI256): RGB;
raw: (ansi256: ANSI256) => RGB;
};
} & route.ansi256 & {
[F in keyof route.ansi256]: {
raw: route.ansi256[F];
};
};
hcg: {
channels: Channels;
labels: [
"h",
"c",
"g"
];
rgb: {
(...hcg: HCG): RGB;
raw: (...hcg: HCG) => RGB;
};
hsv: {
(...hcg: HCG): HSV;
raw: (...hcg: HCG) => HSV;
};
hwb: {
(...hcg: HCG): HWB;
raw: (...hcg: HCG) => HWB;
};
} & route.hcg & {
[F in keyof route.hcg]: {
raw: route.hcg[F];
};
};
apple: {
channels: Channels;
labels: [
"r16",
"g16",
"b16"
];
rgb: {
(...apple: Apple): RGB;
raw: (...apple: Apple) => RGB;
};
} & route.apple & {
[F in keyof route.apple]: {
raw: route.apple[F];
};
};
gray: {
channels: Channels;
labels: [
"gray"
];
rgb: {
(...gray: Gray): RGB;
raw: (...gray: Gray) => RGB;
};
hsl: {
(...gray: Gray): HSL;
raw: (...gray: Gray) => HSL;
};
hsv: {
(...gray: Gray): HSV;
raw: (...gray: Gray) => HSV;
};
hwb: {
(...gray: Gray): HWB;
raw: (...gray: Gray) => HWB;
};
cmyk: {
(...gray: Gray): CMYK;
raw: (...gray: Gray) => CMYK;
};
lab: {
(...gray: Gray): LAB;
raw: (...gray: Gray) => LAB;
};
hex: {
(...gray: Gray): HEX;
raw: (...gray: Gray) => HEX;
};
} & route.gray & {
[F in keyof route.gray]: {
raw: route.gray[F];
};
};
};
declare const convert: Convert;
export type ColorLike = ColorInstance | string | ArrayLike<number> | number | Record<string, any>;
export type ColorJson = {
model: string;
color: number[];
valpha: number;
};
export type ColorObject = {
alpha?: number | undefined;
} & Record<string, number>;
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export interface ColorInstance {
toString(): string;
// eslint-disable-next-line @typescript-eslint/naming-convention
toJSON(): ColorJson;
string(places?: number): string;
percentString(places?: number): string;
array(): number[];
object(): ColorObject;
unitArray(): number[];
unitObject(): {
r: number;
g: number;
b: number;
alpha?: number | undefined;
};
round(places?: number): ColorInstance;
alpha(): number;
alpha(value: number): ColorInstance;
red(): number;
red(value: number): ColorInstance;
green(): number;
green(value: number): ColorInstance;
blue(): number;
blue(value: number): ColorInstance;
hue(): number;
hue(value: number): ColorInstance;
saturationl(): number;
saturationl(value: number): ColorInstance;
lightness(): number;
lightness(value: number): ColorInstance;
saturationv(): number;
saturationv(value: number): ColorInstance;
value(): number;
value(value: number): ColorInstance;
chroma(): number;
chroma(value: number): ColorInstance;
gray(): number;
gray(value: number): ColorInstance;
white(): number;
white(value: number): ColorInstance;
wblack(): number;
wblack(value: number): ColorInstance;
cyan(): number;
cyan(value: number): ColorInstance;
magenta(): number;
magenta(value: number): ColorInstance;
yellow(): number;
yellow(value: number): ColorInstance;
black(): number;
black(value: number): ColorInstance;
x(): number;
x(value: number): ColorInstance;
y(): number;
y(value: number): ColorInstance;
z(): number;
z(value: number): ColorInstance;
l(): number;
l(value: number): ColorInstance;
a(): number;
a(value: number): ColorInstance;
b(): number;
b(value: number): ColorInstance;
keyword(): string;
keyword<V extends string>(value: V): ColorInstance;
hex(): string;
hex<V extends string>(value: V): ColorInstance;
hexa(): string;
hexa<V extends string>(value: V): ColorInstance;
rgbNumber(): number;
luminosity(): number;
contrast(color2: ColorInstance): number;
level(color2: ColorInstance): "AAA" | "AA" | "";
isDark(): boolean;
isLight(): boolean;
negate(): ColorInstance;
lighten(ratio: number): ColorInstance;
darken(ratio: number): ColorInstance;
saturate(ratio: number): ColorInstance;
desaturate(ratio: number): ColorInstance;
whiten(ratio: number): ColorInstance;
blacken(ratio: number): ColorInstance;
grayscale(): ColorInstance;
fade(ratio: number): ColorInstance;
opaquer(ratio: number): ColorInstance;
rotate(degrees: number): ColorInstance;
mix(mixinColor: ColorInstance, weight?: number): ColorInstance;
rgb(...arguments_: number[]): ColorInstance;
hsl(...arguments_: number[]): ColorInstance;
hsv(...arguments_: number[]): ColorInstance;
hwb(...arguments_: number[]): ColorInstance;
cmyk(...arguments_: number[]): ColorInstance;
xyz(...arguments_: number[]): ColorInstance;
lab(...arguments_: number[]): ColorInstance;
lch(...arguments_: number[]): ColorInstance;
ansi16(...arguments_: number[]): ColorInstance;
ansi256(...arguments_: number[]): ColorInstance;
hcg(...arguments_: number[]): ColorInstance;
apple(...arguments_: number[]): ColorInstance;
}
export type ColorConstructor = {
(object?: ColorLike, model?: keyof (typeof convert)): ColorInstance;
new (object?: ColorLike, model?: keyof (typeof convert)): ColorInstance;
rgb(...value: number[]): ColorInstance;
rgb(color: ColorLike): ColorInstance;
hsl(...value: number[]): ColorInstance;
hsl(color: ColorLike): ColorInstance;
hsv(...value: number[]): ColorInstance;
hsv(color: ColorLike): ColorInstance;
hwb(...value: number[]): ColorInstance;
hwb(color: ColorLike): ColorInstance;
cmyk(...value: number[]): ColorInstance;
cmyk(color: ColorLike): ColorInstance;
xyz(...value: number[]): ColorInstance;
xyz(color: ColorLike): ColorInstance;
lab(...value: number[]): ColorInstance;
lab(color: ColorLike): ColorInstance;
lch(...value: number[]): ColorInstance;
lch(color: ColorLike): ColorInstance;
ansi16(...value: number[]): ColorInstance;
ansi16(color: ColorLike): ColorInstance;
ansi256(...value: number[]): ColorInstance;
ansi256(color: ColorLike): ColorInstance;
hcg(...value: number[]): ColorInstance;
hcg(color: ColorLike): ColorInstance;
apple(...value: number[]): ColorInstance;
apple(color: ColorLike): ColorInstance;
};
// eslint-disable-next-line @typescript-eslint/naming-convention
declare const Color: ColorConstructor;
export {
Color as default,
};
export {};
@@ -0,0 +1,58 @@
{
"name": "@img/colour",
"version": "1.1.0",
"description": "The ESM-only 'color' package made compatible for use with CommonJS runtimes",
"license": "MIT",
"main": "index.cjs",
"types": "index.d.ts",
"exports": {
".": {
"types": "./index.d.ts",
"require": "./index.cjs",
"default": "./index.cjs"
},
"./package.json": "./package.json"
},
"authors": [
"Heather Arthur <fayearthur@gmail.com>",
"Josh Junon <josh@junon.me>",
"Maxime Thirouin",
"Dyma Ywanov <dfcreative@gmail.com>",
"LitoMore (https://github.com/LitoMore)"
],
"engines": {
"node": ">=18"
},
"files": [
"color.cjs",
"index.d.ts"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lovell/colour.git"
},
"type": "commonjs",
"keywords": [
"color",
"colour",
"cjs",
"commonjs"
],
"scripts": {
"build:cjs": "esbuild node_modules/color/index.js --bundle --platform=node --outfile=color.cjs",
"build:dts": "dts-bundle-generator ./dts-src.ts -o index.d.ts --project tsconfig.build.json --external-inlines color --external-inlines color-convert --export-referenced-types=false",
"build": "npm run build:cjs && npm run build:dts",
"test": "node --test"
},
"devDependencies": {
"color": "5.0.3",
"color-convert": "3.1.3",
"color-name": "2.1.0",
"color-string": "2.1.4",
"dts-bundle-generator": "^9.5.1",
"esbuild": "^0.27.3"
}
}
@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1,59 @@
# `@img/sharp-win32-arm64`
Prebuilt sharp for use with Windows 64-bit ARM.
## Licensing
Copyright 2013 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This software contains third-party libraries
used under the terms of the following licenses:
| Library | Used under the terms of |
|---------------|-----------------------------------------------------------------------------------------------------------|
| aom | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/) |
| cairo | Mozilla Public License 1.1 |
| cgif | MIT License |
| expat | MIT License |
| fontconfig | [fontconfig License](https://gitlab.freedesktop.org/fontconfig/fontconfig/blob/main/COPYING) (BSD-like) |
| freetype | [freetype License](https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT) (BSD-like) |
| fribidi | LGPLv3 |
| glib | LGPLv3 |
| harfbuzz | MIT License |
| highway | BSD 3-Clause |
| lcms | MIT License |
| libarchive | BSD 2-Clause |
| libexif | LGPLv3 |
| libffi | MIT License |
| libheif | LGPLv3 |
| libimagequant | [BSD 2-Clause](https://github.com/lovell/libimagequant/blob/main/COPYRIGHT) |
| libnsgif | MIT License |
| libpng | [libpng License](https://github.com/pnggroup/libpng/blob/master/LICENSE) |
| librsvg | LGPLv3 |
| libtiff | [libtiff License](https://gitlab.com/libtiff/libtiff/blob/master/LICENSE.md) (BSD-like) |
| libultrahdr | MIT License |
| libvips | LGPLv3 |
| libwebp | New BSD License |
| libxml2 | MIT License |
| mozjpeg | [zlib License, IJG License, BSD 3-Clause](https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md) |
| pango | LGPLv3 |
| pixman | MIT License |
| proxy-libintl | LGPLv3 |
| zlib-ng | [zlib License](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md) |
Use of libraries under the terms of the LGPLv3 is via the
"any later version" clause of the LGPLv2 or LGPLv2.1.
Please report any errors or omissions via
https://github.com/lovell/sharp-libvips/issues/new
@@ -0,0 +1 @@
module.exports = require('./lib/sharp-win32-arm64-0.35.5.node');
@@ -0,0 +1,40 @@
{
"name": "@img/sharp-win32-arm64",
"version": "0.35.5",
"description": "Prebuilt sharp for use with Windows 64-bit ARM",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://sharp.pixelplumbing.com",
"repository": {
"type": "git",
"url": "git+https://github.com/lovell/sharp.git",
"directory": "npm/win32-arm64"
},
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"funding": {
"url": "https://opencollective.com/libvips"
},
"preferUnplugged": true,
"files": [
"index.cjs",
"lib",
"versions.json"
],
"publishConfig": {
"access": "public"
},
"type": "commonjs",
"exports": {
"./sharp.node": "./index.cjs",
"./package": "./package.json",
"./versions": "./versions.json"
},
"engines": {
"node": ">=20.9.0"
},
"os": [
"win32"
],
"cpu": [
"arm64"
]
}
@@ -0,0 +1,30 @@
{
"aom": "3.15.1",
"archive": "3.8.9",
"cairo": "1.18.6",
"cgif": "0.5.4",
"exif": "0.6.26",
"expat": "2.8.5",
"ffi": "3.8.0",
"fontconfig": "2.18.3",
"freetype": "2.14.3",
"fribidi": "1.0.17",
"glib": "2.90.0",
"harfbuzz": "14.5.0",
"heif": "1.23.5",
"highway": "1.4.0",
"imagequant": "2.4.1",
"lcms": "2.19.1",
"mozjpeg": "0826579",
"pango": "1.58.2",
"pixman": "0.46.4",
"png": "1.6.58",
"proxy-libintl": "0.5",
"rsvg": "2.63.2",
"tiff": "4.7.2",
"uhdr": "2.0.2",
"vips": "8.18.7",
"webp": "1.6.0",
"xml2": "2.15.4",
"zlib-ng": "2.3.3"
}
@@ -0,0 +1,45 @@
{
"name": "@napi-rs/canvas-win32-arm64-msvc",
"version": "0.1.100",
"os": [
"win32"
],
"cpu": [
"arm64"
],
"main": "skia.win32-arm64-msvc.node",
"files": [
"skia.win32-arm64-msvc.node",
"icudtl.dat"
],
"description": "Canvas for Node.js with skia backend",
"keywords": [
"napi-rs",
"NAPI",
"N-API",
"Rust",
"node-addon",
"node-addon-api",
"canvas",
"image",
"pdf",
"svg",
"skia"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Brooooooklyn/canvas.git"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
}
}
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 lynweklm@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,448 @@
# `skr canvas`
[![CI](https://github.com/Brooooooklyn/canvas/actions/workflows/CI.yaml/badge.svg)](https://github.com/Brooooooklyn/canvas/actions/workflows/CI.yaml)
![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm148-hotpink)
[![install size](https://packagephobia.com/badge?p=@napi-rs/canvas)](https://packagephobia.com/result?p=@napi-rs/canvas)
[![Downloads](https://img.shields.io/npm/dm/@napi-rs/canvas.svg?sanitize=true)](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true)
> 🚀 Help me to become a full-time open-source developer by [sponsoring me on Github](https://github.com/sponsors/Brooooooklyn)
Google Skia binding to Node.js via [Node-API](https://napi.rs), **0 System dependencies!**
⚠️ This project is in pre-release stage. And there may be some bugs.<br/>
For details on planned features and future direction please refer to the [Roadmap](https://github.com/Brooooooklyn/canvas/issues/113).
[中文文档](./README-zh.md)
# Install
```bash
yarn add @napi-rs/canvas
npm install @napi-rs/canvas
```
# Support matrix
## System requirement
### `arm64`
[**_cortex-a57_**](https://en.wikipedia.org/wiki/ARM_Cortex-A57) or newer CPU architecture on **Linux**.
All Apple M chips on **macOS**.
### `armv7`
[**_cortex-a7_**](https://en.wikipedia.org/wiki/ARM_Cortex-A7) or newer CPU architecture.
### glibc
Since Skia relies on the [glibc](https://www.gnu.org/software/libc/) 2.18 API, you need to have at least glibc version >= 2.18 on your system.
## AWS Lambda usage
To use this library on Lambda you will need to use a Lambda layer.
You can simply attach a lambda layer by getting an ARN from [Canvas-Lambda-Layer](https://github.com/ShivamJoker/Canvas-Lambda-Layer)
> Make sure to exclude `@napi-rs/canvas` while bundling your Lambda.
# Usage
```js
const { promises } = require('node:fs')
const { join } = require('node:path')
const { createCanvas, loadImage } = require('@napi-rs/canvas')
const canvas = createCanvas(300, 320)
const ctx = canvas.getContext('2d')
ctx.lineWidth = 10
ctx.strokeStyle = '#03a9f4'
ctx.fillStyle = '#03a9f4'
// Wall
ctx.strokeRect(75, 140, 150, 110)
// Door
ctx.fillRect(130, 190, 40, 60)
// Roof
ctx.beginPath()
ctx.moveTo(50, 140)
ctx.lineTo(150, 60)
ctx.lineTo(250, 140)
ctx.closePath()
ctx.stroke()
async function main() {
// load images from disk or from a URL
const catImage = await loadImage('path/to/cat.png')
const dogImage = await loadImage('https://example.com/path/to/dog.jpg')
ctx.drawImage(catImage, 0, 0, catImage.width, catImage.height)
ctx.drawImage(dogImage, canvas.width / 2, canvas.height / 2, dogImage.width, dogImage.height)
// export canvas as image
const pngData = await canvas.encode('png') // JPEG, AVIF and WebP are also supported
// encoding in libuv thread pool, non-blocking
await promises.writeFile(join(__dirname, 'simple.png'), pngData)
}
main()
```
![](./example/simple.png)
## Emoji text
```js
const { writeFileSync } = require('fs')
const { join } = require('path')
const { createCanvas, GlobalFonts } = require('@napi-rs/canvas')
GlobalFonts.registerFromPath(join(__dirname, '..', 'fonts', 'AppleColorEmoji@2x.ttf'), 'Apple Emoji')
GlobalFonts.registerFromPath(join(__dirname, '..', '__test__', 'fonts', 'COLRv1.ttf'), 'COLRv1')
console.info(GlobalFonts.families)
const canvas = createCanvas(760, 360)
const ctx = canvas.getContext('2d')
ctx.font = '50px Apple Emoji'
ctx.strokeText('😀😃😄😁😆😅😂🤣☺️😊😊😇', 50, 150)
ctx.font = '100px COLRv1'
ctx.fillText('abc', 50, 300)
const b = canvas.toBuffer('image/png')
writeFileSync(join(__dirname, 'draw-emoji.png'), b)
```
![](./example/draw-emoji.png)
# Performance
See [benchmark](./benchmark) for benchmark code.
Hardware info:
```
,MMMM. Host - xxxxxxxxxxxxxxxxxxxxxxx
.MMMMMM Machine - Mac15,9
MMMMM, Kernel - 24.0.0
.;MMMMM:' MMMMMMMMMM;. OS - macOS 15.0.1 Sequoia
MMMMMMMMMMMMNWMMMMMMMMMMM: DE - Aqua
.MMMMMMMMMMMMMMMMMMMMMMMMWM. WM - Quartz Compositor
MMMMMMMMMMMMMMMMMMMMMMMMM. Packages - 194 (Homebrew), 32 (cargo)
;MMMMMMMMMMMMMMMMMMMMMMMM: Shell - zsh
:MMMMMMMMMMMMMMMMMMMMMMMM: Terminal - warpterminal (Version v0.2024.10.23.14.49.stable_00)
.MMMMMMMMMMMMMMMMMMMMMMMMM. Resolution - 5120x2880@160fps (as 2560x1440)
MMMMMMMMMMMMMMMMMMMMMMMMMMM. 2992x1934@120fps (as 1496x967)
.MMMMMMMMMMMMMMMMMMMMMMMMMM. 2232x1512@60fps (as 1116x756)
MMMMMMMMMMMMMMMMMMMMMMMM Uptime - 1d 2h 32m
;MMMMMMMMMMMMMMMMMMMM. CPU - Apple M3 Max (16)
.MMMM,. .MMMM,. CPU Load - 16%
Memory - 50.1 GB / 134.2 GB
Battery - 78% & Discharging
Disk Space - 624.0 GB / 994.7 GB
```
```
❯ yarn bench
Draw a House and export to PNG
┌─────────┬─────────────────┬───────────────────────┬──────────────────────────┬────────────────────────────┬───────────────────────────┬─────────┐
│ (index) │ Task name │ Latency average (ns) │ Latency median (ns) │ Throughput average (ops/s) │ Throughput median (ops/s) │ Samples │
├─────────┼─────────────────┼───────────────────────┼──────────────────────────┼────────────────────────────┼───────────────────────────┼─────────┤
│ 0 │ '@napi-rs/skia' │ '14676992.14 ± 0.68%' │ '14602333.00' │ '68 ± 0.59%' │ '68' │ 69 │
│ 1 │ 'skia-canvas' │ '21167809.17 ± 2.05%' │ '20960021.00 ± 13646.00' │ '47 ± 1.31%' │ '48' │ 64 │
│ 2 │ 'node-canvas' │ '16552027.42 ± 0.70%' │ '16451291.50 ± 2208.50' │ '60 ± 0.62%' │ '61' │ 64 │
└─────────┴─────────────────┴───────────────────────┴──────────────────────────┴────────────────────────────┴───────────────────────────┴─────────┘
Draw Gradient and export to PNG
┌─────────┬─────────────────┬───────────────────────┬─────────────────────────┬────────────────────────────┬───────────────────────────┬─────────┐
│ (index) │ Task name │ Latency average (ns) │ Latency median (ns) │ Throughput average (ops/s) │ Throughput median (ops/s) │ Samples │
├─────────┼─────────────────┼───────────────────────┼─────────────────────────┼────────────────────────────┼───────────────────────────┼─────────┤
│ 0 │ '@napi-rs/skia' │ '15228495.58 ± 0.53%' │ '15146312.50 ± 1187.50' │ '66 ± 0.48%' │ '66' │ 66 │
│ 1 │ 'skia-canvas' │ '21725564.41 ± 2.20%' │ '21412520.50 ± 2104.50' │ '46 ± 1.39%' │ '47' │ 64 │
│ 2 │ 'node-canvas' │ '17976022.14 ± 1.53%' │ '17563479.50 ± 5104.50' │ '56 ± 1.38%' │ '57' │ 64 │
└─────────┴─────────────────┴───────────────────────┴─────────────────────────┴────────────────────────────┴───────────────────────────┴─────────┘
```
# Features
## Path2D
```typescript
new Path2D()
new Path2D(path: Path2D)
// new Path2D('M108.956,403.826c0,0,0.178,3.344-1.276,3.311 c-1.455-0.033-30.507-84.917-66.752-80.957C40.928,326.18,72.326,313.197,108.956,403.826z')
new Path2D(path: string)
```
```typescript
export interface DOMMatrix2DInit {
a: number
b: number
c: number
d: number
e: number
f: number
}
export class Path2D {
constructor(path?: Path2D | string)
addPath(path: Path2D, transform?: DOMMatrix2DInit): void
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void
closePath(): void
ellipse(
x: number,
y: number,
radiusX: number,
radiusY: number,
rotation: number,
startAngle: number,
endAngle: number,
anticlockwise?: boolean,
): void
lineTo(x: number, y: number): void
moveTo(x: number, y: number): void
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void
rect(x: number, y: number, w: number, h: number): void
// PathKit methods
op(path: Path2D, operation: PathOp): Path2D
toSVGString(): string
getFillType(): FillType
getFillTypeString(): string
setFillType(type: FillType): void
simplify(): Path2D
asWinding(): Path2D
stroke(stroke?: StrokeOptions): Path2D
transform(transform: DOMMatrix2DInit): Path2D
getBounds(): [left: number, top: number, right: number, bottom: number]
computeTightBounds(): [left: number, top: number, right: number, bottom: number]
trim(start: number, end: number, isComplement?: boolean): Path2D
round(radius: number): Path2D
equals(path: Path2D): boolean
}
```
## PathKit
`PathKit` is a toolset for manipulating Path in `Skia`, supporting **_quadratic beziers_**, **_cubic beziers_** and **_conics_**.
The main features are.
### Path Operation
`.op(path, PathOp)`
```js
const pathOne = new Path2D(
'M8 50H92C96.4183 50 100 53.5817 100 58V142C100 146.418 96.4183 150 92 150H8C3.58172 150 0 146.418 0 142V58C0 53.5817 3.58172 50 8 50Z',
)
const pathTwo = new Path2D(
'"M58 0H142C146.418 0 150 3.58172 150 8V92C150 96.4183 146.418 100 142 100H58C53.5817 100 50 96.4183 50 92V8C50 3.58172 53.5817 0 58 0Z',
)
pathOne.op(pathTwo, PathOp.Intersect).toSVGString()
// => "M100 100L58 100C53.5817 100 50 96.4183 50 92L50 50L92 50C96.4183 50 100 53.5817 100 58L100 100Z"
```
- **Union**, subtract the op path from the first path
- **Difference**, intersect the two paths
- **ReverseDifference**, union (inclusive-or) the two paths
- **Intersect**, exclusive-or the two paths
- **XOR**, subtract the first path from the op path
![boolean-operations](./docs/imgs/boolean-operations.svg)
### Covert `FillType` in **_Path_**
`.asWinding()`
You can convert `fill-rule="evenodd"` to `fill-rule="nonzero"` in SVG.
This is useful for **OpenType** font-related tools, as `fill-rule="nonzero"` is only supported in **OpenType** fonts.
![SVG fill-rule](./docs/imgs/asWinding@2x.png)
```js
const pathCircle = new Path2D(
'M24.2979 13.6364H129.394V40.9091H24.2979L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455H70.4673V68.1818H16.073C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727V113.636C7.00728 118.657 11.0661 122.727 16.073 122.727H70.4673V150H84.0658V122.727H128.041C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818H84.0658V54.5455H133.927C138.934 54.5455 142.993 50.4755 142.993 45.4545V9.09091C142.993 4.07014 138.934 0 133.927 0H21.9592ZM125.702 109.091H20.6058V81.8182H125.702L135.372 95.4545L125.702 109.091Z',
)
pathCircle.setFillType(FillType.EvenOdd)
pathCircle.asWinding().toSVGString()
// => "M24.2979 13.6364L129.394 13.6364L129.394 40.9091L24.2979 40.9091L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455L70.4673 54.5455L70.4673 68.1818L16.073 68.1818C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727L7.00728 113.636C7.00728 118.657 11.0661 122.727 16.073 122.727L70.4673 122.727L70.4673 150L84.0658 150L84.0658 122.727L128.041 122.727C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818L84.0658 68.1818L84.0658 54.5455L133.927 54.5455C138.934 54.5455 142.993 50.4755 142.993 45.4545L142.993 9.09091C142.993 4.07014 138.934 0 133.927 0L21.9592 0ZM125.702 109.091L20.6058 109.091L20.6058 81.8182L125.702 81.8182L135.372 95.4545L125.702 109.091Z"
```
### Simplify **_Path_**
`.simplify()`
Set the path to the same non-overlapping contour as the original path area, which means that it can also remove overlapping paths.
<img width="800" src="./docs/imgs/simplify.png" >
[SVG with overlapping paths](./docs/imgs/overlapping-path.svg) (Left)
```js
const path =
'M2.933,89.89 L89.005,3.818 Q90.412,2.411 92.249,1.65 Q94.087,0.889 96.076,0.889 Q98.065,0.889 99.903,1.65 Q101.741,2.411 103.147,3.818 L189.22,89.89 Q190.626,91.296 191.387,93.134 Q192.148,94.972 192.148,96.961 Q192.148,98.95 191.387,100.788 Q190.626,102.625 189.219,104.032 Q187.813,105.439 185.975,106.2 Q184.138,106.961 182.148,106.961 Q180.159,106.961 178.322,106.2 Q176.484,105.439 175.077,104.032 L89.005,17.96 L96.076,10.889 L103.147,17.96 L17.075,104.032 Q15.668,105.439 13.831,106.2 Q11.993,106.961 10.004,106.961 Q8.015,106.961 6.177,106.2 Q4.339,105.439 2.933,104.032 Q1.526,102.625 0.765,100.788 Q0.004,98.95 0.004,96.961 Q0.004,94.972 0.765,93.134 Q1.526,91.296 2.933,89.89 Z'
path.simplify().toSVGString()
// => "M89.005 3.818L2.933 89.89Q1.526 91.296 0.765 93.134Q0.004 94.972 0.004 96.961Q0.004 98.95 0.765 100.788Q1.526 102.625 2.933 104.032Q4.339 105.439 6.177 106.2Q8.015 106.961 10.004 106.961Q11.993 106.961 13.831 106.2Q15.668 105.439 17.075 104.032L96.076 25.031L175.077 104.032Q176.484 105.439 178.322 106.2Q180.159 106.961 182.148 106.961Q184.138 106.961 185.975 106.2Q187.813 105.439 189.219 104.032Q190.626 102.625 191.387 100.788Q192.148 98.95 192.148 96.961Q192.148 94.972 191.387 93.134Q190.626 91.296 189.22 89.89L103.147 3.818Q101.741 2.411 99.903 1.65Q98.065 0.889 96.076 0.889Q94.087 0.889 92.249 1.65Q90.412 2.411 89.005 3.818Z"
```
## Lottie Animation
Render [Lottie](https://airbnb.io/lottie/) animations using Skia's [Skottie](https://skia.org/docs/user/modules/skottie/) module.
### Load Animation
```js
const { LottieAnimation } = require('@napi-rs/canvas')
// Load from file
const animation = LottieAnimation.loadFromFile('animation.json')
// Load from JSON string with resource path for external assets
const animation = LottieAnimation.loadFromData(jsonString, {
resourcePath: '/path/to/assets',
})
```
### Animation Properties
```js
animation.duration // Total duration in seconds
animation.fps // Frames per second
animation.frames // Total frame count
animation.width // Animation width
animation.height // Animation height
animation.version // Lottie format version
```
### Playback Control
```js
animation.seekFrame(30) // Seek to frame 30
animation.seek(1.5) // Seek to 1.5 seconds
```
### Render to Canvas
```js
const { createCanvas, LottieAnimation } = require('@napi-rs/canvas')
const animation = LottieAnimation.loadFromFile('animation.json')
const canvas = createCanvas(animation.width, animation.height)
const ctx = canvas.getContext('2d')
// Render at original size
animation.render(ctx)
// Render with custom destination rect
animation.render(ctx, { x: 0, y: 0, width: 800, height: 600 })
```
### Supported Features
- **Embedded images** - Base64-encoded images (`data:image/png;base64,...`)
- **Embedded fonts** - Vector glyph paths for text rendering without system fonts
- **External assets** - Load images from `resourcePath` directory
- **dotLottie format** - Extract `.lottie` ZIP files at runtime (see example)
### Example: Encode Lottie to Video
See [`example/lottie-to-video.ts`](./example/lottie-to-video.ts) for encoding Lottie animations to MP4 using [`@napi-rs/webcodecs`](https://github.com/Brooooooklyn/webcodecs-node).
```js
import { createCanvas, LottieAnimation } from '@napi-rs/canvas'
import {
VideoEncoder,
VideoFrame,
Mp4Muxer,
type EncodedVideoChunk,
type EncodedVideoChunkMetadata,
} from '@napi-rs/webcodecs'
const animation = LottieAnimation.loadFromFile('animation.json')
const canvas = createCanvas(animation.width, animation.height)
const ctx = canvas.getContext('2d')
for (let frame = 0; frame < animation.frames; frame++) {
animation.seekFrame(frame)
ctx.fillStyle = '#ffffff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
animation.render(ctx)
// Encode frame to video...
}
```
# [Example](./example/tiger.js)
> The tiger.json was serialized from [gojs/samples/tiger](https://github.com/NorthwoodsSoftware/GoJS/blob/master/samples/tiger.html)
<img width="500" src="example/tiger.png">
```shell
node example/anime-girl.js
```
| SVG | PNG |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <img width="500" src="example/anime-girl.svg"><br/>[CC-BY-SA 3.0](https://creativecommons.org/licenses/by/3.0) by [Niabot](https://commons.wikimedia.org/wiki/User:Niabot) | <img width="500" src="example/anime-girl.png"><br/>[CC-BY-SA 3.0](https://creativecommons.org/licenses/by/3.0) by [Niabot](https://commons.wikimedia.org/wiki/User:Niabot) |
# Building
## Build skia from source
You can build this project from source, the system requirements are here: https://skia.org/docs/user/build
```sh
# Clone the code:
$ git clone --recurse-submodules https://github.com/Brooooooklyn/canvas.git
$ cd canvas
# Build Skia:
$ node scripts/build-skia.js
# Install NPM packages, build the Node.js addon:
$ npm install -g yarn
$ yarn install --mode=skip-build # Here are modules that are used for benchmarking and are hard to install, you can skip it by specifying `--mode=skip-build`
$ sudo dnf install clang # https://fedora.pkgs.org/34/fedora-x86_64/clang-12.0.0-0.3.rc1.fc34.x86_64.rpm.html
$ yarn build
# All done! Run test cases or examples now:
$ yarn test
$ node example/tiger.js
```
## Pull pre-build skia binary from GitHub
You can pull skia pre-build binaries if you just care the `Rust` part:
```sh
# Clone the code:
$ git clone --recurse-submodules https://github.com/Brooooooklyn/canvas.git
$ cd canvas
# Download Skia binaries:
# It will pull the binaries match the git hash in `./skia` submodule
$ node scripts/release-skia-binary.mjs --download
# Install NPM packages, build the Node.js addon:
$ npm install -g yarn
$ yarn install --mode=skip-build
$ sudo dnf install clang # https://fedora.pkgs.org/34/fedora-x86_64/clang-12.0.0-0.3.rc1.fc34.x86_64.rpm.html
$ yarn build
# All done! Run test cases or examples now:
$ yarn test
$ node example/tiger.js
```
@@ -0,0 +1,873 @@
const { inspect } = require('util')
/*
* vendored in order to fix its dependence on the window global [cds 2020/08/04]
* otherwise unchanged from https://github.com/jarek-foksa/geometry-polyfill/tree/f36bbc8f4bc43539d980687904ce46c8e915543d
*/
// @info
// DOMPoint polyfill
// @src
// https://drafts.fxtf.org/geometry/#DOMPoint
// https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_point_read_only.cc
class DOMPoint {
constructor(x = 0, y = 0, z = 0, w = 1) {
this.x = x
this.y = y
this.z = z
this.w = w
}
static fromPoint(otherPoint) {
return new DOMPoint(
otherPoint.x,
otherPoint.y,
otherPoint.z !== undefined ? otherPoint.z : 0,
otherPoint.w !== undefined ? otherPoint.w : 1,
)
}
matrixTransform(matrix) {
if ((matrix.is2D || matrix instanceof SVGMatrix) && this.z === 0 && this.w === 1) {
return new DOMPoint(
this.x * matrix.a + this.y * matrix.c + matrix.e,
this.x * matrix.b + this.y * matrix.d + matrix.f,
0,
1,
)
} else {
return new DOMPoint(
this.x * matrix.m11 + this.y * matrix.m21 + this.z * matrix.m31 + this.w * matrix.m41,
this.x * matrix.m12 + this.y * matrix.m22 + this.z * matrix.m32 + this.w * matrix.m42,
this.x * matrix.m13 + this.y * matrix.m23 + this.z * matrix.m33 + this.w * matrix.m43,
this.x * matrix.m14 + this.y * matrix.m24 + this.z * matrix.m34 + this.w * matrix.m44,
)
}
}
toJSON() {
return {
x: this.x,
y: this.y,
z: this.z,
w: this.w,
}
}
}
// @info
// DOMRect polyfill
// @src
// https://drafts.fxtf.org/geometry/#DOMRect
// https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc
class DOMRect {
constructor(x = 0, y = 0, width = 0, height = 0) {
this.x = x
this.y = y
this.width = width
this.height = height
}
static fromRect(otherRect) {
return new DOMRect(otherRect.x, otherRect.y, otherRect.width, otherRect.height)
}
get top() {
return this.y
}
get left() {
return this.x
}
get right() {
return this.x + this.width
}
get bottom() {
return this.y + this.height
}
toJSON() {
return {
x: this.x,
y: this.y,
width: this.width,
height: this.height,
top: this.top,
left: this.left,
right: this.right,
bottom: this.bottom,
}
}
}
for (const propertyName of ['top', 'right', 'bottom', 'left']) {
const propertyDescriptor = Object.getOwnPropertyDescriptor(DOMRect.prototype, propertyName)
propertyDescriptor.enumerable = true
Object.defineProperty(DOMRect.prototype, propertyName, propertyDescriptor)
}
// @info
// DOMMatrix polyfill (SVG 2)
// @src
// https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
// https://github.com/tocharomera/generativecanvas/blob/master/node-canvas/lib/DOMMatrix.js
const M11 = 0,
M12 = 1,
M13 = 2,
M14 = 3
const M21 = 4,
M22 = 5,
M23 = 6,
M24 = 7
const M31 = 8,
M32 = 9,
M33 = 10,
M34 = 11
const M41 = 12,
M42 = 13,
M43 = 14,
M44 = 15
const A = M11,
B = M12
const C = M21,
D = M22
const E = M41,
F = M42
const DEGREE_PER_RAD = 180 / Math.PI
const RAD_PER_DEGREE = Math.PI / 180
const VALUES = Symbol('values')
const IS_2D = Symbol('is2D')
function parseMatrix(init) {
let parsed = init.replace(/matrix\(/, '').split(/,/, 7)
if (parsed.length !== 6) {
throw new Error(`Failed to parse ${init}`)
}
parsed = parsed.map(parseFloat)
return [parsed[0], parsed[1], 0, 0, parsed[2], parsed[3], 0, 0, 0, 0, 1, 0, parsed[4], parsed[5], 0, 1]
}
function parseMatrix3d(init) {
const parsed = init.replace(/matrix3d\(/, '').split(/,/, 17)
if (parsed.length !== 16) {
throw new Error(`Failed to parse ${init}`)
}
return parsed.map(parseFloat)
}
function parseTransform(tform) {
const type = tform.split(/\(/, 1)[0]
if (type === 'matrix') {
return parseMatrix(tform)
} else if (type === 'matrix3d') {
return parseMatrix3d(tform)
} else {
throw new Error(`${type} parsing not implemented`)
}
}
const setNumber2D = (receiver, index, value) => {
if (typeof value !== 'number') {
throw new TypeError('Expected number')
}
receiver[VALUES][index] = value
}
const setNumber3D = (receiver, index, value) => {
if (typeof value !== 'number') {
throw new TypeError('Expected number')
}
if (index === M33 || index === M44) {
if (value !== 1) {
receiver[IS_2D] = false
}
} else if (value !== 0) {
receiver[IS_2D] = false
}
receiver[VALUES][index] = value
}
const newInstance = (values) => {
const instance = Object.create(DOMMatrix.prototype)
instance.constructor = DOMMatrix
instance[IS_2D] = true
instance[VALUES] = values
return instance
}
const multiply = (first, second) => {
const dest = new Float64Array(16)
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let sum = 0
for (let k = 0; k < 4; k++) {
sum += first[i * 4 + k] * second[k * 4 + j]
}
dest[i * 4 + j] = sum
}
}
return dest
}
class DOMMatrix {
get m11() {
return this[VALUES][M11]
}
set m11(value) {
setNumber2D(this, M11, value)
}
get m12() {
return this[VALUES][M12]
}
set m12(value) {
setNumber2D(this, M12, value)
}
get m13() {
return this[VALUES][M13]
}
set m13(value) {
setNumber3D(this, M13, value)
}
get m14() {
return this[VALUES][M14]
}
set m14(value) {
setNumber3D(this, M14, value)
}
get m21() {
return this[VALUES][M21]
}
set m21(value) {
setNumber2D(this, M21, value)
}
get m22() {
return this[VALUES][M22]
}
set m22(value) {
setNumber2D(this, M22, value)
}
get m23() {
return this[VALUES][M23]
}
set m23(value) {
setNumber3D(this, M23, value)
}
get m24() {
return this[VALUES][M24]
}
set m24(value) {
setNumber3D(this, M24, value)
}
get m31() {
return this[VALUES][M31]
}
set m31(value) {
setNumber3D(this, M31, value)
}
get m32() {
return this[VALUES][M32]
}
set m32(value) {
setNumber3D(this, M32, value)
}
get m33() {
return this[VALUES][M33]
}
set m33(value) {
setNumber3D(this, M33, value)
}
get m34() {
return this[VALUES][M34]
}
set m34(value) {
setNumber3D(this, M34, value)
}
get m41() {
return this[VALUES][M41]
}
set m41(value) {
setNumber2D(this, M41, value)
}
get m42() {
return this[VALUES][M42]
}
set m42(value) {
setNumber2D(this, M42, value)
}
get m43() {
return this[VALUES][M43]
}
set m43(value) {
setNumber3D(this, M43, value)
}
get m44() {
return this[VALUES][M44]
}
set m44(value) {
setNumber3D(this, M44, value)
}
get a() {
return this[VALUES][A]
}
set a(value) {
setNumber2D(this, A, value)
}
get b() {
return this[VALUES][B]
}
set b(value) {
setNumber2D(this, B, value)
}
get c() {
return this[VALUES][C]
}
set c(value) {
setNumber2D(this, C, value)
}
get d() {
return this[VALUES][D]
}
set d(value) {
setNumber2D(this, D, value)
}
get e() {
return this[VALUES][E]
}
set e(value) {
setNumber2D(this, E, value)
}
get f() {
return this[VALUES][F]
}
set f(value) {
setNumber2D(this, F, value)
}
get is2D() {
return this[IS_2D]
}
get isIdentity() {
const values = this[VALUES]
return (
values[M11] === 1 &&
values[M12] === 0 &&
values[M13] === 0 &&
values[M14] === 0 &&
values[M21] === 0 &&
values[M22] === 1 &&
values[M23] === 0 &&
values[M24] === 0 &&
values[M31] === 0 &&
values[M32] === 0 &&
values[M33] === 1 &&
values[M34] === 0 &&
values[M41] === 0 &&
values[M42] === 0 &&
values[M43] === 0 &&
values[M44] === 1
)
}
static fromMatrix(init) {
if (init instanceof DOMMatrix) {
return new DOMMatrix(init[VALUES])
} else if (init instanceof SVGMatrix) {
return new DOMMatrix([init.a, init.b, init.c, init.d, init.e, init.f])
} else {
throw new TypeError('Expected DOMMatrix')
}
}
static fromFloat32Array(init) {
if (!(init instanceof Float32Array)) throw new TypeError('Expected Float32Array')
return new DOMMatrix(init)
}
static fromFloat64Array(init) {
if (!(init instanceof Float64Array)) throw new TypeError('Expected Float64Array')
return new DOMMatrix(init)
}
// @type
// (Float64Array) => void
constructor(init) {
this[IS_2D] = true
this[VALUES] = new Float64Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
// Parse CSS transformList
if (typeof init === 'string') {
if (init === '') {
return
} else {
const tforms = init.split(/\)\s+/, 20).map(parseTransform)
if (tforms.length === 0) {
return
}
init = tforms[0]
for (let i = 1; i < tforms.length; i++) {
init = multiply(tforms[i], init)
}
}
}
let i = 0
if (init && init.length === 6) {
setNumber2D(this, A, init[i++])
setNumber2D(this, B, init[i++])
setNumber2D(this, C, init[i++])
setNumber2D(this, D, init[i++])
setNumber2D(this, E, init[i++])
setNumber2D(this, F, init[i++])
} else if (init && init.length === 16) {
setNumber2D(this, M11, init[i++])
setNumber2D(this, M12, init[i++])
setNumber3D(this, M13, init[i++])
setNumber3D(this, M14, init[i++])
setNumber2D(this, M21, init[i++])
setNumber2D(this, M22, init[i++])
setNumber3D(this, M23, init[i++])
setNumber3D(this, M24, init[i++])
setNumber3D(this, M31, init[i++])
setNumber3D(this, M32, init[i++])
setNumber3D(this, M33, init[i++])
setNumber3D(this, M34, init[i++])
setNumber2D(this, M41, init[i++])
setNumber2D(this, M42, init[i++])
setNumber3D(this, M43, init[i++])
setNumber3D(this, M44, init[i])
} else if (init !== undefined) {
throw new TypeError('Expected string or array.')
}
}
dump() {
const mat = this[VALUES]
console.info([mat.slice(0, 4), mat.slice(4, 8), mat.slice(8, 12), mat.slice(12, 16)])
}
[inspect.custom](depth) {
if (depth < 0) return '[DOMMatrix]'
const { a, b, c, d, e, f, is2D, isIdentity } = this
if (this.is2D) {
return `DOMMatrix ${inspect({ a, b, c, d, e, f, is2D, isIdentity }, { colors: true })}`
} else {
const { m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, is2D, isIdentity } = this
return `DOMMatrix ${inspect(
{
a,
b,
c,
d,
e,
f,
m11,
m12,
m13,
m14,
m21,
m22,
m23,
m24,
m31,
m32,
m33,
m34,
m41,
m42,
m43,
m44,
is2D,
isIdentity,
},
{ colors: true },
)}`
}
}
multiply(other) {
return newInstance(this[VALUES]).multiplySelf(other)
}
multiplySelf(other) {
this[VALUES] = multiply(other[VALUES], this[VALUES])
if (!other.is2D) {
this[IS_2D] = false
}
return this
}
preMultiplySelf(other) {
this[VALUES] = multiply(this[VALUES], other[VALUES])
if (!other.is2D) {
this[IS_2D] = false
}
return this
}
translate(tx, ty, tz) {
return newInstance(this[VALUES]).translateSelf(tx, ty, tz)
}
translateSelf(tx = 0, ty = 0, tz = 0) {
this[VALUES] = multiply([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1], this[VALUES])
if (tz !== 0) {
this[IS_2D] = false
}
return this
}
scale(scaleX, scaleY, scaleZ, originX, originY, originZ) {
return newInstance(this[VALUES]).scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ)
}
scale3d(scale, originX, originY, originZ) {
return newInstance(this[VALUES]).scale3dSelf(scale, originX, originY, originZ)
}
scale3dSelf(scale, originX, originY, originZ) {
return this.scaleSelf(scale, scale, scale, originX, originY, originZ)
}
scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) {
// Not redundant with translate's checks because we need to negate the values later.
if (typeof originX !== 'number') originX = 0
if (typeof originY !== 'number') originY = 0
if (typeof originZ !== 'number') originZ = 0
this.translateSelf(originX, originY, originZ)
if (typeof scaleX !== 'number') scaleX = 1
if (typeof scaleY !== 'number') scaleY = scaleX
if (typeof scaleZ !== 'number') scaleZ = 1
this[VALUES] = multiply([scaleX, 0, 0, 0, 0, scaleY, 0, 0, 0, 0, scaleZ, 0, 0, 0, 0, 1], this[VALUES])
this.translateSelf(-originX, -originY, -originZ)
if (scaleZ !== 1 || originZ !== 0) {
this[IS_2D] = false
}
return this
}
rotateFromVector(x, y) {
return newInstance(this[VALUES]).rotateFromVectorSelf(x, y)
}
rotateFromVectorSelf(x = 0, y = 0) {
const theta = x === 0 && y === 0 ? 0 : Math.atan2(y, x) * DEGREE_PER_RAD
return this.rotateSelf(theta)
}
rotate(rotX, rotY, rotZ) {
return newInstance(this[VALUES]).rotateSelf(rotX, rotY, rotZ)
}
rotateSelf(rotX, rotY, rotZ) {
if (rotY === undefined && rotZ === undefined) {
rotZ = rotX
rotX = rotY = 0
}
if (typeof rotY !== 'number') rotY = 0
if (typeof rotZ !== 'number') rotZ = 0
if (rotX !== 0 || rotY !== 0) {
this[IS_2D] = false
}
rotX *= RAD_PER_DEGREE
rotY *= RAD_PER_DEGREE
rotZ *= RAD_PER_DEGREE
let c = Math.cos(rotZ)
let s = Math.sin(rotZ)
this[VALUES] = multiply([c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], this[VALUES])
c = Math.cos(rotY)
s = Math.sin(rotY)
this[VALUES] = multiply([c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1], this[VALUES])
c = Math.cos(rotX)
s = Math.sin(rotX)
this[VALUES] = multiply([1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1], this[VALUES])
return this
}
rotateAxisAngle(x, y, z, angle) {
return newInstance(this[VALUES]).rotateAxisAngleSelf(x, y, z, angle)
}
rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) {
const length = Math.sqrt(x * x + y * y + z * z)
if (length === 0) {
return this
}
if (length !== 1) {
x /= length
y /= length
z /= length
}
angle *= RAD_PER_DEGREE
const c = Math.cos(angle)
const s = Math.sin(angle)
const t = 1 - c
const tx = t * x
const ty = t * y
this[VALUES] = multiply(
[
tx * x + c,
tx * y + s * z,
tx * z - s * y,
0,
tx * y - s * z,
ty * y + c,
ty * z + s * x,
0,
tx * z + s * y,
ty * z - s * x,
t * z * z + c,
0,
0,
0,
0,
1,
],
this[VALUES],
)
if (x !== 0 || y !== 0) {
this[IS_2D] = false
}
return this
}
skewX(sx) {
return newInstance(this[VALUES]).skewXSelf(sx)
}
skewXSelf(sx) {
if (typeof sx !== 'number') {
return this
}
const t = Math.tan(sx * RAD_PER_DEGREE)
this[VALUES] = multiply([1, 0, 0, 0, t, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], this[VALUES])
return this
}
skewY(sy) {
return newInstance(this[VALUES]).skewYSelf(sy)
}
skewYSelf(sy) {
if (typeof sy !== 'number') {
return this
}
const t = Math.tan(sy * RAD_PER_DEGREE)
this[VALUES] = multiply([1, t, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], this[VALUES])
return this
}
flipX() {
return newInstance(multiply([-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], this[VALUES]))
}
flipY() {
return newInstance(multiply([1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], this[VALUES]))
}
inverse() {
return newInstance(this[VALUES].slice()).invertSelf()
}
invertSelf() {
if (this[IS_2D]) {
const det = this[VALUES][A] * this[VALUES][D] - this[VALUES][B] * this[VALUES][C]
// Invertable
if (det !== 0) {
const newA = this[VALUES][D] / det
const newB = -this[VALUES][B] / det
const newC = -this[VALUES][C] / det
const newD = this[VALUES][A] / det
const newE = (this[VALUES][C] * this[VALUES][F] - this[VALUES][D] * this[VALUES][E]) / det
const newF = (this[VALUES][B] * this[VALUES][E] - this[VALUES][A] * this[VALUES][F]) / det
this.a = newA
this.b = newB
this.c = newC
this.d = newD
this.e = newE
this.f = newF
return this
}
// Not invertable
else {
this[IS_2D] = false
this[VALUES] = [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
return this
}
} else {
throw new Error('3D matrix inversion is not implemented.')
}
}
setMatrixValue(transformList) {
const temp = new DOMMatrix(transformList)
this[VALUES] = temp[VALUES]
this[IS_2D] = temp[IS_2D]
return this
}
transformPoint(point) {
const x = point.x || 0
const y = point.y || 0
const z = point.z || 0
const w = point.w || 1
const values = this[VALUES]
const nx = values[M11] * x + values[M21] * y + values[M31] * z + values[M41] * w
const ny = values[M12] * x + values[M22] * y + values[M32] * z + values[M42] * w
const nz = values[M13] * x + values[M23] * y + values[M33] * z + values[M43] * w
const nw = values[M14] * x + values[M24] * y + values[M34] * z + values[M44] * w
return new DOMPoint(nx, ny, nz, nw)
}
toFloat32Array() {
return Float32Array.from(this[VALUES])
}
toFloat64Array() {
return this[VALUES].slice(0)
}
toJSON() {
return {
a: this.a,
b: this.b,
c: this.c,
d: this.d,
e: this.e,
f: this.f,
m11: this.m11,
m12: this.m12,
m13: this.m13,
m14: this.m14,
m21: this.m21,
m22: this.m22,
m23: this.m23,
m24: this.m24,
m31: this.m31,
m32: this.m32,
m33: this.m33,
m34: this.m34,
m41: this.m41,
m42: this.m42,
m43: this.m43,
m44: this.m44,
is2D: this.is2D,
isIdentity: this.isIdentity,
}
}
toString() {
if (this.is2D) {
return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.e}, ${this.f})`
} else {
return `matrix3d(${this[VALUES].join(', ')})`
}
}
}
for (const propertyName of [
'a',
'b',
'c',
'd',
'e',
'f',
'm11',
'm12',
'm13',
'm14',
'm21',
'm22',
'm23',
'm24',
'm31',
'm32',
'm33',
'm34',
'm41',
'm42',
'm43',
'm44',
'is2D',
'isIdentity',
]) {
const propertyDescriptor = Object.getOwnPropertyDescriptor(DOMMatrix.prototype, propertyName)
propertyDescriptor.enumerable = true
Object.defineProperty(DOMMatrix.prototype, propertyName, propertyDescriptor)
}
module.exports = { DOMPoint, DOMMatrix, DOMRect }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,196 @@
const { platform, homedir } = require('os')
const { join } = require('path')
const {
clearAllCache,
CanvasRenderingContext2D,
CanvasElement,
SVGCanvas,
Path: Path2D,
ImageData,
Image,
FontKey,
GlobalFonts,
PathOp,
FillType,
StrokeJoin,
StrokeCap,
convertSVGTextToPath,
PdfDocument,
GifEncoder,
GifDisposal,
LottieAnimation,
} = require('./js-binding')
const { DOMPoint, DOMMatrix, DOMRect } = require('./geometry')
const loadImage = require('./load-image')
// Add Symbol.dispose support for GifEncoder (ECMAScript 2024 Explicit Resource Management)
if (GifEncoder && typeof Symbol.dispose !== 'undefined') {
GifEncoder.prototype[Symbol.dispose] = function () {
this.dispose()
}
}
const SvgExportFlag = {
ConvertTextToPaths: 0x01,
NoPrettyXML: 0x02,
RelativePathEncoding: 0x04,
}
if (!('families' in GlobalFonts)) {
Object.defineProperty(GlobalFonts, 'families', {
get: function () {
return JSON.parse(GlobalFonts.getFamilies().toString())
},
})
}
if (!('has' in GlobalFonts)) {
Object.defineProperty(GlobalFonts, 'has', {
value: function has(name) {
return !!JSON.parse(GlobalFonts.getFamilies().toString()).find(({ family }) => family === name)
},
configurable: false,
enumerable: false,
writable: false,
})
}
const _toBlob = CanvasElement.prototype.toBlob
const _convertToBlob = CanvasElement.prototype.convertToBlob
if ('Blob' in globalThis) {
CanvasElement.prototype.toBlob = function toBlob(callback, mimeType, quality) {
_toBlob.call(
this,
function (/** @type {Uint8Array} */ imageBuffer) {
const blob = new Blob([imageBuffer.buffer], { type: mimeType })
callback(blob)
},
mimeType,
quality,
)
}
CanvasElement.prototype.convertToBlob = function convertToBlob(options) {
return _convertToBlob.call(this, options).then((/** @type {Uint8Array} */ imageBuffer) => {
const blob = new Blob([imageBuffer.buffer], { type: options?.mime || 'image/png' })
return blob
})
}
} else {
// oxlint-disable-next-line no-unused-vars
CanvasElement.prototype.toBlob = function toBlob(callback, mimeType, quality) {
callback(null)
}
// oxlint-disable-next-line no-unused-vars
CanvasElement.prototype.convertToBlob = function convertToBlob(options) {
return Promise.reject(new Error('Blob is not supported in this environment'))
}
}
const _getTransform = CanvasRenderingContext2D.prototype.getTransform
CanvasRenderingContext2D.prototype.getTransform = function getTransform() {
const transform = _getTransform.apply(this, arguments)
// monkey patched, skip
if (transform instanceof DOMMatrix) {
return transform
}
const { a, b, c, d, e, f } = transform
return new DOMMatrix([a, b, c, d, e, f])
}
// Workaround for webpack bundling issue with drawImage
// Store the original drawImage method
const _drawImage = CanvasRenderingContext2D.prototype.drawImage
// Override drawImage to ensure proper type recognition in bundled environments
CanvasRenderingContext2D.prototype.drawImage = function drawImage(image, ...args) {
// If the image is a Canvas-like object but not recognized due to bundling,
// we need to ensure it's properly identified
if (image && typeof image === 'object') {
// First check if it's a wrapped canvas object
if (image.canvas instanceof CanvasElement || image.canvas instanceof SVGCanvas) {
image = image.canvas
} else if (image._canvas instanceof CanvasElement || image._canvas instanceof SVGCanvas) {
image = image._canvas
}
// Then check if it's a Canvas-like object by checking for getContext method
else if (typeof image.getContext === 'function' && image.width && image.height) {
// If it has canvas properties but isn't recognized as CanvasElement or SVGCanvas,
// try to correct the prototype chain
if (!(image instanceof CanvasElement) && !(image instanceof SVGCanvas)) {
// Try to create a proper CanvasElement from the canvas-like object
// This helps when webpack has transformed the prototype chain
Object.setPrototypeOf(image, CanvasElement.prototype)
}
}
}
// Call the original drawImage with the potentially corrected image
return _drawImage.apply(this, [image, ...args])
}
function createCanvas(width, height, flag) {
const isSvgBackend = typeof flag !== 'undefined'
return isSvgBackend ? new SVGCanvas(width, height, flag) : new CanvasElement(width, height)
}
class Canvas {
constructor(width, height, flag) {
return createCanvas(width, height, flag)
}
static [Symbol.hasInstance](instance) {
return instance instanceof CanvasElement || instance instanceof SVGCanvas
}
}
if (!process.env.DISABLE_SYSTEM_FONTS_LOAD) {
GlobalFonts.loadSystemFonts()
const platformName = platform()
const homedirPath = homedir()
switch (platformName) {
case 'win32':
GlobalFonts.loadFontsFromDir(join(homedirPath, 'AppData', 'Local', 'Microsoft', 'Windows', 'Fonts'))
break
case 'darwin':
GlobalFonts.loadFontsFromDir(join(homedirPath, 'Library', 'Fonts'))
break
case 'linux':
GlobalFonts.loadFontsFromDir(join('usr', 'local', 'share', 'fonts'))
GlobalFonts.loadFontsFromDir(join(homedirPath, '.fonts'))
break
}
}
module.exports = {
clearAllCache,
Canvas,
createCanvas,
Path2D,
ImageData,
Image,
PathOp,
FillType,
StrokeCap,
StrokeJoin,
SvgExportFlag,
GlobalFonts: GlobalFonts,
convertSVGTextToPath,
DOMPoint,
DOMMatrix,
DOMRect,
loadImage,
FontKey,
// Export these for better webpack compatibility
CanvasElement,
SVGCanvas,
PDFDocument: PdfDocument,
// GIF encoding
GifEncoder,
GifDisposal,
// Lottie animation
LottieAnimation,
}
@@ -0,0 +1,464 @@
// prettier-ignore
/* eslint-disable */
// @ts-nocheck
/* auto-generated by NAPI-RS */
const { readFileSync } = require('fs')
let nativeBinding = null
const loadErrors = []
const isMusl = () => {
let musl = false
if (process.platform === 'linux') {
musl = isMuslFromFilesystem()
if (musl === null) {
musl = isMuslFromReport()
}
if (musl === null) {
musl = isMuslFromChildProcess()
}
}
return musl
}
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
const isMuslFromFilesystem = () => {
try {
return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
} catch {
return null
}
}
const isMuslFromReport = () => {
let report = null
if (typeof process.report?.getReport === 'function') {
process.report.excludeNetwork = true
report = process.report.getReport()
}
if (!report) {
return null
}
if (report.header && report.header.glibcVersionRuntime) {
return false
}
if (Array.isArray(report.sharedObjects)) {
if (report.sharedObjects.some(isFileMusl)) {
return true
}
}
return false
}
const isMuslFromChildProcess = () => {
try {
return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
} catch (e) {
// If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
return false
}
}
function requireNative() {
if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
try {
return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH)
} catch (err) {
loadErrors.push(err)
}
} else if (process.platform === 'android') {
if (process.arch === 'arm64') {
try {
return require('./skia.android-arm64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-android-arm64')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'arm') {
try {
return require('./skia.android-arm-eabi.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-android-arm-eabi')
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
}
} else if (process.platform === 'win32') {
if (process.arch === 'x64') {
if (
process.config?.variables?.shlib_suffix === 'dll.a' ||
process.config?.variables?.node_target_type === 'shared_library'
) {
try {
return require('./skia.win32-x64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-win32-x64-gnu')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.win32-x64-msvc.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-win32-x64-msvc')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'ia32') {
try {
return require('./skia.win32-ia32-msvc.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-win32-ia32-msvc')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'arm64') {
try {
return require('./skia.win32-arm64-msvc.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-win32-arm64-msvc')
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
}
} else if (process.platform === 'darwin') {
try {
return require('./skia.darwin-universal.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-darwin-universal')
} catch (e) {
loadErrors.push(e)
}
if (process.arch === 'x64') {
try {
return require('./skia.darwin-x64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-darwin-x64')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'arm64') {
try {
return require('./skia.darwin-arm64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-darwin-arm64')
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
}
} else if (process.platform === 'freebsd') {
if (process.arch === 'x64') {
try {
return require('./skia.freebsd-x64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-freebsd-x64')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'arm64') {
try {
return require('./skia.freebsd-arm64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-freebsd-arm64')
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
}
} else if (process.platform === 'linux') {
if (process.arch === 'x64') {
if (isMusl()) {
try {
return require('./skia.linux-x64-musl.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-x64-musl')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.linux-x64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-x64-gnu')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'arm64') {
if (isMusl()) {
try {
return require('./skia.linux-arm64-musl.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-arm64-musl')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.linux-arm64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-arm64-gnu')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'arm') {
if (isMusl()) {
try {
return require('./skia.linux-arm-musleabihf.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-arm-musleabihf')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.linux-arm-gnueabihf.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-arm-gnueabihf')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'loong64') {
if (isMusl()) {
try {
return require('./skia.linux-loong64-musl.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-loong64-musl')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.linux-loong64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-loong64-gnu')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'riscv64') {
if (isMusl()) {
try {
return require('./skia.linux-riscv64-musl.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-riscv64-musl')
} catch (e) {
loadErrors.push(e)
}
} else {
try {
return require('./skia.linux-riscv64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-riscv64-gnu')
} catch (e) {
loadErrors.push(e)
}
}
} else if (process.arch === 'ppc64') {
try {
return require('./skia.linux-ppc64-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-ppc64-gnu')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 's390x') {
try {
return require('./skia.linux-s390x-gnu.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-linux-s390x-gnu')
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
}
} else if (process.platform === 'openharmony') {
if (process.arch === 'arm64') {
try {
return require('./skia.openharmony-arm64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-openharmony-arm64')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'x64') {
try {
return require('./skia.openharmony-x64.node')
} catch (e) {
loadErrors.push(e)
}
try {
return require('@napi-rs/canvas-openharmony-x64')
} catch (e) {
loadErrors.push(e)
}
} else if (process.arch === 'arm') {
try {
return require('./skia.openharmony-arm.node')
} catch (e) {
loadErrors.push(e)
}
try {
const binding = require('@napi-rs/canvas-openharmony-arm')
return binding
} catch (e) {
loadErrors.push(e)
}
} else {
loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
}
} else {
loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
}
}
nativeBinding = requireNative()
if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
let wasiBinding = null
let wasiBindingError = null
try {
wasiBinding = require('./skia.wasi.cjs')
nativeBinding = wasiBinding
} catch (err) {
if (process.env.NAPI_RS_FORCE_WASI) {
wasiBindingError = err
}
}
if (!nativeBinding) {
try {
wasiBinding = require('@napi-rs/canvas-wasm32-wasi')
nativeBinding = wasiBinding
} catch (err) {
if (process.env.NAPI_RS_FORCE_WASI) {
wasiBindingError.cause = err
loadErrors.push(err)
}
}
}
}
if (!nativeBinding) {
if (loadErrors.length > 0) {
throw new Error(
`Cannot find native binding. ` +
`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
{
cause: loadErrors.reduce((err, cur) => {
cur.cause = err
return cur
}),
},
)
}
throw new Error(`Failed to load native binding`)
}
module.exports = nativeBinding
module.exports.GlobalFonts = nativeBinding.GlobalFonts
module.exports.CanvasElement = nativeBinding.CanvasElement
module.exports.CanvasGradient = nativeBinding.CanvasGradient
module.exports.CanvasPattern = nativeBinding.CanvasPattern
module.exports.CanvasRenderingContext2D = nativeBinding.CanvasRenderingContext2D
module.exports.FontKey = nativeBinding.FontKey
module.exports.Image = nativeBinding.Image
module.exports.ImageData = nativeBinding.ImageData
module.exports.Path = nativeBinding.Path
module.exports.PdfDocument = nativeBinding.PdfDocument
module.exports.SVGCanvas = nativeBinding.SVGCanvas
module.exports.ChromaSubsampling = nativeBinding.ChromaSubsampling
module.exports.clearAllCache = nativeBinding.clearAllCache
module.exports.convertSVGTextToPath = nativeBinding.convertSVGTextToPath
module.exports.FillType = nativeBinding.FillType
module.exports.PathOp = nativeBinding.PathOp
module.exports.StrokeCap = nativeBinding.StrokeCap
module.exports.StrokeJoin = nativeBinding.StrokeJoin
module.exports.SvgExportFlag = nativeBinding.SvgExportFlag
module.exports.GifEncoder = nativeBinding.GifEncoder
module.exports.GifDisposal = nativeBinding.GifDisposal

Some files were not shown because too many files have changed in this diff Show More