@hasna/todos 0.15.11 → 0.15.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cloud-router.d.ts +10 -1
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/index.js +279 -23
- package/dist/contracts.js +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/index.js +154 -6
- package/dist/mcp.js +1 -1
- package/dist/project-registration.js +1 -1
- package/dist/registry.js +1 -1
- package/dist/release-provenance.json +5 -5
- package/dist/sdk/index.js +21 -0
- package/dist/sdk/v1.generated.d.ts +32 -0
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +154 -6
- package/dist/server/openapi.d.ts +183 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -70,7 +70,7 @@ var package_default;
|
|
|
70
70
|
var init_package = __esm(() => {
|
|
71
71
|
package_default = {
|
|
72
72
|
name: "@hasna/todos",
|
|
73
|
-
version: "0.15.
|
|
73
|
+
version: "0.15.12",
|
|
74
74
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
75
75
|
type: "module",
|
|
76
76
|
main: "dist/index.js",
|
|
@@ -23703,6 +23703,7 @@ function buildV1OpenApiDocument(version = getPackageVersion()) {
|
|
|
23703
23703
|
ProjectTaskListEnsureResult: projectTaskListEnsureResultSchema,
|
|
23704
23704
|
ProjectTaskListRollbackResult: projectTaskListRollbackResultSchema,
|
|
23705
23705
|
TaskComment: taskCommentSchema,
|
|
23706
|
+
TaskGitRef: taskGitRefSchema,
|
|
23706
23707
|
Plan: planSchema,
|
|
23707
23708
|
PlanProjectLinkReceipt: planProjectLinkReceiptSchema,
|
|
23708
23709
|
PlanProjectLinkResult: planProjectLinkResultSchema,
|
|
@@ -24864,6 +24865,92 @@ function buildV1OpenApiDocument(version = getPackageVersion()) {
|
|
|
24864
24865
|
}
|
|
24865
24866
|
}
|
|
24866
24867
|
},
|
|
24868
|
+
"/v1/tasks/{id}/refs": {
|
|
24869
|
+
get: {
|
|
24870
|
+
operationId: "listTaskGitRefs",
|
|
24871
|
+
summary: "List git branch and pull-request refs linked to a task",
|
|
24872
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
24873
|
+
responses: {
|
|
24874
|
+
"200": {
|
|
24875
|
+
content: {
|
|
24876
|
+
"application/json": {
|
|
24877
|
+
schema: {
|
|
24878
|
+
type: "object",
|
|
24879
|
+
additionalProperties: false,
|
|
24880
|
+
required: ["refs", "count"],
|
|
24881
|
+
properties: {
|
|
24882
|
+
refs: { type: "array", items: { $ref: "#/components/schemas/TaskGitRef" } },
|
|
24883
|
+
count: { type: "integer", minimum: 0 }
|
|
24884
|
+
}
|
|
24885
|
+
}
|
|
24886
|
+
}
|
|
24887
|
+
}
|
|
24888
|
+
}
|
|
24889
|
+
}
|
|
24890
|
+
},
|
|
24891
|
+
post: {
|
|
24892
|
+
operationId: "linkTaskGitRef",
|
|
24893
|
+
summary: "Link a git branch or pull-request ref to a task",
|
|
24894
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
24895
|
+
requestBody: {
|
|
24896
|
+
required: true,
|
|
24897
|
+
content: {
|
|
24898
|
+
"application/json": {
|
|
24899
|
+
schema: {
|
|
24900
|
+
type: "object",
|
|
24901
|
+
additionalProperties: false,
|
|
24902
|
+
required: ["ref_type", "name"],
|
|
24903
|
+
properties: {
|
|
24904
|
+
ref_type: { type: "string", enum: ["branch", "pull_request"] },
|
|
24905
|
+
name: { type: "string", minLength: 1 },
|
|
24906
|
+
url: { type: "string" },
|
|
24907
|
+
provider: { type: "string" },
|
|
24908
|
+
metadata: { type: "object", additionalProperties: true }
|
|
24909
|
+
}
|
|
24910
|
+
}
|
|
24911
|
+
}
|
|
24912
|
+
}
|
|
24913
|
+
},
|
|
24914
|
+
responses: {
|
|
24915
|
+
"201": {
|
|
24916
|
+
content: {
|
|
24917
|
+
"application/json": {
|
|
24918
|
+
schema: {
|
|
24919
|
+
type: "object",
|
|
24920
|
+
additionalProperties: false,
|
|
24921
|
+
required: ["ref"],
|
|
24922
|
+
properties: { ref: { $ref: "#/components/schemas/TaskGitRef" } }
|
|
24923
|
+
}
|
|
24924
|
+
}
|
|
24925
|
+
}
|
|
24926
|
+
}
|
|
24927
|
+
}
|
|
24928
|
+
}
|
|
24929
|
+
},
|
|
24930
|
+
"/v1/refs/{ref}": {
|
|
24931
|
+
get: {
|
|
24932
|
+
operationId: "findTaskGitRefs",
|
|
24933
|
+
summary: "Find task links by git branch or pull-request ref",
|
|
24934
|
+
parameters: [{ name: "ref", in: "path", required: true, schema: { type: "string" } }],
|
|
24935
|
+
responses: {
|
|
24936
|
+
"200": {
|
|
24937
|
+
content: {
|
|
24938
|
+
"application/json": {
|
|
24939
|
+
schema: {
|
|
24940
|
+
type: "object",
|
|
24941
|
+
additionalProperties: false,
|
|
24942
|
+
required: ["refs", "count"],
|
|
24943
|
+
properties: {
|
|
24944
|
+
refs: { type: "array", items: { $ref: "#/components/schemas/TaskGitRef" } },
|
|
24945
|
+
count: { type: "integer", minimum: 0 }
|
|
24946
|
+
}
|
|
24947
|
+
}
|
|
24948
|
+
}
|
|
24949
|
+
}
|
|
24950
|
+
}
|
|
24951
|
+
}
|
|
24952
|
+
}
|
|
24953
|
+
},
|
|
24867
24954
|
"/v1/tasks/{id}/start": {
|
|
24868
24955
|
post: {
|
|
24869
24956
|
operationId: "startTask",
|
|
@@ -25315,7 +25402,7 @@ function buildV1OpenApiDocument(version = getPackageVersion()) {
|
|
|
25315
25402
|
}
|
|
25316
25403
|
};
|
|
25317
25404
|
}
|
|
25318
|
-
var taskSchema, projectSchema, taskListSchema, projectTaskListEnsureReceiptSchema, projectTaskListEnsureResultSchema, projectTaskListRollbackResultSchema, taskCommentSchema, planSchema, planProjectLinkReceiptSchema, planProjectLinkResultSchema, planProjectLinkRollbackResultSchema, templateTaskSchema, templateSchema, templateVariableSchema, createTemplateTaskInputSchema;
|
|
25405
|
+
var taskSchema, projectSchema, taskListSchema, projectTaskListEnsureReceiptSchema, projectTaskListEnsureResultSchema, projectTaskListRollbackResultSchema, taskCommentSchema, taskGitRefSchema, planSchema, planProjectLinkReceiptSchema, planProjectLinkResultSchema, planProjectLinkRollbackResultSchema, templateTaskSchema, templateSchema, templateVariableSchema, createTemplateTaskInputSchema;
|
|
25319
25406
|
var init_openapi = __esm(() => {
|
|
25320
25407
|
init_package_version();
|
|
25321
25408
|
init_types();
|
|
@@ -25451,6 +25538,32 @@ var init_openapi = __esm(() => {
|
|
|
25451
25538
|
created_at: { type: "string", format: "date-time" }
|
|
25452
25539
|
}
|
|
25453
25540
|
};
|
|
25541
|
+
taskGitRefSchema = {
|
|
25542
|
+
type: "object",
|
|
25543
|
+
additionalProperties: false,
|
|
25544
|
+
required: [
|
|
25545
|
+
"id",
|
|
25546
|
+
"task_id",
|
|
25547
|
+
"ref_type",
|
|
25548
|
+
"name",
|
|
25549
|
+
"url",
|
|
25550
|
+
"provider",
|
|
25551
|
+
"metadata",
|
|
25552
|
+
"created_at",
|
|
25553
|
+
"updated_at"
|
|
25554
|
+
],
|
|
25555
|
+
properties: {
|
|
25556
|
+
id: { type: "string", minLength: 1 },
|
|
25557
|
+
task_id: { type: "string", minLength: 1 },
|
|
25558
|
+
ref_type: { type: "string", enum: ["branch", "pull_request"] },
|
|
25559
|
+
name: { type: "string", minLength: 1 },
|
|
25560
|
+
url: { type: "string", nullable: true },
|
|
25561
|
+
provider: { type: "string", nullable: true },
|
|
25562
|
+
metadata: { type: "object", additionalProperties: true },
|
|
25563
|
+
created_at: { type: "string", format: "date-time" },
|
|
25564
|
+
updated_at: { type: "string", format: "date-time" }
|
|
25565
|
+
}
|
|
25566
|
+
};
|
|
25454
25567
|
planSchema = {
|
|
25455
25568
|
type: "object",
|
|
25456
25569
|
required: ["id", "slug", "name", "status", "created_at", "updated_at"],
|
|
@@ -62341,6 +62454,12 @@ function toListQuery(filter = {}) {
|
|
|
62341
62454
|
query["offset"] = filter.offset;
|
|
62342
62455
|
return query;
|
|
62343
62456
|
}
|
|
62457
|
+
function priorityRank(priority) {
|
|
62458
|
+
return PRIORITY_RANK[priority ?? ""] ?? 4;
|
|
62459
|
+
}
|
|
62460
|
+
function compareCloudTaskOrder(a, b) {
|
|
62461
|
+
return priorityRank(a.priority) - priorityRank(b.priority) || b.created_at.localeCompare(a.created_at) || a.id.localeCompare(b.id);
|
|
62462
|
+
}
|
|
62344
62463
|
async function fetchListTagsCapability(client) {
|
|
62345
62464
|
const document = await requiredRemoteRoute(client, "/v1/openapi.json", () => client.transport.get("/openapi.json"));
|
|
62346
62465
|
if (!document || typeof document !== "object" || Array.isArray(document))
|
|
@@ -62362,13 +62481,40 @@ async function requireTagsFilterCapability(client) {
|
|
|
62362
62481
|
throw new Error(`REMOTE_TAGS_FILTER_UNSUPPORTED: configured Todos authority ${authority} does not advertise the tags ` + "query param on GET /v1/tasks; deploy the current @hasna/todos /v1 server to filter by tag; " + "no unfiltered task read was issued");
|
|
62363
62482
|
}
|
|
62364
62483
|
}
|
|
62365
|
-
async function
|
|
62366
|
-
if (filter.tags?.length)
|
|
62367
|
-
await requireTagsFilterCapability(client);
|
|
62484
|
+
async function requestCloudTaskPage(client, filter) {
|
|
62368
62485
|
const res = await requiredRemoteRoute(client, "/v1/tasks", () => client.list("tasks", { query: toListQuery(filter) }));
|
|
62369
62486
|
const envelope = res.raw;
|
|
62370
62487
|
return Array.isArray(envelope?.tasks) ? envelope.tasks : res.items;
|
|
62371
62488
|
}
|
|
62489
|
+
async function cloudListTasks(client, filter = {}) {
|
|
62490
|
+
if (filter.tags?.length)
|
|
62491
|
+
await requireTagsFilterCapability(client);
|
|
62492
|
+
const statuses = Array.isArray(filter.status) ? filter.status : undefined;
|
|
62493
|
+
if (!statuses)
|
|
62494
|
+
return requestCloudTaskPage(client, filter);
|
|
62495
|
+
if (statuses.length === 0)
|
|
62496
|
+
return [];
|
|
62497
|
+
if (statuses.length === 1) {
|
|
62498
|
+
return requestCloudTaskPage(client, { ...filter, status: statuses[0] });
|
|
62499
|
+
}
|
|
62500
|
+
const { status: _status, limit, offset, ...baseFilter } = filter;
|
|
62501
|
+
const start = offset ?? 0;
|
|
62502
|
+
const windowEnd = typeof limit === "number" ? start + limit : undefined;
|
|
62503
|
+
const pages = await Promise.all(statuses.map((status) => requestCloudTaskPage(client, {
|
|
62504
|
+
...baseFilter,
|
|
62505
|
+
status,
|
|
62506
|
+
...windowEnd === undefined ? {} : { limit: windowEnd }
|
|
62507
|
+
})));
|
|
62508
|
+
const seen = new Set;
|
|
62509
|
+
const union3 = pages.flat().filter((task) => {
|
|
62510
|
+
if (seen.has(task.id))
|
|
62511
|
+
return false;
|
|
62512
|
+
seen.add(task.id);
|
|
62513
|
+
return true;
|
|
62514
|
+
});
|
|
62515
|
+
union3.sort(compareCloudTaskOrder);
|
|
62516
|
+
return union3.slice(start, windowEnd);
|
|
62517
|
+
}
|
|
62372
62518
|
async function cloudGetTask(client, id) {
|
|
62373
62519
|
const raw = await client.get("tasks", id);
|
|
62374
62520
|
return raw == null ? null : unwrapTask(raw);
|
|
@@ -62583,7 +62729,7 @@ async function cloudResolveTaskListRef(client, ref, projectId) {
|
|
|
62583
62729
|
}
|
|
62584
62730
|
throw new Error(`Task list not found: "${input}"`);
|
|
62585
62731
|
}
|
|
62586
|
-
var UUID_RE, TRANSPORT_TOKENS, completionCapabilityCache, SERVER_MODE_CANDIDATES, cachedServerMode = null, listTagsCapabilityCache;
|
|
62732
|
+
var UUID_RE, TRANSPORT_TOKENS, completionCapabilityCache, gitRefCapabilityCache, SERVER_MODE_CANDIDATES, cachedServerMode = null, PRIORITY_RANK, listTagsCapabilityCache;
|
|
62587
62733
|
var init_cloud_router = __esm(() => {
|
|
62588
62734
|
init_storage();
|
|
62589
62735
|
init_mode();
|
|
@@ -62602,7 +62748,9 @@ var init_cloud_router = __esm(() => {
|
|
|
62602
62748
|
hybrid: "http"
|
|
62603
62749
|
};
|
|
62604
62750
|
completionCapabilityCache = new Map;
|
|
62751
|
+
gitRefCapabilityCache = new Map;
|
|
62605
62752
|
SERVER_MODE_CANDIDATES = ["postgres", "cloud", "self_hosted"];
|
|
62753
|
+
PRIORITY_RANK = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
62606
62754
|
listTagsCapabilityCache = new Map;
|
|
62607
62755
|
});
|
|
62608
62756
|
|
package/dist/server/openapi.d.ts
CHANGED
|
@@ -271,6 +271,49 @@ export declare function buildV1OpenApiDocument(version?: string): {
|
|
|
271
271
|
};
|
|
272
272
|
};
|
|
273
273
|
};
|
|
274
|
+
TaskGitRef: {
|
|
275
|
+
readonly type: "object";
|
|
276
|
+
readonly additionalProperties: false;
|
|
277
|
+
readonly required: readonly ["id", "task_id", "ref_type", "name", "url", "provider", "metadata", "created_at", "updated_at"];
|
|
278
|
+
readonly properties: {
|
|
279
|
+
readonly id: {
|
|
280
|
+
readonly type: "string";
|
|
281
|
+
readonly minLength: 1;
|
|
282
|
+
};
|
|
283
|
+
readonly task_id: {
|
|
284
|
+
readonly type: "string";
|
|
285
|
+
readonly minLength: 1;
|
|
286
|
+
};
|
|
287
|
+
readonly ref_type: {
|
|
288
|
+
readonly type: "string";
|
|
289
|
+
readonly enum: readonly ["branch", "pull_request"];
|
|
290
|
+
};
|
|
291
|
+
readonly name: {
|
|
292
|
+
readonly type: "string";
|
|
293
|
+
readonly minLength: 1;
|
|
294
|
+
};
|
|
295
|
+
readonly url: {
|
|
296
|
+
readonly type: "string";
|
|
297
|
+
readonly nullable: true;
|
|
298
|
+
};
|
|
299
|
+
readonly provider: {
|
|
300
|
+
readonly type: "string";
|
|
301
|
+
readonly nullable: true;
|
|
302
|
+
};
|
|
303
|
+
readonly metadata: {
|
|
304
|
+
readonly type: "object";
|
|
305
|
+
readonly additionalProperties: true;
|
|
306
|
+
};
|
|
307
|
+
readonly created_at: {
|
|
308
|
+
readonly type: "string";
|
|
309
|
+
readonly format: "date-time";
|
|
310
|
+
};
|
|
311
|
+
readonly updated_at: {
|
|
312
|
+
readonly type: "string";
|
|
313
|
+
readonly format: "date-time";
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
};
|
|
274
317
|
Plan: {
|
|
275
318
|
readonly type: "object";
|
|
276
319
|
readonly required: readonly ["id", "slug", "name", "status", "created_at", "updated_at"];
|
|
@@ -2600,6 +2643,146 @@ export declare function buildV1OpenApiDocument(version?: string): {
|
|
|
2600
2643
|
};
|
|
2601
2644
|
};
|
|
2602
2645
|
};
|
|
2646
|
+
"/v1/tasks/{id}/refs": {
|
|
2647
|
+
get: {
|
|
2648
|
+
operationId: string;
|
|
2649
|
+
summary: string;
|
|
2650
|
+
parameters: {
|
|
2651
|
+
name: string;
|
|
2652
|
+
in: string;
|
|
2653
|
+
required: boolean;
|
|
2654
|
+
schema: {
|
|
2655
|
+
type: string;
|
|
2656
|
+
};
|
|
2657
|
+
}[];
|
|
2658
|
+
responses: {
|
|
2659
|
+
"200": {
|
|
2660
|
+
content: {
|
|
2661
|
+
"application/json": {
|
|
2662
|
+
schema: {
|
|
2663
|
+
type: string;
|
|
2664
|
+
additionalProperties: boolean;
|
|
2665
|
+
required: string[];
|
|
2666
|
+
properties: {
|
|
2667
|
+
refs: {
|
|
2668
|
+
type: string;
|
|
2669
|
+
items: {
|
|
2670
|
+
$ref: string;
|
|
2671
|
+
};
|
|
2672
|
+
};
|
|
2673
|
+
count: {
|
|
2674
|
+
type: string;
|
|
2675
|
+
minimum: number;
|
|
2676
|
+
};
|
|
2677
|
+
};
|
|
2678
|
+
};
|
|
2679
|
+
};
|
|
2680
|
+
};
|
|
2681
|
+
};
|
|
2682
|
+
};
|
|
2683
|
+
};
|
|
2684
|
+
post: {
|
|
2685
|
+
operationId: string;
|
|
2686
|
+
summary: string;
|
|
2687
|
+
parameters: {
|
|
2688
|
+
name: string;
|
|
2689
|
+
in: string;
|
|
2690
|
+
required: boolean;
|
|
2691
|
+
schema: {
|
|
2692
|
+
type: string;
|
|
2693
|
+
};
|
|
2694
|
+
}[];
|
|
2695
|
+
requestBody: {
|
|
2696
|
+
required: boolean;
|
|
2697
|
+
content: {
|
|
2698
|
+
"application/json": {
|
|
2699
|
+
schema: {
|
|
2700
|
+
type: string;
|
|
2701
|
+
additionalProperties: boolean;
|
|
2702
|
+
required: string[];
|
|
2703
|
+
properties: {
|
|
2704
|
+
ref_type: {
|
|
2705
|
+
type: string;
|
|
2706
|
+
enum: string[];
|
|
2707
|
+
};
|
|
2708
|
+
name: {
|
|
2709
|
+
type: string;
|
|
2710
|
+
minLength: number;
|
|
2711
|
+
};
|
|
2712
|
+
url: {
|
|
2713
|
+
type: string;
|
|
2714
|
+
};
|
|
2715
|
+
provider: {
|
|
2716
|
+
type: string;
|
|
2717
|
+
};
|
|
2718
|
+
metadata: {
|
|
2719
|
+
type: string;
|
|
2720
|
+
additionalProperties: boolean;
|
|
2721
|
+
};
|
|
2722
|
+
};
|
|
2723
|
+
};
|
|
2724
|
+
};
|
|
2725
|
+
};
|
|
2726
|
+
};
|
|
2727
|
+
responses: {
|
|
2728
|
+
"201": {
|
|
2729
|
+
content: {
|
|
2730
|
+
"application/json": {
|
|
2731
|
+
schema: {
|
|
2732
|
+
type: string;
|
|
2733
|
+
additionalProperties: boolean;
|
|
2734
|
+
required: string[];
|
|
2735
|
+
properties: {
|
|
2736
|
+
ref: {
|
|
2737
|
+
$ref: string;
|
|
2738
|
+
};
|
|
2739
|
+
};
|
|
2740
|
+
};
|
|
2741
|
+
};
|
|
2742
|
+
};
|
|
2743
|
+
};
|
|
2744
|
+
};
|
|
2745
|
+
};
|
|
2746
|
+
};
|
|
2747
|
+
"/v1/refs/{ref}": {
|
|
2748
|
+
get: {
|
|
2749
|
+
operationId: string;
|
|
2750
|
+
summary: string;
|
|
2751
|
+
parameters: {
|
|
2752
|
+
name: string;
|
|
2753
|
+
in: string;
|
|
2754
|
+
required: boolean;
|
|
2755
|
+
schema: {
|
|
2756
|
+
type: string;
|
|
2757
|
+
};
|
|
2758
|
+
}[];
|
|
2759
|
+
responses: {
|
|
2760
|
+
"200": {
|
|
2761
|
+
content: {
|
|
2762
|
+
"application/json": {
|
|
2763
|
+
schema: {
|
|
2764
|
+
type: string;
|
|
2765
|
+
additionalProperties: boolean;
|
|
2766
|
+
required: string[];
|
|
2767
|
+
properties: {
|
|
2768
|
+
refs: {
|
|
2769
|
+
type: string;
|
|
2770
|
+
items: {
|
|
2771
|
+
$ref: string;
|
|
2772
|
+
};
|
|
2773
|
+
};
|
|
2774
|
+
count: {
|
|
2775
|
+
type: string;
|
|
2776
|
+
minimum: number;
|
|
2777
|
+
};
|
|
2778
|
+
};
|
|
2779
|
+
};
|
|
2780
|
+
};
|
|
2781
|
+
};
|
|
2782
|
+
};
|
|
2783
|
+
};
|
|
2784
|
+
};
|
|
2785
|
+
};
|
|
2603
2786
|
"/v1/tasks/{id}/start": {
|
|
2604
2787
|
post: {
|
|
2605
2788
|
operationId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/server/openapi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/server/openapi.ts"],"names":[],"mappings":"AA8TA,wBAAgB,sBAAsB,CAAC,OAAO,SAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAw+CnE"}
|