@camstack/addon-training 0.0.0-stage → 0.1.1

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 (40) hide show
  1. package/assets/training/icon.svg +5 -0
  2. package/assets/training-modal/icon.svg +4 -0
  3. package/dist/MaskShapeCanvas-BokARvOj.mjs +13806 -0
  4. package/dist/MotionZonesSettings-aj085Nrn.mjs +310 -0
  5. package/dist/PrivacyMaskSettings-BwYjIkQR.mjs +377 -0
  6. package/dist/SceneMonitorEditor-BBfow3Lm.mjs +831 -0
  7. package/dist/_stub.js +17613 -0
  8. package/dist/_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-CspLU0I2.mjs +156 -0
  9. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.js-ZeT4eUYy.mjs +25 -0
  10. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BkKuzhOJ.mjs +26 -0
  11. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CaB1jnkt.mjs +25 -0
  12. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-B3rryujf.mjs +25 -0
  13. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-nL4MGFRP.mjs +26 -0
  14. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs +70 -0
  15. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs +26 -0
  16. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-i_pnGDxd.mjs +25 -0
  17. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-gTIQrhKs.mjs +25 -0
  18. package/dist/addon-training.css +3 -0
  19. package/dist/dist-BnT7Wsvm.mjs +52556 -0
  20. package/dist/dist-WGwGDX6_.js +52708 -0
  21. package/dist/hostInit-Dl0wFDad.mjs +129 -0
  22. package/dist/index.js +205 -0
  23. package/dist/index.mjs +201 -0
  24. package/dist/orchestrator/training.addon.js +1712 -0
  25. package/dist/orchestrator/training.addon.mjs +1710 -0
  26. package/dist/player-overlays-wE5IcDiI.mjs +44 -0
  27. package/dist/providers/modal/training-modal.addon.js +88499 -0
  28. package/dist/providers/modal/training-modal.addon.mjs +88527 -0
  29. package/dist/remoteEntry.js +2 -0
  30. package/dist/remoteEntry.ssr.js +33 -0
  31. package/dist/responsive-D17kMsm1.mjs +122 -0
  32. package/dist/rolldown-runtime-HEgqtunE.mjs +20 -0
  33. package/dist/scene-monitor-copy-LjlvhSRM.mjs +187 -0
  34. package/dist/square-JGDHhLlY.mjs +45 -0
  35. package/dist/trash-2-zeFnLJvf.mjs +25 -0
  36. package/dist/virtualExposes-0m8NqEDE.mjs +27 -0
  37. package/dist/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-iFB6fGI7.mjs +2857 -0
  38. package/dist/virtual_mf-exposes-ssr___mfe_internal__addon_training_page__remoteEntry_js-BbeHzLhl.mjs +10 -0
  39. package/package.json +116 -4
  40. package/README.md +0 -3
@@ -0,0 +1,129 @@
1
+ //#region \0virtual:mf:__mfe_internal__addon_training_page__H_A_I__hostAutoInit__H_A_I__.js
2
+ var e = "__mf_module_cache__";
3
+ globalThis[e] ||= {
4
+ share: {},
5
+ remote: {}
6
+ }, globalThis[e].share ||= {}, globalThis[e].remote ||= {};
7
+ var t = globalThis[e], n;
8
+ async function r() {
9
+ return n ||= (async () => {
10
+ let e = await (await import("./remoteEntry.js")).init(), n = {
11
+ react: {
12
+ version: "19.2.7",
13
+ scope: "default",
14
+ shareConfig: {
15
+ singleton: !0,
16
+ requiredVersion: "*",
17
+ import: !1
18
+ }
19
+ },
20
+ "react-dom": {
21
+ version: "19.2.7",
22
+ scope: "default",
23
+ shareConfig: {
24
+ singleton: !0,
25
+ requiredVersion: "*",
26
+ import: !1
27
+ }
28
+ },
29
+ "react/jsx-runtime": {
30
+ version: "19.2.7",
31
+ scope: "default",
32
+ shareConfig: {
33
+ singleton: !0,
34
+ requiredVersion: "*",
35
+ import: !1
36
+ }
37
+ },
38
+ "@camstack/types": {
39
+ version: "1.2.333",
40
+ scope: "default",
41
+ shareConfig: {
42
+ singleton: !0,
43
+ requiredVersion: "*",
44
+ import: !1
45
+ }
46
+ },
47
+ "@camstack/sdk": {
48
+ version: "1.2.128",
49
+ scope: "default",
50
+ shareConfig: {
51
+ singleton: !0,
52
+ requiredVersion: "*",
53
+ import: !1
54
+ }
55
+ },
56
+ "@tanstack/react-query": {
57
+ version: "5.101.0",
58
+ scope: "default",
59
+ shareConfig: {
60
+ singleton: !0,
61
+ requiredVersion: "*",
62
+ import: !1
63
+ }
64
+ },
65
+ "@trpc/client": {
66
+ version: "11.18.0",
67
+ scope: "default",
68
+ shareConfig: {
69
+ singleton: !0,
70
+ requiredVersion: "*",
71
+ import: !1
72
+ }
73
+ },
74
+ "@trpc/react-query": {
75
+ version: "11.18.0",
76
+ scope: "default",
77
+ shareConfig: {
78
+ singleton: !0,
79
+ requiredVersion: "*",
80
+ import: !1
81
+ }
82
+ },
83
+ "@camstack/ui-library": {
84
+ version: "1.2.254",
85
+ scope: "default",
86
+ shareConfig: {
87
+ singleton: !0,
88
+ requiredVersion: "*",
89
+ import: !1
90
+ }
91
+ },
92
+ "react-dom/client": {
93
+ version: "19.2.7",
94
+ scope: "default",
95
+ shareConfig: {
96
+ singleton: !0,
97
+ requiredVersion: "*",
98
+ import: !1
99
+ }
100
+ }
101
+ }, r = (e, t, n, r) => {
102
+ let i = ((Array.isArray(r) ? r[0] : r) || "default") + ":";
103
+ return t || !n ? i + e : i + e + "@" + n;
104
+ }, i = (e) => {
105
+ let t = e;
106
+ for (let e = 0; e < 5; e++) {
107
+ let e = t?.default;
108
+ if (!e || typeof e != "object" || Object.keys(e).length === 0) break;
109
+ let n = Object.keys(t).filter((e) => e !== "default").map((e) => t[e]);
110
+ if (n.length > 0 && n.some((e) => e !== void 0)) break;
111
+ t = e;
112
+ }
113
+ return t;
114
+ };
115
+ for (let [a, o] of Object.entries(n)) {
116
+ let n = r(a, o.shareConfig?.singleton, o.version, o.scope);
117
+ t.share[n] === void 0 && await e.loadShare(a, { customShareInfo: { shareConfig: o.shareConfig } }).then((e) => {
118
+ let r = typeof e == "function" ? e() : e;
119
+ return Promise.resolve(r).then((e) => {
120
+ t.share[n] = i(e);
121
+ });
122
+ });
123
+ }
124
+ return await Promise.all([]), e;
125
+ })(), n;
126
+ }
127
+ n = r();
128
+ //#endregion
129
+ export { n as hostInitPromise, r as initHost };
package/dist/index.js ADDED
@@ -0,0 +1,205 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("./dist-WGwGDX6_.js");
3
+ const require_orchestrator_training_addon = require("./orchestrator/training.addon.js");
4
+ const require_providers_modal_training_modal_addon = require("./providers/modal/training-modal.addon.js");
5
+ //#region src/providers/fake/fake-provider.ts
6
+ var FakeTrainingProvider = class {
7
+ addonId;
8
+ jobs = /* @__PURE__ */ new Map();
9
+ calls = [];
10
+ configured;
11
+ options;
12
+ constructor(options) {
13
+ this.options = options;
14
+ this.addonId = options.addonId ?? "training-fake";
15
+ this.configured = options.configured ?? true;
16
+ }
17
+ advance(jobKey, state, exitCode) {
18
+ const job = this.require(jobKey);
19
+ job.state = state;
20
+ if (state === "running" && job.startedAt === null) job.startedAt = this.options.now();
21
+ if (state === "succeeded" || state === "failed" || state === "cancelled") {
22
+ job.endedAt = this.options.now();
23
+ job.exitCode = exitCode ?? (state === "succeeded" ? 0 : 1);
24
+ }
25
+ }
26
+ emit(jobKey, ...texts) {
27
+ const job = this.require(jobKey);
28
+ for (const text of texts) job.logs.push({
29
+ ts: this.options.now(),
30
+ text
31
+ });
32
+ }
33
+ setCost(jobKey, usd) {
34
+ this.require(jobKey).costUsd = usd;
35
+ }
36
+ finish(jobKey, outcome) {
37
+ const job = this.require(jobKey);
38
+ job.resultText = outcome.resultText;
39
+ job.bundle = outcome.bundle;
40
+ }
41
+ /** The provider forgets the job (account reset, retention). */
42
+ forget(jobKey) {
43
+ this.jobs.delete(jobKey);
44
+ }
45
+ /** A job started outside our records (a crashed hub, a second hub on the account). */
46
+ plantOrphan(jobKey) {
47
+ this.jobs.set(jobKey, this.blank(jobKey, "running"));
48
+ }
49
+ describe = async () => [{
50
+ addonId: this.addonId,
51
+ kind: "fake",
52
+ label: "Fake cloud",
53
+ gpuTypes: [{
54
+ id: "L4",
55
+ label: "L4",
56
+ usdPerHour: .8,
57
+ vramGb: 24
58
+ }],
59
+ regions: [{
60
+ id: "",
61
+ label: "Any",
62
+ priceMultiplier: 1
63
+ }],
64
+ maxDatasetBytes: 10 * 1024 ** 3,
65
+ maxRuntimeSec: 24 * 3600,
66
+ dataResidencyNote: "The fake keeps everything in memory.",
67
+ configured: this.configured,
68
+ defaults: {
69
+ gpuType: "L4",
70
+ region: "",
71
+ costCapUsd: this.options.costCapUsd ?? 5,
72
+ maxRuntimeSec: 4 * 3600,
73
+ failedDatasetGraceHours: this.options.failedDatasetGraceHours ?? 24
74
+ }
75
+ }];
76
+ validateCredentials = async () => this.configured ? {
77
+ ok: true,
78
+ account: "fake-workspace"
79
+ } : {
80
+ ok: false,
81
+ reason: "missing"
82
+ };
83
+ estimateJob = async (input) => ({
84
+ usdLow: input.gpuSecondsLow / 3600 * .8,
85
+ usdHigh: input.gpuSecondsHigh / 3600 * .8,
86
+ notes: []
87
+ });
88
+ uploadDataset = async (input) => {
89
+ this.calls.push(`upload:${input.jobKey}`);
90
+ const taken = await this.options.peer.take(input.ticket);
91
+ const job = this.jobs.get(input.jobKey) ?? this.blank(input.jobKey, "pending");
92
+ job.dataset = {
93
+ bytes: taken.bytes.length,
94
+ sha256: taken.sha256
95
+ };
96
+ job.datasetDeleted = false;
97
+ this.jobs.set(input.jobKey, job);
98
+ return {
99
+ bytes: taken.bytes.length,
100
+ sha256: taken.sha256
101
+ };
102
+ };
103
+ submitJob = async (input) => {
104
+ this.calls.push(`submit:${input.jobKey}`);
105
+ const job = this.jobs.get(input.jobKey) ?? this.blank(input.jobKey, "pending");
106
+ job.submits += 1;
107
+ if (job.jobSpecJson === null) job.jobSpecJson = input.jobSpecJson;
108
+ this.jobs.set(input.jobKey, job);
109
+ return this.status(job);
110
+ };
111
+ getJob = async (input) => {
112
+ const job = this.jobs.get(input.jobKey);
113
+ return job === void 0 ? this.lostStatus(input.jobKey) : this.status(job);
114
+ };
115
+ listJobEvents = async (input) => {
116
+ const job = this.jobs.get(input.jobKey);
117
+ const from = input.cursor === void 0 ? 0 : Number(input.cursor);
118
+ const lines = job === void 0 ? [] : job.logs.slice(from, from + input.max);
119
+ return {
120
+ lines,
121
+ cursor: String(from + lines.length)
122
+ };
123
+ };
124
+ cancelJob = async (input) => {
125
+ this.calls.push(`cancel:${input.jobKey}`);
126
+ const job = this.jobs.get(input.jobKey);
127
+ if (job !== void 0 && (job.state === "pending" || job.state === "starting" || job.state === "running")) {
128
+ job.state = "cancelled";
129
+ job.endedAt = this.options.now();
130
+ }
131
+ return { ok: true };
132
+ };
133
+ readResult = async (input) => {
134
+ const text = this.jobs.get(input.jobKey)?.resultText ?? null;
135
+ return text === null ? { found: false } : {
136
+ found: true,
137
+ text
138
+ };
139
+ };
140
+ offerArtifact = async (input) => {
141
+ const bundle = this.jobs.get(input.jobKey)?.bundle ?? null;
142
+ if (bundle === null) throw new Error(`no bundle for ${input.jobKey}`);
143
+ return { ticket: this.options.peer.offer(bundle) };
144
+ };
145
+ cleanupJob = async (input) => {
146
+ this.calls.push(`cleanup:${input.jobKey}`);
147
+ const job = this.jobs.get(input.jobKey);
148
+ if (job === void 0 || job.datasetDeleted) return { deleted: [] };
149
+ job.datasetDeleted = true;
150
+ return { deleted: [`cst-ds-${input.jobKey}`] };
151
+ };
152
+ listJobs = async () => [...this.jobs.values()].filter((j) => !j.datasetDeleted).map((j) => this.status(j));
153
+ require(jobKey) {
154
+ const job = this.jobs.get(jobKey);
155
+ if (job === void 0) throw new Error(`fake provider: no job ${jobKey}`);
156
+ return job;
157
+ }
158
+ blank(jobKey, state) {
159
+ return {
160
+ jobKey,
161
+ state,
162
+ submits: 0,
163
+ startedAt: state === "running" ? this.options.now() : null,
164
+ endedAt: null,
165
+ exitCode: null,
166
+ costUsd: 0,
167
+ jobSpecJson: null,
168
+ dataset: null,
169
+ datasetDeleted: false,
170
+ logs: [],
171
+ resultText: null,
172
+ bundle: null
173
+ };
174
+ }
175
+ status(job) {
176
+ return {
177
+ jobKey: job.jobKey,
178
+ providerJobId: `fake-${job.jobKey}`,
179
+ state: job.state,
180
+ ...job.startedAt !== null ? { startedAt: job.startedAt } : {},
181
+ ...job.endedAt !== null ? { endedAt: job.endedAt } : {},
182
+ ...job.exitCode !== null ? { exitCode: job.exitCode } : {},
183
+ gpuType: "L4",
184
+ billedSeconds: 0,
185
+ costUsd: job.costUsd,
186
+ costIsEstimate: true,
187
+ lastFetchedAt: this.options.now()
188
+ };
189
+ }
190
+ lostStatus(jobKey) {
191
+ return {
192
+ jobKey,
193
+ state: "lost",
194
+ gpuType: "L4",
195
+ billedSeconds: 0,
196
+ costUsd: 0,
197
+ costIsEstimate: true,
198
+ lastFetchedAt: this.options.now()
199
+ };
200
+ }
201
+ };
202
+ //#endregion
203
+ exports.FakeTrainingProvider = FakeTrainingProvider;
204
+ exports.TrainingAddon = require_orchestrator_training_addon.TrainingAddon;
205
+ exports.TrainingModalAddon = require_providers_modal_training_modal_addon.TrainingModalAddon;
package/dist/index.mjs ADDED
@@ -0,0 +1,201 @@
1
+ import { TrainingAddon } from "./orchestrator/training.addon.mjs";
2
+ import { TrainingModalAddon } from "./providers/modal/training-modal.addon.mjs";
3
+ //#region src/providers/fake/fake-provider.ts
4
+ var FakeTrainingProvider = class {
5
+ addonId;
6
+ jobs = /* @__PURE__ */ new Map();
7
+ calls = [];
8
+ configured;
9
+ options;
10
+ constructor(options) {
11
+ this.options = options;
12
+ this.addonId = options.addonId ?? "training-fake";
13
+ this.configured = options.configured ?? true;
14
+ }
15
+ advance(jobKey, state, exitCode) {
16
+ const job = this.require(jobKey);
17
+ job.state = state;
18
+ if (state === "running" && job.startedAt === null) job.startedAt = this.options.now();
19
+ if (state === "succeeded" || state === "failed" || state === "cancelled") {
20
+ job.endedAt = this.options.now();
21
+ job.exitCode = exitCode ?? (state === "succeeded" ? 0 : 1);
22
+ }
23
+ }
24
+ emit(jobKey, ...texts) {
25
+ const job = this.require(jobKey);
26
+ for (const text of texts) job.logs.push({
27
+ ts: this.options.now(),
28
+ text
29
+ });
30
+ }
31
+ setCost(jobKey, usd) {
32
+ this.require(jobKey).costUsd = usd;
33
+ }
34
+ finish(jobKey, outcome) {
35
+ const job = this.require(jobKey);
36
+ job.resultText = outcome.resultText;
37
+ job.bundle = outcome.bundle;
38
+ }
39
+ /** The provider forgets the job (account reset, retention). */
40
+ forget(jobKey) {
41
+ this.jobs.delete(jobKey);
42
+ }
43
+ /** A job started outside our records (a crashed hub, a second hub on the account). */
44
+ plantOrphan(jobKey) {
45
+ this.jobs.set(jobKey, this.blank(jobKey, "running"));
46
+ }
47
+ describe = async () => [{
48
+ addonId: this.addonId,
49
+ kind: "fake",
50
+ label: "Fake cloud",
51
+ gpuTypes: [{
52
+ id: "L4",
53
+ label: "L4",
54
+ usdPerHour: .8,
55
+ vramGb: 24
56
+ }],
57
+ regions: [{
58
+ id: "",
59
+ label: "Any",
60
+ priceMultiplier: 1
61
+ }],
62
+ maxDatasetBytes: 10 * 1024 ** 3,
63
+ maxRuntimeSec: 24 * 3600,
64
+ dataResidencyNote: "The fake keeps everything in memory.",
65
+ configured: this.configured,
66
+ defaults: {
67
+ gpuType: "L4",
68
+ region: "",
69
+ costCapUsd: this.options.costCapUsd ?? 5,
70
+ maxRuntimeSec: 4 * 3600,
71
+ failedDatasetGraceHours: this.options.failedDatasetGraceHours ?? 24
72
+ }
73
+ }];
74
+ validateCredentials = async () => this.configured ? {
75
+ ok: true,
76
+ account: "fake-workspace"
77
+ } : {
78
+ ok: false,
79
+ reason: "missing"
80
+ };
81
+ estimateJob = async (input) => ({
82
+ usdLow: input.gpuSecondsLow / 3600 * .8,
83
+ usdHigh: input.gpuSecondsHigh / 3600 * .8,
84
+ notes: []
85
+ });
86
+ uploadDataset = async (input) => {
87
+ this.calls.push(`upload:${input.jobKey}`);
88
+ const taken = await this.options.peer.take(input.ticket);
89
+ const job = this.jobs.get(input.jobKey) ?? this.blank(input.jobKey, "pending");
90
+ job.dataset = {
91
+ bytes: taken.bytes.length,
92
+ sha256: taken.sha256
93
+ };
94
+ job.datasetDeleted = false;
95
+ this.jobs.set(input.jobKey, job);
96
+ return {
97
+ bytes: taken.bytes.length,
98
+ sha256: taken.sha256
99
+ };
100
+ };
101
+ submitJob = async (input) => {
102
+ this.calls.push(`submit:${input.jobKey}`);
103
+ const job = this.jobs.get(input.jobKey) ?? this.blank(input.jobKey, "pending");
104
+ job.submits += 1;
105
+ if (job.jobSpecJson === null) job.jobSpecJson = input.jobSpecJson;
106
+ this.jobs.set(input.jobKey, job);
107
+ return this.status(job);
108
+ };
109
+ getJob = async (input) => {
110
+ const job = this.jobs.get(input.jobKey);
111
+ return job === void 0 ? this.lostStatus(input.jobKey) : this.status(job);
112
+ };
113
+ listJobEvents = async (input) => {
114
+ const job = this.jobs.get(input.jobKey);
115
+ const from = input.cursor === void 0 ? 0 : Number(input.cursor);
116
+ const lines = job === void 0 ? [] : job.logs.slice(from, from + input.max);
117
+ return {
118
+ lines,
119
+ cursor: String(from + lines.length)
120
+ };
121
+ };
122
+ cancelJob = async (input) => {
123
+ this.calls.push(`cancel:${input.jobKey}`);
124
+ const job = this.jobs.get(input.jobKey);
125
+ if (job !== void 0 && (job.state === "pending" || job.state === "starting" || job.state === "running")) {
126
+ job.state = "cancelled";
127
+ job.endedAt = this.options.now();
128
+ }
129
+ return { ok: true };
130
+ };
131
+ readResult = async (input) => {
132
+ const text = this.jobs.get(input.jobKey)?.resultText ?? null;
133
+ return text === null ? { found: false } : {
134
+ found: true,
135
+ text
136
+ };
137
+ };
138
+ offerArtifact = async (input) => {
139
+ const bundle = this.jobs.get(input.jobKey)?.bundle ?? null;
140
+ if (bundle === null) throw new Error(`no bundle for ${input.jobKey}`);
141
+ return { ticket: this.options.peer.offer(bundle) };
142
+ };
143
+ cleanupJob = async (input) => {
144
+ this.calls.push(`cleanup:${input.jobKey}`);
145
+ const job = this.jobs.get(input.jobKey);
146
+ if (job === void 0 || job.datasetDeleted) return { deleted: [] };
147
+ job.datasetDeleted = true;
148
+ return { deleted: [`cst-ds-${input.jobKey}`] };
149
+ };
150
+ listJobs = async () => [...this.jobs.values()].filter((j) => !j.datasetDeleted).map((j) => this.status(j));
151
+ require(jobKey) {
152
+ const job = this.jobs.get(jobKey);
153
+ if (job === void 0) throw new Error(`fake provider: no job ${jobKey}`);
154
+ return job;
155
+ }
156
+ blank(jobKey, state) {
157
+ return {
158
+ jobKey,
159
+ state,
160
+ submits: 0,
161
+ startedAt: state === "running" ? this.options.now() : null,
162
+ endedAt: null,
163
+ exitCode: null,
164
+ costUsd: 0,
165
+ jobSpecJson: null,
166
+ dataset: null,
167
+ datasetDeleted: false,
168
+ logs: [],
169
+ resultText: null,
170
+ bundle: null
171
+ };
172
+ }
173
+ status(job) {
174
+ return {
175
+ jobKey: job.jobKey,
176
+ providerJobId: `fake-${job.jobKey}`,
177
+ state: job.state,
178
+ ...job.startedAt !== null ? { startedAt: job.startedAt } : {},
179
+ ...job.endedAt !== null ? { endedAt: job.endedAt } : {},
180
+ ...job.exitCode !== null ? { exitCode: job.exitCode } : {},
181
+ gpuType: "L4",
182
+ billedSeconds: 0,
183
+ costUsd: job.costUsd,
184
+ costIsEstimate: true,
185
+ lastFetchedAt: this.options.now()
186
+ };
187
+ }
188
+ lostStatus(jobKey) {
189
+ return {
190
+ jobKey,
191
+ state: "lost",
192
+ gpuType: "L4",
193
+ billedSeconds: 0,
194
+ costUsd: 0,
195
+ costIsEstimate: true,
196
+ lastFetchedAt: this.options.now()
197
+ };
198
+ }
199
+ };
200
+ //#endregion
201
+ export { FakeTrainingProvider, TrainingAddon, TrainingModalAddon };