pushwork 1.0.0
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/README.md +460 -0
- package/dist/browser/browser-sync-engine.d.ts +64 -0
- package/dist/browser/browser-sync-engine.d.ts.map +1 -0
- package/dist/browser/browser-sync-engine.js +303 -0
- package/dist/browser/browser-sync-engine.js.map +1 -0
- package/dist/browser/filesystem-adapter.d.ts +84 -0
- package/dist/browser/filesystem-adapter.d.ts.map +1 -0
- package/dist/browser/filesystem-adapter.js +413 -0
- package/dist/browser/filesystem-adapter.js.map +1 -0
- package/dist/browser/index.d.ts +36 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +90 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/types.d.ts +70 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +6 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/cli/commands.d.ts +71 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +794 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +199 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +71 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +314 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/change-detection.d.ts +78 -0
- package/dist/core/change-detection.d.ts.map +1 -0
- package/dist/core/change-detection.js +370 -0
- package/dist/core/change-detection.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +22 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/isomorphic-snapshot.d.ts +58 -0
- package/dist/core/isomorphic-snapshot.d.ts.map +1 -0
- package/dist/core/isomorphic-snapshot.js +204 -0
- package/dist/core/isomorphic-snapshot.js.map +1 -0
- package/dist/core/move-detection.d.ts +72 -0
- package/dist/core/move-detection.d.ts.map +1 -0
- package/dist/core/move-detection.js +200 -0
- package/dist/core/move-detection.js.map +1 -0
- package/dist/core/snapshot.d.ts +109 -0
- package/dist/core/snapshot.d.ts.map +1 -0
- package/dist/core/snapshot.js +263 -0
- package/dist/core/snapshot.js.map +1 -0
- package/dist/core/sync-engine.d.ts +110 -0
- package/dist/core/sync-engine.d.ts.map +1 -0
- package/dist/core/sync-engine.js +817 -0
- package/dist/core/sync-engine.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/platform/browser-filesystem.d.ts +26 -0
- package/dist/platform/browser-filesystem.d.ts.map +1 -0
- package/dist/platform/browser-filesystem.js +91 -0
- package/dist/platform/browser-filesystem.js.map +1 -0
- package/dist/platform/filesystem.d.ts +29 -0
- package/dist/platform/filesystem.d.ts.map +1 -0
- package/dist/platform/filesystem.js +65 -0
- package/dist/platform/filesystem.js.map +1 -0
- package/dist/platform/node-filesystem.d.ts +21 -0
- package/dist/platform/node-filesystem.d.ts.map +1 -0
- package/dist/platform/node-filesystem.js +93 -0
- package/dist/platform/node-filesystem.js.map +1 -0
- package/dist/types/config.d.ts +119 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/documents.d.ts +70 -0
- package/dist/types/documents.d.ts.map +1 -0
- package/dist/types/documents.js +23 -0
- package/dist/types/documents.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/snapshot.d.ts +81 -0
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +17 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/utils/content-similarity.d.ts +53 -0
- package/dist/utils/content-similarity.d.ts.map +1 -0
- package/dist/utils/content-similarity.js +155 -0
- package/dist/utils/content-similarity.js.map +1 -0
- package/dist/utils/content.d.ts +5 -0
- package/dist/utils/content.d.ts.map +1 -0
- package/dist/utils/content.js +30 -0
- package/dist/utils/content.js.map +1 -0
- package/dist/utils/fs-browser.d.ts +57 -0
- package/dist/utils/fs-browser.d.ts.map +1 -0
- package/dist/utils/fs-browser.js +311 -0
- package/dist/utils/fs-browser.js.map +1 -0
- package/dist/utils/fs-node.d.ts +53 -0
- package/dist/utils/fs-node.d.ts.map +1 -0
- package/dist/utils/fs-node.js +220 -0
- package/dist/utils/fs-node.js.map +1 -0
- package/dist/utils/fs.d.ts +62 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +293 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +23 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/isomorphic.d.ts +29 -0
- package/dist/utils/isomorphic.d.ts.map +1 -0
- package/dist/utils/isomorphic.js +139 -0
- package/dist/utils/isomorphic.js.map +1 -0
- package/dist/utils/mime-types.d.ts +13 -0
- package/dist/utils/mime-types.d.ts.map +1 -0
- package/dist/utils/mime-types.js +240 -0
- package/dist/utils/mime-types.js.map +1 -0
- package/dist/utils/network-sync.d.ts +12 -0
- package/dist/utils/network-sync.d.ts.map +1 -0
- package/dist/utils/network-sync.js +149 -0
- package/dist/utils/network-sync.js.map +1 -0
- package/dist/utils/pure.d.ts +25 -0
- package/dist/utils/pure.d.ts.map +1 -0
- package/dist/utils/pure.js +112 -0
- package/dist/utils/pure.js.map +1 -0
- package/dist/utils/repo-factory.d.ts +11 -0
- package/dist/utils/repo-factory.d.ts.map +1 -0
- package/dist/utils/repo-factory.js +77 -0
- package/dist/utils/repo-factory.js.map +1 -0
- package/package.json +83 -0
- package/src/cli/commands.ts +1053 -0
- package/src/cli/index.ts +2 -0
- package/src/cli.ts +287 -0
- package/src/config/index.ts +334 -0
- package/src/core/change-detection.ts +484 -0
- package/src/core/index.ts +5 -0
- package/src/core/move-detection.ts +269 -0
- package/src/core/snapshot.ts +285 -0
- package/src/core/sync-engine.ts +1167 -0
- package/src/index.ts +14 -0
- package/src/types/config.ts +130 -0
- package/src/types/documents.ts +72 -0
- package/src/types/index.ts +8 -0
- package/src/types/snapshot.ts +88 -0
- package/src/utils/content-similarity.ts +194 -0
- package/src/utils/content.ts +28 -0
- package/src/utils/fs.ts +289 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/mime-types.ts +236 -0
- package/src/utils/network-sync.ts +153 -0
- package/src/utils/repo-factory.ts +58 -0
- package/test/README-TESTING-GAPS.md +174 -0
- package/test/integration/README.md +328 -0
- package/test/integration/clone-test.sh +310 -0
- package/test/integration/conflict-resolution-test.sh +309 -0
- package/test/integration/deletion-behavior-test.sh +487 -0
- package/test/integration/deletion-sync-test-simple.sh +193 -0
- package/test/integration/deletion-sync-test.sh +297 -0
- package/test/integration/exclude-patterns.test.ts +152 -0
- package/test/integration/full-integration-test.sh +363 -0
- package/test/integration/sync-deletion.test.ts +339 -0
- package/test/integration/sync-flow.test.ts +309 -0
- package/test/run-tests.sh +225 -0
- package/test/unit/content-similarity.test.ts +236 -0
- package/test/unit/deletion-behavior.test.ts +260 -0
- package/test/unit/enhanced-mime-detection.test.ts +266 -0
- package/test/unit/snapshot.test.ts +431 -0
- package/test/unit/sync-timing.test.ts +178 -0
- package/test/unit/utils.test.ts +368 -0
- package/tools/browser-sync/README.md +116 -0
- package/tools/browser-sync/package.json +44 -0
- package/tools/browser-sync/patchwork.json +1 -0
- package/tools/browser-sync/pnpm-lock.yaml +4202 -0
- package/tools/browser-sync/src/components/BrowserSyncTool.tsx +599 -0
- package/tools/browser-sync/src/index.ts +20 -0
- package/tools/browser-sync/src/polyfills.ts +31 -0
- package/tools/browser-sync/src/styles.css +290 -0
- package/tools/browser-sync/src/types.ts +27 -0
- package/tools/browser-sync/vite.config.ts +25 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Isomorphic snapshot manager that works in both Node.js and browser
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.IsomorphicSnapshotManager = exports.IndexedDBSnapshotStorage = exports.FileSnapshotStorage = void 0;
|
|
7
|
+
const isomorphic_1 = require("../utils/isomorphic");
|
|
8
|
+
/**
|
|
9
|
+
* File-based snapshot storage (for Node.js and browser with file system access)
|
|
10
|
+
*/
|
|
11
|
+
class FileSnapshotStorage {
|
|
12
|
+
constructor(rootPath) {
|
|
13
|
+
this.rootPath = rootPath;
|
|
14
|
+
}
|
|
15
|
+
getSnapshotPath(key = "current") {
|
|
16
|
+
return `${this.rootPath}/${FileSnapshotStorage.SYNC_TOOL_DIR}/${key}-${FileSnapshotStorage.SNAPSHOT_FILENAME}`;
|
|
17
|
+
}
|
|
18
|
+
getSyncToolDir() {
|
|
19
|
+
return `${this.rootPath}/${FileSnapshotStorage.SYNC_TOOL_DIR}`;
|
|
20
|
+
}
|
|
21
|
+
async save(snapshot, key = "current") {
|
|
22
|
+
await (0, isomorphic_1.ensureDirectoryExists)(this.getSyncToolDir());
|
|
23
|
+
const serializable = this.toSerializable(snapshot);
|
|
24
|
+
const content = JSON.stringify(serializable, null, 2);
|
|
25
|
+
await (0, isomorphic_1.writeFileContent)(this.getSnapshotPath(key), content);
|
|
26
|
+
}
|
|
27
|
+
async load(key = "current") {
|
|
28
|
+
const snapshotPath = this.getSnapshotPath(key);
|
|
29
|
+
if (!(await (0, isomorphic_1.pathExists)(snapshotPath))) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const content = await (0, isomorphic_1.readFileContent)(snapshotPath);
|
|
34
|
+
const contentStr = typeof content === "string"
|
|
35
|
+
? content
|
|
36
|
+
: new TextDecoder().decode(content);
|
|
37
|
+
const serializable = JSON.parse(contentStr);
|
|
38
|
+
return this.fromSerializable(serializable);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error(`Failed to load snapshot from ${snapshotPath}: ${error}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async backup(key = "current") {
|
|
45
|
+
const snapshot = await this.load(key);
|
|
46
|
+
if (snapshot) {
|
|
47
|
+
const backupKey = `${key}-backup-${Date.now()}`;
|
|
48
|
+
await this.save(snapshot, backupKey);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
toSerializable(snapshot) {
|
|
52
|
+
return {
|
|
53
|
+
rootPath: snapshot.rootPath,
|
|
54
|
+
timestamp: new Date(snapshot.timestamp).toISOString(),
|
|
55
|
+
files: Array.from(snapshot.files.entries()),
|
|
56
|
+
directories: Array.from(snapshot.directories.entries()),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
fromSerializable(serializable) {
|
|
60
|
+
return {
|
|
61
|
+
rootPath: serializable.rootPath,
|
|
62
|
+
timestamp: new Date(serializable.timestamp).getTime(),
|
|
63
|
+
files: new Map(serializable.files),
|
|
64
|
+
directories: new Map(serializable.directories),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.FileSnapshotStorage = FileSnapshotStorage;
|
|
69
|
+
FileSnapshotStorage.SNAPSHOT_FILENAME = "snapshot.json";
|
|
70
|
+
FileSnapshotStorage.SYNC_TOOL_DIR = ".pushwork";
|
|
71
|
+
/**
|
|
72
|
+
* IndexedDB-based snapshot storage (for browser environments)
|
|
73
|
+
*/
|
|
74
|
+
class IndexedDBSnapshotStorage {
|
|
75
|
+
constructor() {
|
|
76
|
+
this.dbName = "pushwork-snapshots";
|
|
77
|
+
this.storeName = "snapshots";
|
|
78
|
+
this.version = 1;
|
|
79
|
+
}
|
|
80
|
+
async save(snapshot, key = "current") {
|
|
81
|
+
const db = await this.openDB();
|
|
82
|
+
const transaction = db.transaction([this.storeName], "readwrite");
|
|
83
|
+
const store = transaction.objectStore(this.storeName);
|
|
84
|
+
const serializable = this.toSerializable(snapshot);
|
|
85
|
+
const putRequest = store.put({
|
|
86
|
+
key,
|
|
87
|
+
snapshot: JSON.stringify(serializable),
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
});
|
|
90
|
+
await new Promise((resolve, reject) => {
|
|
91
|
+
putRequest.onsuccess = () => resolve(undefined);
|
|
92
|
+
putRequest.onerror = () => reject(putRequest.error);
|
|
93
|
+
});
|
|
94
|
+
db.close();
|
|
95
|
+
}
|
|
96
|
+
async load(key = "current") {
|
|
97
|
+
try {
|
|
98
|
+
const db = await this.openDB();
|
|
99
|
+
const transaction = db.transaction([this.storeName], "readonly");
|
|
100
|
+
const store = transaction.objectStore(this.storeName);
|
|
101
|
+
const request = store.get(key);
|
|
102
|
+
const result = await new Promise((resolve, reject) => {
|
|
103
|
+
request.onsuccess = () => resolve(request.result);
|
|
104
|
+
request.onerror = () => reject(request.error);
|
|
105
|
+
});
|
|
106
|
+
db.close();
|
|
107
|
+
if (result) {
|
|
108
|
+
const serializable = JSON.parse(result.snapshot);
|
|
109
|
+
return this.fromSerializable(serializable);
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.warn("Failed to load snapshot from IndexedDB:", error);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async backup(key = "current") {
|
|
119
|
+
const snapshot = await this.load(key);
|
|
120
|
+
if (snapshot) {
|
|
121
|
+
await this.save(snapshot, `${key}-backup-${Date.now()}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async openDB() {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const request = indexedDB.open(this.dbName, this.version);
|
|
127
|
+
request.onerror = () => reject(request.error);
|
|
128
|
+
request.onsuccess = () => resolve(request.result);
|
|
129
|
+
request.onupgradeneeded = (event) => {
|
|
130
|
+
const db = event.target.result;
|
|
131
|
+
if (!db.objectStoreNames.contains(this.storeName)) {
|
|
132
|
+
db.createObjectStore(this.storeName, { keyPath: "key" });
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
toSerializable(snapshot) {
|
|
138
|
+
return {
|
|
139
|
+
rootPath: snapshot.rootPath,
|
|
140
|
+
timestamp: new Date(snapshot.timestamp).toISOString(),
|
|
141
|
+
files: Array.from(snapshot.files.entries()),
|
|
142
|
+
directories: Array.from(snapshot.directories.entries()),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
fromSerializable(serializable) {
|
|
146
|
+
return {
|
|
147
|
+
rootPath: serializable.rootPath,
|
|
148
|
+
timestamp: new Date(serializable.timestamp).getTime(),
|
|
149
|
+
files: new Map(serializable.files),
|
|
150
|
+
directories: new Map(serializable.directories),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.IndexedDBSnapshotStorage = IndexedDBSnapshotStorage;
|
|
155
|
+
/**
|
|
156
|
+
* Isomorphic snapshot manager that uses appropriate storage for the platform
|
|
157
|
+
*/
|
|
158
|
+
class IsomorphicSnapshotManager {
|
|
159
|
+
constructor(rootPath, useIndexedDB = false) {
|
|
160
|
+
if (useIndexedDB ||
|
|
161
|
+
(typeof window !== "undefined" && typeof indexedDB !== "undefined")) {
|
|
162
|
+
this.storage = new IndexedDBSnapshotStorage();
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.storage = new FileSnapshotStorage(rootPath);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async save(snapshot) {
|
|
169
|
+
return this.storage.save(snapshot);
|
|
170
|
+
}
|
|
171
|
+
async load() {
|
|
172
|
+
return this.storage.load();
|
|
173
|
+
}
|
|
174
|
+
async backup() {
|
|
175
|
+
return this.storage.backup();
|
|
176
|
+
}
|
|
177
|
+
async createEmptySnapshot(rootPath) {
|
|
178
|
+
return {
|
|
179
|
+
rootPath,
|
|
180
|
+
timestamp: Date.now(),
|
|
181
|
+
files: new Map(),
|
|
182
|
+
directories: new Map(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
updateFileEntry(snapshot, relativePath, entry) {
|
|
186
|
+
snapshot.files.set(relativePath, entry);
|
|
187
|
+
}
|
|
188
|
+
updateDirectoryEntry(snapshot, relativePath, entry) {
|
|
189
|
+
snapshot.directories.set(relativePath, entry);
|
|
190
|
+
}
|
|
191
|
+
removeFileEntry(snapshot, relativePath) {
|
|
192
|
+
snapshot.files.delete(relativePath);
|
|
193
|
+
}
|
|
194
|
+
createEmpty() {
|
|
195
|
+
return {
|
|
196
|
+
rootPath: "",
|
|
197
|
+
timestamp: Date.now(),
|
|
198
|
+
files: new Map(),
|
|
199
|
+
directories: new Map(),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.IsomorphicSnapshotManager = IsomorphicSnapshotManager;
|
|
204
|
+
//# sourceMappingURL=isomorphic-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isomorphic-snapshot.js","sourceRoot":"","sources":["../../src/core/isomorphic-snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SyncSnapshot, MoveCandidate } from "../types";
|
|
2
|
+
import { DetectedChange } from "./change-detection";
|
|
3
|
+
/**
|
|
4
|
+
* Move detection engine
|
|
5
|
+
*/
|
|
6
|
+
export declare class MoveDetector {
|
|
7
|
+
private static readonly AUTO_THRESHOLD;
|
|
8
|
+
private static readonly PROMPT_THRESHOLD;
|
|
9
|
+
/**
|
|
10
|
+
* Detect file moves by analyzing deleted and created files
|
|
11
|
+
*/
|
|
12
|
+
detectMoves(changes: DetectedChange[], snapshot: SyncSnapshot, rootPath: string): Promise<{
|
|
13
|
+
moves: MoveCandidate[];
|
|
14
|
+
remainingChanges: DetectedChange[];
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Get content of a deleted file from snapshot
|
|
18
|
+
*/
|
|
19
|
+
private getDeletedFileContent;
|
|
20
|
+
/**
|
|
21
|
+
* Group moves by confidence level
|
|
22
|
+
*/
|
|
23
|
+
groupMovesByConfidence(moves: MoveCandidate[]): {
|
|
24
|
+
autoMoves: MoveCandidate[];
|
|
25
|
+
promptMoves: MoveCandidate[];
|
|
26
|
+
lowConfidenceMoves: MoveCandidate[];
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Validate move candidates to avoid conflicts
|
|
30
|
+
*/
|
|
31
|
+
validateMoves(moves: MoveCandidate[]): {
|
|
32
|
+
validMoves: MoveCandidate[];
|
|
33
|
+
conflicts: Array<{
|
|
34
|
+
moves: MoveCandidate[];
|
|
35
|
+
reason: string;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Apply move detection heuristics
|
|
40
|
+
*/
|
|
41
|
+
applyHeuristics(moves: MoveCandidate[]): MoveCandidate[];
|
|
42
|
+
/**
|
|
43
|
+
* Get directory path from file path
|
|
44
|
+
*/
|
|
45
|
+
private getDirectoryPath;
|
|
46
|
+
/**
|
|
47
|
+
* Get file extension from file path
|
|
48
|
+
*/
|
|
49
|
+
private getFileExtension;
|
|
50
|
+
/**
|
|
51
|
+
* Check if a move should be auto-applied
|
|
52
|
+
*/
|
|
53
|
+
shouldAutoApply(move: MoveCandidate): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Check if a move should prompt the user
|
|
56
|
+
*/
|
|
57
|
+
shouldPromptUser(move: MoveCandidate): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Format move for display
|
|
60
|
+
*/
|
|
61
|
+
formatMove(move: MoveCandidate): string;
|
|
62
|
+
/**
|
|
63
|
+
* Calculate move statistics
|
|
64
|
+
*/
|
|
65
|
+
calculateStats(moves: MoveCandidate[]): {
|
|
66
|
+
total: number;
|
|
67
|
+
auto: number;
|
|
68
|
+
prompt: number;
|
|
69
|
+
averageSimilarity: number;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=move-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-detection.d.ts","sourceRoot":"","sources":["../../src/core/move-detection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EAGd,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAc,MAAM,oBAAoB,CAAC;AAEhE;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAO;IAE/C;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,cAAc,EAAE,EACzB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QAAC,gBAAgB,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IA8E1E;;OAEG;YACW,qBAAqB;IAWnC;;OAEG;IACH,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG;QAC9C,SAAS,EAAE,aAAa,EAAE,CAAC;QAC3B,WAAW,EAAE,aAAa,EAAE,CAAC;QAC7B,kBAAkB,EAAE,aAAa,EAAE,CAAC;KACrC;IAQD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG;QACrC,UAAU,EAAE,aAAa,EAAE,CAAC;QAC5B,SAAS,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9D;IA4CD;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE;IAwBxD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;IAI7C;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;IAI9C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM;IAKvC;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG;QACtC,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,EAAE,MAAM,CAAC;KAC3B;CASF"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MoveDetector = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const change_detection_1 = require("./change-detection");
|
|
6
|
+
/**
|
|
7
|
+
* Move detection engine
|
|
8
|
+
*/
|
|
9
|
+
class MoveDetector {
|
|
10
|
+
/**
|
|
11
|
+
* Detect file moves by analyzing deleted and created files
|
|
12
|
+
*/
|
|
13
|
+
async detectMoves(changes, snapshot, rootPath) {
|
|
14
|
+
// Separate deletions and creations
|
|
15
|
+
const deletedFiles = changes.filter((c) => !c.localContent && c.changeType === change_detection_1.ChangeType.LOCAL_ONLY);
|
|
16
|
+
const createdFiles = changes.filter((c) => c.localContent &&
|
|
17
|
+
c.changeType === change_detection_1.ChangeType.LOCAL_ONLY &&
|
|
18
|
+
!snapshot.files.has(c.path));
|
|
19
|
+
if (deletedFiles.length === 0 || createdFiles.length === 0) {
|
|
20
|
+
return { moves: [], remainingChanges: changes };
|
|
21
|
+
}
|
|
22
|
+
const moves = [];
|
|
23
|
+
const usedCreations = new Set();
|
|
24
|
+
const usedDeletions = new Set();
|
|
25
|
+
// Find potential moves by comparing content
|
|
26
|
+
for (const deletedFile of deletedFiles) {
|
|
27
|
+
const deletedContent = await this.getDeletedFileContent(deletedFile, snapshot);
|
|
28
|
+
if (!deletedContent)
|
|
29
|
+
continue;
|
|
30
|
+
let bestMatch = null;
|
|
31
|
+
for (const createdFile of createdFiles) {
|
|
32
|
+
if (usedCreations.has(createdFile.path))
|
|
33
|
+
continue;
|
|
34
|
+
if (!createdFile.localContent)
|
|
35
|
+
continue;
|
|
36
|
+
const similarity = await utils_1.ContentSimilarity.calculateSimilarity(deletedContent, createdFile.localContent);
|
|
37
|
+
if (similarity >= MoveDetector.PROMPT_THRESHOLD) {
|
|
38
|
+
if (!bestMatch || similarity > bestMatch.similarity) {
|
|
39
|
+
bestMatch = { file: createdFile, similarity };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (bestMatch) {
|
|
44
|
+
const confidence = utils_1.ContentSimilarity.getConfidenceLevel(bestMatch.similarity);
|
|
45
|
+
// Always report the potential move (for logging/prompting)
|
|
46
|
+
moves.push({
|
|
47
|
+
fromPath: deletedFile.path,
|
|
48
|
+
toPath: bestMatch.file.path,
|
|
49
|
+
similarity: bestMatch.similarity,
|
|
50
|
+
confidence,
|
|
51
|
+
});
|
|
52
|
+
// Only consume the deletion/creation pair when we would auto-apply the move.
|
|
53
|
+
// If we only want to prompt, leave the original changes in place so
|
|
54
|
+
// sync can still proceed as delete+create (avoids infinite warning loop).
|
|
55
|
+
if (bestMatch.similarity >= MoveDetector.AUTO_THRESHOLD) {
|
|
56
|
+
usedCreations.add(bestMatch.file.path);
|
|
57
|
+
usedDeletions.add(deletedFile.path);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Filter out changes that are part of moves
|
|
62
|
+
const remainingChanges = changes.filter((change) => !usedCreations.has(change.path) && !usedDeletions.has(change.path));
|
|
63
|
+
return { moves, remainingChanges };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get content of a deleted file from snapshot
|
|
67
|
+
*/
|
|
68
|
+
async getDeletedFileContent(deletedFile, snapshot) {
|
|
69
|
+
const snapshotEntry = snapshot.files.get(deletedFile.path);
|
|
70
|
+
if (!snapshotEntry)
|
|
71
|
+
return null;
|
|
72
|
+
// Return remote content if available, otherwise null
|
|
73
|
+
return deletedFile.remoteContent || null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Group moves by confidence level
|
|
77
|
+
*/
|
|
78
|
+
groupMovesByConfidence(moves) {
|
|
79
|
+
const autoMoves = moves.filter((m) => m.confidence === "auto");
|
|
80
|
+
const promptMoves = moves.filter((m) => m.confidence === "prompt");
|
|
81
|
+
const lowConfidenceMoves = moves.filter((m) => m.confidence === "low");
|
|
82
|
+
return { autoMoves, promptMoves, lowConfidenceMoves };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validate move candidates to avoid conflicts
|
|
86
|
+
*/
|
|
87
|
+
validateMoves(moves) {
|
|
88
|
+
const validMoves = [];
|
|
89
|
+
const conflicts = [];
|
|
90
|
+
// Check for multiple sources mapping to same destination
|
|
91
|
+
const destinationMap = new Map();
|
|
92
|
+
for (const move of moves) {
|
|
93
|
+
if (!destinationMap.has(move.toPath)) {
|
|
94
|
+
destinationMap.set(move.toPath, []);
|
|
95
|
+
}
|
|
96
|
+
destinationMap.get(move.toPath).push(move);
|
|
97
|
+
}
|
|
98
|
+
// Check for multiple destinations from same source
|
|
99
|
+
const sourceMap = new Map();
|
|
100
|
+
for (const move of moves) {
|
|
101
|
+
if (!sourceMap.has(move.fromPath)) {
|
|
102
|
+
sourceMap.set(move.fromPath, []);
|
|
103
|
+
}
|
|
104
|
+
sourceMap.get(move.fromPath).push(move);
|
|
105
|
+
}
|
|
106
|
+
for (const move of moves) {
|
|
107
|
+
const destinationConflicts = destinationMap.get(move.toPath);
|
|
108
|
+
const sourceConflicts = sourceMap.get(move.fromPath);
|
|
109
|
+
if (destinationConflicts.length > 1) {
|
|
110
|
+
conflicts.push({
|
|
111
|
+
moves: destinationConflicts,
|
|
112
|
+
reason: `Multiple files moving to ${move.toPath}`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (sourceConflicts.length > 1) {
|
|
116
|
+
conflicts.push({
|
|
117
|
+
moves: sourceConflicts,
|
|
118
|
+
reason: `File ${move.fromPath} has multiple potential destinations`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
validMoves.push(move);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { validMoves, conflicts };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Apply move detection heuristics
|
|
129
|
+
*/
|
|
130
|
+
applyHeuristics(moves) {
|
|
131
|
+
return moves
|
|
132
|
+
.filter((move) => {
|
|
133
|
+
// Filter out moves within the same directory unless similarity is very high
|
|
134
|
+
const fromDir = this.getDirectoryPath(move.fromPath);
|
|
135
|
+
const toDir = this.getDirectoryPath(move.toPath);
|
|
136
|
+
if (fromDir === toDir && move.similarity < 0.9) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
// Filter out moves with very different file extensions unless similarity is perfect
|
|
140
|
+
const fromExt = this.getFileExtension(move.fromPath);
|
|
141
|
+
const toExt = this.getFileExtension(move.toPath);
|
|
142
|
+
if (fromExt !== toExt && move.similarity < 1.0) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
})
|
|
147
|
+
.sort((a, b) => b.similarity - a.similarity); // Sort by similarity descending
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get directory path from file path
|
|
151
|
+
*/
|
|
152
|
+
getDirectoryPath(filePath) {
|
|
153
|
+
const lastSlash = filePath.lastIndexOf("/");
|
|
154
|
+
return lastSlash >= 0 ? filePath.substring(0, lastSlash) : "";
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get file extension from file path
|
|
158
|
+
*/
|
|
159
|
+
getFileExtension(filePath) {
|
|
160
|
+
const lastDot = filePath.lastIndexOf(".");
|
|
161
|
+
const lastSlash = filePath.lastIndexOf("/");
|
|
162
|
+
if (lastDot > lastSlash && lastDot >= 0) {
|
|
163
|
+
return filePath.substring(lastDot + 1).toLowerCase();
|
|
164
|
+
}
|
|
165
|
+
return "";
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if a move should be auto-applied
|
|
169
|
+
*/
|
|
170
|
+
shouldAutoApply(move) {
|
|
171
|
+
return move.confidence === "auto";
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if a move should prompt the user
|
|
175
|
+
*/
|
|
176
|
+
shouldPromptUser(move) {
|
|
177
|
+
return move.confidence === "prompt";
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Format move for display
|
|
181
|
+
*/
|
|
182
|
+
formatMove(move) {
|
|
183
|
+
const percentage = Math.round(move.similarity * 100);
|
|
184
|
+
return `${move.fromPath} → ${move.toPath} (${percentage}% similar)`;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Calculate move statistics
|
|
188
|
+
*/
|
|
189
|
+
calculateStats(moves) {
|
|
190
|
+
const total = moves.length;
|
|
191
|
+
const auto = moves.filter((m) => m.confidence === "auto").length;
|
|
192
|
+
const prompt = moves.filter((m) => m.confidence === "prompt").length;
|
|
193
|
+
const averageSimilarity = total > 0 ? moves.reduce((sum, m) => sum + m.similarity, 0) / total : 0;
|
|
194
|
+
return { total, auto, prompt, averageSimilarity };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.MoveDetector = MoveDetector;
|
|
198
|
+
MoveDetector.AUTO_THRESHOLD = 0.8;
|
|
199
|
+
MoveDetector.PROMPT_THRESHOLD = 0.5;
|
|
200
|
+
//# sourceMappingURL=move-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-detection.js","sourceRoot":"","sources":["../../src/core/move-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pvh TODO: the files & directories could be unified into a single map of entries with a type field
|
|
3
|
+
*/
|
|
4
|
+
import { SyncSnapshot, SnapshotFileEntry, SnapshotDirectoryEntry } from "../types";
|
|
5
|
+
/**
|
|
6
|
+
* Manages sync snapshots for local state tracking
|
|
7
|
+
*/
|
|
8
|
+
export declare class SnapshotManager {
|
|
9
|
+
private rootPath;
|
|
10
|
+
private static readonly SNAPSHOT_FILENAME;
|
|
11
|
+
private static readonly SYNC_TOOL_DIR;
|
|
12
|
+
constructor(rootPath: string);
|
|
13
|
+
/**
|
|
14
|
+
* Get path to sync tool directory
|
|
15
|
+
*/
|
|
16
|
+
private getSyncToolDir;
|
|
17
|
+
/**
|
|
18
|
+
* Get path to snapshot file
|
|
19
|
+
*/
|
|
20
|
+
private getSnapshotPath;
|
|
21
|
+
/**
|
|
22
|
+
* Check if snapshot exists
|
|
23
|
+
*/
|
|
24
|
+
exists(): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Load snapshot from disk
|
|
27
|
+
*/
|
|
28
|
+
load(): Promise<SyncSnapshot | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Save snapshot to disk
|
|
31
|
+
*/
|
|
32
|
+
save(snapshot: SyncSnapshot): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Create empty snapshot
|
|
35
|
+
*/
|
|
36
|
+
createEmpty(): SyncSnapshot;
|
|
37
|
+
/**
|
|
38
|
+
* Update file entry in snapshot
|
|
39
|
+
*/
|
|
40
|
+
updateFileEntry(snapshot: SyncSnapshot, relativePath: string, entry: SnapshotFileEntry): void;
|
|
41
|
+
/**
|
|
42
|
+
* Update directory entry in snapshot
|
|
43
|
+
*/
|
|
44
|
+
updateDirectoryEntry(snapshot: SyncSnapshot, relativePath: string, entry: SnapshotDirectoryEntry): void;
|
|
45
|
+
/**
|
|
46
|
+
* Remove file entry from snapshot
|
|
47
|
+
*/
|
|
48
|
+
removeFileEntry(snapshot: SyncSnapshot, relativePath: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Remove directory entry from snapshot
|
|
51
|
+
*/
|
|
52
|
+
removeDirectoryEntry(snapshot: SyncSnapshot, relativePath: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get all file paths in snapshot
|
|
55
|
+
*/
|
|
56
|
+
getFilePaths(snapshot: SyncSnapshot): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get all directory paths in snapshot
|
|
59
|
+
*/
|
|
60
|
+
getDirectoryPaths(snapshot: SyncSnapshot): string[];
|
|
61
|
+
/**
|
|
62
|
+
* Get file entry by path
|
|
63
|
+
*/
|
|
64
|
+
getFileEntry(snapshot: SyncSnapshot, relativePath: string): SnapshotFileEntry | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Get directory entry by path
|
|
67
|
+
*/
|
|
68
|
+
getDirectoryEntry(snapshot: SyncSnapshot, relativePath: string): SnapshotDirectoryEntry | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Check if path is tracked in snapshot
|
|
71
|
+
*/
|
|
72
|
+
isTracked(snapshot: SyncSnapshot, relativePath: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Get snapshot statistics
|
|
75
|
+
*/
|
|
76
|
+
getStats(snapshot: SyncSnapshot): {
|
|
77
|
+
files: number;
|
|
78
|
+
directories: number;
|
|
79
|
+
timestamp: Date;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Backup current snapshot
|
|
83
|
+
*/
|
|
84
|
+
backup(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Validate snapshot integrity
|
|
87
|
+
*/
|
|
88
|
+
validate(snapshot: SyncSnapshot): {
|
|
89
|
+
valid: boolean;
|
|
90
|
+
errors: string[];
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Convert snapshot to serializable format
|
|
94
|
+
*/
|
|
95
|
+
private serializeSnapshot;
|
|
96
|
+
/**
|
|
97
|
+
* Convert serializable format back to snapshot
|
|
98
|
+
*/
|
|
99
|
+
private deserializeSnapshot;
|
|
100
|
+
/**
|
|
101
|
+
* Clear all snapshot data
|
|
102
|
+
*/
|
|
103
|
+
clear(snapshot: SyncSnapshot): void;
|
|
104
|
+
/**
|
|
105
|
+
* Clone snapshot for safe manipulation
|
|
106
|
+
*/
|
|
107
|
+
clone(snapshot: SyncSnapshot): SyncSnapshot;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/core/snapshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EACL,YAAY,EAEZ,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,qBAAa,eAAe;IAId,OAAO,CAAC,QAAQ;IAH5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAe;gBAEhC,QAAQ,EAAE,MAAM;IAEpC;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAiB1C;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAajD;;OAEG;IACH,WAAW,IAAI,YAAY;IAU3B;;OAEG;IACH,eAAe,CACb,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,iBAAiB,GACvB,IAAI;IAKP;;OAEG;IACH,oBAAoB,CAClB,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,sBAAsB,GAC5B,IAAI;IAKP;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAKnE;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAKxE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,EAAE;IAI9C;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,EAAE;IAInD;;OAEG;IACH,YAAY,CACV,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,iBAAiB,GAAG,SAAS;IAIhC;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,sBAAsB,GAAG,SAAS;IAIrC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAMhE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG;QAChC,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,IAAI,CAAC;KACjB;IAQD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IA8BtE;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAMnC;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY;CAS5C"}
|