@mindexec/cli 0.2.481 → 0.2.482

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.
Files changed (24) hide show
  1. package/electron/main.cjs +2 -0
  2. package/electron/source-smoke.mjs +4 -0
  3. package/electron/update-manager-smoke.mjs +14 -2
  4. package/electron/update-manager.cjs +31 -3
  5. package/package.json +6 -5
  6. package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
  7. package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
  8. package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
  9. package/scripts/desktop-update-publisher-smoke.mjs +12 -1
  10. package/scripts/desktop-update-worker-smoke.mjs +95 -0
  11. package/scripts/publish-mindexec-desktop-updates.mjs +13 -5
  12. package/wwwroot/_framework/{MindExecution.Core.2r5s0vx16i.dll → MindExecution.Core.l639gk1bj0.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Kernel.8y4azlvjyi.dll → MindExecution.Kernel.dhkjql36qa.dll} +0 -0
  14. package/wwwroot/_framework/{MindExecution.Plugins.Admin.dtzk93cn6n.dll → MindExecution.Plugins.Admin.sdnqjd3bhw.dll} +0 -0
  15. package/wwwroot/_framework/{MindExecution.Plugins.Business.uyqiv67u0q.dll → MindExecution.Plugins.Business.dntgcr4fyr.dll} +0 -0
  16. package/wwwroot/_framework/{MindExecution.Plugins.Concept.5w50lskzj6.dll → MindExecution.Plugins.Concept.jiz294lahg.dll} +0 -0
  17. package/wwwroot/_framework/{MindExecution.Plugins.Directory.a8isl4htud.dll → MindExecution.Plugins.Directory.v0qvphgk63.dll} +0 -0
  18. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.imbm6hfih7.dll → MindExecution.Plugins.PlanMaster.mvfl14g6r9.dll} +0 -0
  19. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.ua03os14kk.dll → MindExecution.Plugins.YouTube.e5ui1py8ia.dll} +0 -0
  20. package/wwwroot/_framework/{MindExecution.Shared.yxk1a55sjz.dll → MindExecution.Shared.4pev6youhl.dll} +0 -0
  21. package/wwwroot/_framework/{MindExecution.Web.9bmh8f8s3k.dll → MindExecution.Web.vzu3nwlp2r.dll} +0 -0
  22. package/wwwroot/_framework/blazor.boot.json +21 -21
  23. package/wwwroot/service-worker-assets.js +22 -22
  24. package/wwwroot/service-worker.js +1 -1
package/electron/main.cjs CHANGED
@@ -252,6 +252,8 @@ function sendUpdateStatus(status) {
252
252
  appendDesktopLog(
253
253
  `[update] state=${status.state} current=${status.currentVersion || ''} ` +
254
254
  `available=${status.availableVersion || ''} progress=${Math.round(status.progress || 0)} ` +
255
+ `bytes=${Math.round(status.downloadTransferredBytes || 0)}/${Math.round(status.downloadTotalBytes || 0)} ` +
256
+ `speed=${Math.round(status.downloadBytesPerSecond || 0)} ` +
255
257
  `kind=${status.installKind || ''}${status.error ? ` error=${status.error}` : ''}`
256
258
  );
257
259
  if (mainWindow && !mainWindow.isDestroyed() && !mainWindow.webContents.isDestroyed()) {
@@ -34,6 +34,8 @@ assert.match(packageJson.scripts?.['desktop:publish:update:dev'] || '', /--chann
34
34
  assert.equal(packageJson.dependencies?.['electron-updater'], '^6.8.9', 'The packaged updater dependency is missing.');
35
35
  assert.equal(packageJson.build?.extraMetadata?.desktopUpdateChannel, 'dev', 'Development installers must stay on the dev feed.');
36
36
  assert.equal(packageJson.build?.publish?.provider, 'generic', 'Desktop updates must use the generic R2-backed provider.');
37
+ assert.equal(packageJson.build?.publish?.useMultipleRangeRequest, false,
38
+ 'Packaged differential downloads must use one byte range per request.');
37
39
  assert.equal(
38
40
  packageJson.build?.publish?.url,
39
41
  'https://mindexec.lovecrdm.workers.dev/dev/windows/x64',
@@ -98,6 +100,8 @@ assert.match(preloadSource, /mindExecDesktop/, 'The updater preload namespace ch
98
100
  assert.match(preloadSource, /updates:\s*\{/, 'The updater preload API is missing.');
99
101
  assert.match(updateManagerSource, /autoDownload\s*=\s*false/, 'Updates must not download through an unowned implicit path.');
100
102
  assert.match(updateManagerSource, /autoInstallOnAppQuit\s*=\s*false/, 'Updates must not restart without the explicit prompt path.');
103
+ assert.match(updateManagerSource, /useMultipleRangeRequest:\s*false/,
104
+ 'Differential downloads must use Worker-compatible single byte ranges.');
101
105
  assert.match(updateManagerSource, /quitAndInstall\(true, true\)/, 'Downloaded updates must relaunch silently after approval.');
102
106
  assert.match(updateManagerSource, /desktop-updates-require-installed-windows-app/,
103
107
  'Portable and unpacked builds must fail closed instead of replacing themselves.');
@@ -31,7 +31,12 @@ class FakeUpdater extends EventEmitter {
31
31
 
32
32
  async downloadUpdate() {
33
33
  this.downloadCalls += 1;
34
- this.emit('download-progress', { percent: 42 });
34
+ this.emit('download-progress', {
35
+ percent: 42,
36
+ total: 2_737_300,
37
+ transferred: 1_149_666,
38
+ bytesPerSecond: 5_000_000
39
+ });
35
40
  await new Promise(resolve => setTimeout(resolve, 5));
36
41
  this.emit('update-downloaded', { version: '1.1.0' });
37
42
  }
@@ -79,7 +84,14 @@ test('concurrent checks share one version request and one download', async () =>
79
84
  assert.equal(second.state, 'downloaded');
80
85
  assert.equal(updater.checkCalls, 1);
81
86
  assert.equal(updater.downloadCalls, 1);
82
- assert.deepEqual(updater.feed, { provider: 'generic', url: 'https://updates.example/dev/windows/x64' });
87
+ assert.deepEqual(updater.feed, {
88
+ provider: 'generic',
89
+ url: 'https://updates.example/dev/windows/x64',
90
+ useMultipleRangeRequest: false
91
+ });
92
+ assert.equal(first.downloadTotalBytes, 2_737_300);
93
+ assert.equal(first.downloadTransferredBytes, 1_149_666);
94
+ assert.equal(first.downloadBytesPerSecond, 5_000_000);
83
95
  });
84
96
 
85
97
  test('portable and unpacked executables never call electron-updater', async () => {
@@ -49,6 +49,9 @@ function createProductUpdateManager({
49
49
  availableVersion: '',
50
50
  downloaded: false,
51
51
  progress: 0,
52
+ downloadTotalBytes: 0,
53
+ downloadTransferredBytes: 0,
54
+ downloadBytesPerSecond: 0,
52
55
  error: '',
53
56
  configured: feed.configured,
54
57
  feedUrl: feed.url,
@@ -89,7 +92,13 @@ function createProductUpdateManager({
89
92
 
90
93
  updater.autoDownload = false;
91
94
  updater.autoInstallOnAppQuit = false;
92
- if (feed.url) updater.setFeedURL({ provider: 'generic', url: feed.url });
95
+ if (feed.url) {
96
+ updater.setFeedURL({
97
+ provider: 'generic',
98
+ url: feed.url,
99
+ useMultipleRangeRequest: false
100
+ });
101
+ }
93
102
 
94
103
  updater.on('checking-for-update', () => {
95
104
  checkOutcome = 'checking';
@@ -102,15 +111,34 @@ function createProductUpdateManager({
102
111
  availableVersion: String(info?.version || ''),
103
112
  downloaded: false,
104
113
  progress: 0,
114
+ downloadTotalBytes: 0,
115
+ downloadTransferredBytes: 0,
116
+ downloadBytesPerSecond: 0,
105
117
  error: ''
106
118
  });
107
119
  });
108
120
  updater.on('update-not-available', () => {
109
121
  checkOutcome = 'current';
110
- publish({ state: 'current', availableVersion: '', downloaded: false, progress: 0, error: '' });
122
+ publish({
123
+ state: 'current',
124
+ availableVersion: '',
125
+ downloaded: false,
126
+ progress: 0,
127
+ downloadTotalBytes: 0,
128
+ downloadTransferredBytes: 0,
129
+ downloadBytesPerSecond: 0,
130
+ error: ''
131
+ });
111
132
  });
112
133
  updater.on('download-progress', progress => {
113
- publish({ state: 'downloading', progress: Number(progress?.percent || 0), error: '' });
134
+ publish({
135
+ state: 'downloading',
136
+ progress: Number(progress?.percent || 0),
137
+ downloadTotalBytes: Number(progress?.total || 0),
138
+ downloadTransferredBytes: Number(progress?.transferred || 0),
139
+ downloadBytesPerSecond: Number(progress?.bytesPerSecond || 0),
140
+ error: ''
141
+ });
114
142
  });
115
143
  updater.on('update-downloaded', info => {
116
144
  publish({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.481",
3
+ "version": "0.2.482",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -160,9 +160,10 @@
160
160
  "portable": {
161
161
  "artifactName": "MindExec-Portable-${version}-${arch}.${ext}"
162
162
  },
163
- "publish": {
164
- "provider": "generic",
165
- "url": "https://mindexec.lovecrdm.workers.dev/dev/windows/x64"
166
- }
163
+ "publish": {
164
+ "provider": "generic",
165
+ "url": "https://mindexec.lovecrdm.workers.dev/dev/windows/x64",
166
+ "useMultipleRangeRequest": false
167
+ }
167
168
  }
168
169
  }
@@ -54,6 +54,17 @@ test('publisher validates version, size, and SHA-512 before upload', async () =>
54
54
  }),
55
55
  /desktop-update-dev-unsigned-ack-required/
56
56
  );
57
+ assert.throws(
58
+ () => readReleasePlan({
59
+ platform: 'windows-x64',
60
+ directory,
61
+ packageVersion: '1.2.3',
62
+ channel: 'dev',
63
+ allowUnsigned: true
64
+ }),
65
+ /desktop-update-blockmap-missing/
66
+ );
67
+ await writeFile(join(directory, `${artifact}.blockmap`), Buffer.from('blockmap'));
57
68
  const plan = readReleasePlan({
58
69
  platform: 'windows-x64',
59
70
  directory,
@@ -62,7 +73,7 @@ test('publisher validates version, size, and SHA-512 before upload', async () =>
62
73
  allowUnsigned: true
63
74
  });
64
75
  assert.equal(plan.prefix, 'dev/windows/x64');
65
- assert.deepEqual(plan.artifacts.map(item => item.fileName), [artifact]);
76
+ assert.deepEqual(plan.artifacts.map(item => item.fileName), [artifact, `${artifact}.blockmap`]);
66
77
  assert.throws(
67
78
  () => readReleasePlan({
68
79
  platform: 'windows-x64',
@@ -70,3 +70,98 @@ test('worker preserves resumable byte-range responses for large installers', asy
70
70
  assert.equal(response.headers.get('content-range'), 'bytes 8-11/20');
71
71
  assert.equal(response.headers.get('content-length'), '4');
72
72
  });
73
+
74
+ test('worker serves electron-updater multi-range requests as multipart without returning the full installer', async () => {
75
+ const source = new TextEncoder().encode('0123456789abcdefghij');
76
+ const calls = [];
77
+ const env = {
78
+ UPDATE_BUCKET: {
79
+ head: async () => ({
80
+ size: source.byteLength,
81
+ httpEtag: '"release-etag"',
82
+ writeHttpMetadata(headers) { headers.set('content-type', 'application/octet-stream'); }
83
+ }),
84
+ get: async (_key, options) => {
85
+ calls.push(options.range);
86
+ const { offset, length } = options.range;
87
+ const bytes = source.slice(offset, offset + length);
88
+ return {
89
+ body: new ReadableStream({ start(controller) { controller.enqueue(bytes); controller.close(); } }),
90
+ size: source.byteLength,
91
+ range: { offset, length },
92
+ httpEtag: '"release-etag"',
93
+ writeHttpMetadata(headers) { headers.set('content-type', 'application/octet-stream'); }
94
+ };
95
+ }
96
+ }
97
+ };
98
+
99
+ const response = await worker.fetch(new Request(
100
+ 'https://updates.example/dev/windows/x64/MindExec-0.2.461-dev-x64.exe',
101
+ { headers: { range: 'bytes=0-3,10-13' } }
102
+ ), env);
103
+ const body = await response.text();
104
+
105
+ assert.equal(response.status, 206);
106
+ assert.match(response.headers.get('content-type') || '', /^multipart\/byteranges; boundary=/i);
107
+ assert.equal(response.headers.has('content-range'), false);
108
+ assert.deepEqual(calls, [{ offset: 0, length: 4 }, { offset: 10, length: 4 }]);
109
+ assert.match(body, /Content-Range: bytes 0-3\/20\r\n\r\n0123/);
110
+ assert.match(body, /Content-Range: bytes 10-13\/20\r\n\r\nabcd/);
111
+ assert.equal(new TextEncoder().encode(body).byteLength, Number(response.headers.get('content-length')));
112
+ assert.ok(Number(response.headers.get('content-length')) < source.byteLength * 20,
113
+ 'multi-range response must contain only requested parts, not the full installer');
114
+ });
115
+
116
+ test('worker rejects oversized or overlapping multi-range requests before reading R2', async () => {
117
+ let getCount = 0;
118
+ const metadata = {
119
+ size: 100_000_000,
120
+ httpEtag: '"release-etag"',
121
+ writeHttpMetadata(headers) { headers.set('content-type', 'application/octet-stream'); }
122
+ };
123
+ const env = {
124
+ UPDATE_BUCKET: {
125
+ head: async () => metadata,
126
+ get: async () => { getCount += 1; return null; }
127
+ }
128
+ };
129
+
130
+ const oversized = await worker.fetch(new Request(
131
+ 'https://updates.example/dev/windows/x64/MindExec-0.2.461-dev-x64.exe',
132
+ { headers: { range: 'bytes=0-33554431,33554432-67108864' } }
133
+ ), env);
134
+ assert.equal(oversized.status, 416);
135
+
136
+ const overlapping = await worker.fetch(new Request(
137
+ 'https://updates.example/dev/windows/x64/MindExec-0.2.461-dev-x64.exe',
138
+ { headers: { range: 'bytes=0-10,10-20' } }
139
+ ), env);
140
+ assert.equal(overlapping.status, 416);
141
+ assert.equal(getCount, 0);
142
+ });
143
+
144
+ test('worker fails closed when R2 does not honor an explicit multipart range', async () => {
145
+ const source = new TextEncoder().encode('0123456789abcdefghij');
146
+ const metadata = {
147
+ size: source.byteLength,
148
+ httpEtag: '"release-etag"',
149
+ writeHttpMetadata(headers) { headers.set('content-type', 'application/octet-stream'); }
150
+ };
151
+ const env = {
152
+ UPDATE_BUCKET: {
153
+ head: async () => metadata,
154
+ get: async () => ({
155
+ ...metadata,
156
+ range: { offset: 0, length: source.byteLength },
157
+ body: new ReadableStream({ start(controller) { controller.enqueue(source); controller.close(); } })
158
+ })
159
+ }
160
+ };
161
+
162
+ const response = await worker.fetch(new Request(
163
+ 'https://updates.example/dev/windows/x64/MindExec-0.2.461-dev-x64.exe',
164
+ { headers: { range: 'bytes=0-3,10-13' } }
165
+ ), env);
166
+ await assert.rejects(response.arrayBuffer(), /desktop-update-range-mismatch:0-3/);
167
+ });
@@ -100,6 +100,12 @@ export function readReleasePlan({
100
100
  if (sha512Base64(filePath) !== item.sha512) {
101
101
  throw new Error(`desktop-update-artifact-hash-mismatch:${item.name}`);
102
102
  }
103
+ if (/\.exe$/i.test(item.name)) {
104
+ const blockmapName = `${item.name}.blockmap`;
105
+ if (!existsSync(resolve(releaseDir, blockmapName))) {
106
+ throw new Error(`desktop-update-blockmap-missing:${blockmapName}`);
107
+ }
108
+ }
103
109
  }
104
110
 
105
111
  const artifacts = readdirSync(releaseDir)
@@ -164,15 +170,17 @@ async function verifyPublished(plan) {
164
170
  throw new Error('desktop-update-public-manifest-mismatch');
165
171
  }
166
172
 
167
- for (const item of plan.manifest.files) {
168
- const artifactResponse = await fetch(`${PUBLIC_BASE_URL}/${plan.prefix}/${encodeURIComponent(item.name)}`, {
173
+ for (const artifact of plan.artifacts) {
174
+ const artifactResponse = await fetch(`${PUBLIC_BASE_URL}/${plan.prefix}/${encodeURIComponent(artifact.fileName)}`, {
169
175
  method: 'HEAD',
170
176
  cache: 'no-store'
171
177
  });
172
- if (!artifactResponse.ok) throw new Error(`desktop-update-public-artifact-http-${artifactResponse.status}:${item.name}`);
173
- const expectedSize = item.size || statSync(resolve(plan.manifest.filePath, '..', item.name)).size;
178
+ if (!artifactResponse.ok) {
179
+ throw new Error(`desktop-update-public-artifact-http-${artifactResponse.status}:${artifact.fileName}`);
180
+ }
181
+ const expectedSize = statSync(artifact.filePath).size;
174
182
  if (Number(artifactResponse.headers.get('content-length') || 0) !== expectedSize) {
175
- throw new Error(`desktop-update-public-artifact-size-mismatch:${item.name}`);
183
+ throw new Error(`desktop-update-public-artifact-size-mismatch:${artifact.fileName}`);
176
184
  }
177
185
  }
178
186
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-mXWbB+r0wD5ixhld4+MKtYH4yPbQ7mRkmT7v8rgb2+E=",
4
+ "hash": "sha256-G3h1Bw32VT2isfx70lg1F1v94ewdn/kwAWOD4zpsU0U=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -122,16 +122,16 @@
122
122
  "System.brmz7yk5qh.dll": "System.dll",
123
123
  "netstandard.b50t77veor.dll": "netstandard.dll",
124
124
  "System.Private.CoreLib.wflwsce1yq.dll": "System.Private.CoreLib.dll",
125
- "MindExecution.Core.2r5s0vx16i.dll": "MindExecution.Core.dll",
126
- "MindExecution.Kernel.8y4azlvjyi.dll": "MindExecution.Kernel.dll",
127
- "MindExecution.Plugins.Admin.dtzk93cn6n.dll": "MindExecution.Plugins.Admin.dll",
128
- "MindExecution.Plugins.Business.uyqiv67u0q.dll": "MindExecution.Plugins.Business.dll",
129
- "MindExecution.Plugins.Concept.5w50lskzj6.dll": "MindExecution.Plugins.Concept.dll",
130
- "MindExecution.Plugins.Directory.a8isl4htud.dll": "MindExecution.Plugins.Directory.dll",
131
- "MindExecution.Plugins.PlanMaster.imbm6hfih7.dll": "MindExecution.Plugins.PlanMaster.dll",
132
- "MindExecution.Plugins.YouTube.ua03os14kk.dll": "MindExecution.Plugins.YouTube.dll",
133
- "MindExecution.Shared.yxk1a55sjz.dll": "MindExecution.Shared.dll",
134
- "MindExecution.Web.9bmh8f8s3k.dll": "MindExecution.Web.dll",
125
+ "MindExecution.Core.l639gk1bj0.dll": "MindExecution.Core.dll",
126
+ "MindExecution.Kernel.dhkjql36qa.dll": "MindExecution.Kernel.dll",
127
+ "MindExecution.Plugins.Admin.sdnqjd3bhw.dll": "MindExecution.Plugins.Admin.dll",
128
+ "MindExecution.Plugins.Business.dntgcr4fyr.dll": "MindExecution.Plugins.Business.dll",
129
+ "MindExecution.Plugins.Concept.jiz294lahg.dll": "MindExecution.Plugins.Concept.dll",
130
+ "MindExecution.Plugins.Directory.v0qvphgk63.dll": "MindExecution.Plugins.Directory.dll",
131
+ "MindExecution.Plugins.PlanMaster.mvfl14g6r9.dll": "MindExecution.Plugins.PlanMaster.dll",
132
+ "MindExecution.Plugins.YouTube.e5ui1py8ia.dll": "MindExecution.Plugins.YouTube.dll",
133
+ "MindExecution.Shared.4pev6youhl.dll": "MindExecution.Shared.dll",
134
+ "MindExecution.Web.vzu3nwlp2r.dll": "MindExecution.Web.dll",
135
135
  "dotnet.native.566r55w3xu.js": "dotnet.native.js",
136
136
  "dotnet.native.x6q5aixc38.wasm": "dotnet.native.wasm",
137
137
  "dotnet.js": "dotnet.js",
@@ -276,18 +276,18 @@
276
276
  "System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
277
277
  "System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
278
278
  "netstandard.b50t77veor.dll": "sha256-//jQGOXjb8ET8WtXgOJrAxLx6E7zDJ5RjRRutwkvmxo=",
279
- "MindExecution.Core.2r5s0vx16i.dll": "sha256-Hji7EvwLtfgPOiDYgH4DHXZibPhbdWcYiGPG4NjYCWg=",
280
- "MindExecution.Kernel.8y4azlvjyi.dll": "sha256-cKFcW5yNWguo2InCvgpimy5t/MhGZ2f5zITqvF99lvg=",
281
- "MindExecution.Plugins.Business.uyqiv67u0q.dll": "sha256-BqDkv3XHSL10h0Lda9sJCj4NVrhijSowakl9dgGKCzk=",
282
- "MindExecution.Plugins.Concept.5w50lskzj6.dll": "sha256-1UKv7Dxs0goKcQOkSsYBdhbE7Vp5Oy4YpqvXOtzEMHM=",
283
- "MindExecution.Plugins.PlanMaster.imbm6hfih7.dll": "sha256-pgGCEAp8dmn511srw7KD/2fctoAJgnHAzcvGWbhoWG4=",
284
- "MindExecution.Shared.yxk1a55sjz.dll": "sha256-Ru7/Qulj+40HqtPdqDs5O6dNvshmQ6JngyipwN4/dcs=",
285
- "MindExecution.Web.9bmh8f8s3k.dll": "sha256-Na9Tbn6PRhJ3L72qs5aIn+/ahlhtzZIxWc7r8G/vAtk="
279
+ "MindExecution.Core.l639gk1bj0.dll": "sha256-o9dLvKGmstXiu50XUmRpwwsv/y81aA/NGRnKJy/1mks=",
280
+ "MindExecution.Kernel.dhkjql36qa.dll": "sha256-cWxc5rwjR4RYwAhGrlp5vxEiT7qneX2jrUTLWjL37CY=",
281
+ "MindExecution.Plugins.Business.dntgcr4fyr.dll": "sha256-GdIOYT2OuYdKorFOcfSWztPr8NIXddBdSj2kDJGORQw=",
282
+ "MindExecution.Plugins.Concept.jiz294lahg.dll": "sha256-SymfLnM0iJss9UJY7xGZXwfVzzl2NvfpKrrIVhmpW2I=",
283
+ "MindExecution.Plugins.PlanMaster.mvfl14g6r9.dll": "sha256-ovRoi3461C9eaSGfnBsDjS4EZKOZVhw3fLC7RELZUPU=",
284
+ "MindExecution.Shared.4pev6youhl.dll": "sha256-KOoTEe4T+zZNRFKjb8sO4/v/Q0X/ZQ8riPIs+8Nomak=",
285
+ "MindExecution.Web.vzu3nwlp2r.dll": "sha256-VblMDl0VAUvXDfnNtQPlWo00If/P1WCx7Bo7y2+prrQ="
286
286
  },
287
287
  "lazyAssembly": {
288
- "MindExecution.Plugins.Admin.dtzk93cn6n.dll": "sha256-UQfkrWbcBYN30pXQ3RWIZqQwygXIvaBBqc/H6hqiTyE=",
289
- "MindExecution.Plugins.Directory.a8isl4htud.dll": "sha256-tp9XZ/Nxysn/xuTsD8lsKyJt++V8GjSkjsXm++ZxhVk=",
290
- "MindExecution.Plugins.YouTube.ua03os14kk.dll": "sha256-Rjxv6t01L71frLHXiB3nNEeuVc9CK7OOYtF8UwUyhSI="
288
+ "MindExecution.Plugins.Admin.sdnqjd3bhw.dll": "sha256-4C8f3TLtj/VLuY9CpNvtPkWw5VtZl5ZnDe+Xq4d9LTU=",
289
+ "MindExecution.Plugins.Directory.v0qvphgk63.dll": "sha256-fzKMUnP4AFBBYkFh1IuhGyl7KMMkmCGKqlnPu4QBWUs=",
290
+ "MindExecution.Plugins.YouTube.e5ui1py8ia.dll": "sha256-Ii4ds8rpDHBAXVQKrb3AATbtF0MfTw51Iqu44nzVBx0="
291
291
  }
292
292
  },
293
293
  "cacheBootResources": true,
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "TXjYyM9d",
2
+ "version": "tcfcurmf",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -446,44 +446,44 @@ self.assetsManifest = {
446
446
  "url": "_framework/MimeMapping.og9ys58ylm.dll"
447
447
  },
448
448
  {
449
- "hash": "sha256-Hji7EvwLtfgPOiDYgH4DHXZibPhbdWcYiGPG4NjYCWg=",
450
- "url": "_framework/MindExecution.Core.2r5s0vx16i.dll"
449
+ "hash": "sha256-o9dLvKGmstXiu50XUmRpwwsv/y81aA/NGRnKJy/1mks=",
450
+ "url": "_framework/MindExecution.Core.l639gk1bj0.dll"
451
451
  },
452
452
  {
453
- "hash": "sha256-cKFcW5yNWguo2InCvgpimy5t/MhGZ2f5zITqvF99lvg=",
454
- "url": "_framework/MindExecution.Kernel.8y4azlvjyi.dll"
453
+ "hash": "sha256-cWxc5rwjR4RYwAhGrlp5vxEiT7qneX2jrUTLWjL37CY=",
454
+ "url": "_framework/MindExecution.Kernel.dhkjql36qa.dll"
455
455
  },
456
456
  {
457
- "hash": "sha256-UQfkrWbcBYN30pXQ3RWIZqQwygXIvaBBqc/H6hqiTyE=",
458
- "url": "_framework/MindExecution.Plugins.Admin.dtzk93cn6n.dll"
457
+ "hash": "sha256-4C8f3TLtj/VLuY9CpNvtPkWw5VtZl5ZnDe+Xq4d9LTU=",
458
+ "url": "_framework/MindExecution.Plugins.Admin.sdnqjd3bhw.dll"
459
459
  },
460
460
  {
461
- "hash": "sha256-BqDkv3XHSL10h0Lda9sJCj4NVrhijSowakl9dgGKCzk=",
462
- "url": "_framework/MindExecution.Plugins.Business.uyqiv67u0q.dll"
461
+ "hash": "sha256-GdIOYT2OuYdKorFOcfSWztPr8NIXddBdSj2kDJGORQw=",
462
+ "url": "_framework/MindExecution.Plugins.Business.dntgcr4fyr.dll"
463
463
  },
464
464
  {
465
- "hash": "sha256-1UKv7Dxs0goKcQOkSsYBdhbE7Vp5Oy4YpqvXOtzEMHM=",
466
- "url": "_framework/MindExecution.Plugins.Concept.5w50lskzj6.dll"
465
+ "hash": "sha256-SymfLnM0iJss9UJY7xGZXwfVzzl2NvfpKrrIVhmpW2I=",
466
+ "url": "_framework/MindExecution.Plugins.Concept.jiz294lahg.dll"
467
467
  },
468
468
  {
469
- "hash": "sha256-tp9XZ/Nxysn/xuTsD8lsKyJt++V8GjSkjsXm++ZxhVk=",
470
- "url": "_framework/MindExecution.Plugins.Directory.a8isl4htud.dll"
469
+ "hash": "sha256-fzKMUnP4AFBBYkFh1IuhGyl7KMMkmCGKqlnPu4QBWUs=",
470
+ "url": "_framework/MindExecution.Plugins.Directory.v0qvphgk63.dll"
471
471
  },
472
472
  {
473
- "hash": "sha256-pgGCEAp8dmn511srw7KD/2fctoAJgnHAzcvGWbhoWG4=",
474
- "url": "_framework/MindExecution.Plugins.PlanMaster.imbm6hfih7.dll"
473
+ "hash": "sha256-ovRoi3461C9eaSGfnBsDjS4EZKOZVhw3fLC7RELZUPU=",
474
+ "url": "_framework/MindExecution.Plugins.PlanMaster.mvfl14g6r9.dll"
475
475
  },
476
476
  {
477
- "hash": "sha256-Rjxv6t01L71frLHXiB3nNEeuVc9CK7OOYtF8UwUyhSI=",
478
- "url": "_framework/MindExecution.Plugins.YouTube.ua03os14kk.dll"
477
+ "hash": "sha256-Ii4ds8rpDHBAXVQKrb3AATbtF0MfTw51Iqu44nzVBx0=",
478
+ "url": "_framework/MindExecution.Plugins.YouTube.e5ui1py8ia.dll"
479
479
  },
480
480
  {
481
- "hash": "sha256-Ru7/Qulj+40HqtPdqDs5O6dNvshmQ6JngyipwN4/dcs=",
482
- "url": "_framework/MindExecution.Shared.yxk1a55sjz.dll"
481
+ "hash": "sha256-KOoTEe4T+zZNRFKjb8sO4/v/Q0X/ZQ8riPIs+8Nomak=",
482
+ "url": "_framework/MindExecution.Shared.4pev6youhl.dll"
483
483
  },
484
484
  {
485
- "hash": "sha256-Na9Tbn6PRhJ3L72qs5aIn+/ahlhtzZIxWc7r8G/vAtk=",
486
- "url": "_framework/MindExecution.Web.9bmh8f8s3k.dll"
485
+ "hash": "sha256-VblMDl0VAUvXDfnNtQPlWo00If/P1WCx7Bo7y2+prrQ=",
486
+ "url": "_framework/MindExecution.Web.vzu3nwlp2r.dll"
487
487
  },
488
488
  {
489
489
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -802,7 +802,7 @@ self.assetsManifest = {
802
802
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
803
803
  },
804
804
  {
805
- "hash": "sha256-WvsgoQTqkn6gicUIMbadHK3hWH9MBshwEhAMOUntDlA=",
805
+ "hash": "sha256-00g6lZAcB0GYDBhxl4x36IRIi/jFnPu33Z7RB0uqomA=",
806
806
  "url": "_framework/blazor.boot.json"
807
807
  },
808
808
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: TXjYyM9d */
1
+ /* Manifest version: tcfcurmf */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4