@ejfdelgado/ejflab-common 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/LICENSE +201 -0
- package/README.md +2 -0
- package/package.json +29 -0
- package/src/CollisionsEngine.js +252 -0
- package/src/CsvFormatter.js +54 -0
- package/src/CsvFormatter.test.js +119 -0
- package/src/CsvFormatterFilters.js +79 -0
- package/src/CsvParser.js +51 -0
- package/src/CsvParser.test.js +41 -0
- package/src/CsvWithFilters.js +114 -0
- package/src/FaceEncoder.js +64 -0
- package/src/FlowChartDiagram.js +503 -0
- package/src/IdGen.js +211 -0
- package/src/ModuloDatoSeguro.js +142 -0
- package/src/ModuloDatoSeguro.test.js +29 -0
- package/src/ModuloDatoSeguro.test.mjs +45 -0
- package/src/ModuloDatoSeguroBack.mjs +55 -0
- package/src/ModuloDatoSeguroFront.js +73 -0
- package/src/ModuloSonido.js +83 -0
- package/src/ModuloVideos.js +51 -0
- package/src/MyColor.js +136 -0
- package/src/MyColor.test.js +37 -0
- package/src/MyConstants.js +147 -0
- package/src/MyCookies.js +34 -0
- package/src/MyDates.js +412 -0
- package/src/MyDates.test.js +26 -0
- package/src/MyDatesBack.mjs +21 -0
- package/src/MyDatesFront.js +41 -0
- package/src/MyJsPdf.js +52 -0
- package/src/MyRoutes.js +29 -0
- package/src/MyTemplate.js +272 -0
- package/src/MyTemplate.test.js +90 -0
- package/src/MyTensorflow.js +248 -0
- package/src/MyTensorflow.test.js +19 -0
- package/src/MyTensorflowBack.mjs +33 -0
- package/src/MyThrottle.js +80 -0
- package/src/MyTuples.js +445 -0
- package/src/MyTuples.test.js +330 -0
- package/src/MyUtilities.js +137 -0
- package/src/SimpleObj.js +153 -0
- package/src/SimpleObj.test.js +58 -0
- package/src/TriangulacionGeometric.js +335 -0
- package/src/changePath.js +38 -0
- package/src/data/case0.csv +3 -0
- package/src/data/case0.json +24 -0
- package/src/data/case1.csv +2 -0
- package/src/data/case1.json +24 -0
- package/src/data/case2.csv +3 -0
- package/src/data/case2.json +24 -0
- package/src/data/case3.csv +3 -0
- package/src/data/case3.json +24 -0
- package/src/data/format0.json +0 -0
- package/src/data/format0.txt +1 -0
- package/src/data/tensordata.csv +10 -0
- package/src/data/tensordata.json +37 -0
- package/src/data/tensordata.test.csv +10 -0
- package/src/data/tensormodel.json +113 -0
- package/src/fft.js +224 -0
- package/src/flowchart/FlowChartExec.js +763 -0
- package/src/flowchart/steps/CommandBasic.js +32 -0
- package/src/flowchart/steps/CommandInc.js +19 -0
- package/src/flowchart/steps/CommandMilvus.js +47 -0
- package/src/flowchart/steps/CommandMinio.js +28 -0
- package/src/flowchart/steps/CommandMongo.js +59 -0
- package/src/flowchart/steps/CommandPrint.js +12 -0
- package/src/flowchart/steps/CommandSet.js +14 -0
- package/src/flowchart/steps/CommandTimeline.js +21 -0
- package/src/flowchart/steps/CommandTimelineNext.js +28 -0
- package/src/flowchart/steps/StepBasic.js +184 -0
- package/src/flowchart/steps/StepCheckProcessor.js +26 -0
- package/src/flowchart/steps/StepCheckSrc.js +42 -0
- package/src/flowchart/steps/StepIsTrue.js +12 -0
- package/src/flowchart/steps/StepOneTime.js +21 -0
- package/src/flowchart/steps/StepProcess.js +163 -0
- package/src/flowchart/steps/StepReadSrc.js +66 -0
- package/src/flowchart/steps/StepSleep.js +22 -0
- package/src/flowchart/steps/StepTimeLineEnds.js +21 -0
- package/src/flowchart/steps/StepTimeLineHasMore.js +16 -0
- package/src/gif/index.d.ts +20 -0
- package/src/gif/index.mjs +85 -0
- package/src/gif/utils/checkTypes.d.ts +2 -0
- package/src/gif/utils/checkTypes.mjs +11 -0
- package/src/js-colormaps.js +19484 -0
- package/src/sortify.js +75 -0
- package/src/sqlmodelparser/SqlModelParser.js +22 -0
- package/src/test/csv/test_1000_20230429204538700.csv +1001 -0
- package/src/test/csv/test_5_20230429204525930.csv +6 -0
- package/src/test/svg/test.html +5 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
const { StepBasic } = require("./StepBasic");
|
|
2
|
+
const { SimpleObj } = require("../../SimpleObj");
|
|
3
|
+
const { IdGen } = require("../../IdGen");
|
|
4
|
+
const { encode, decode } = require("@msgpack/msgpack");
|
|
5
|
+
|
|
6
|
+
class StepProcess extends StepBasic {
|
|
7
|
+
constructor(context, id, commandName, argsTxt) {
|
|
8
|
+
super(context, id, commandName, argsTxt);
|
|
9
|
+
super.alwaysEvaluateCanContinue = true;
|
|
10
|
+
}
|
|
11
|
+
async execFirst() {
|
|
12
|
+
|
|
13
|
+
const partsName = /^([^\.\d]+)(\d*)\.?([^'.]*)$/.exec(this.args[0]);
|
|
14
|
+
if (!partsName) {
|
|
15
|
+
console.log(`The processor name ${this.args[0]} does not match ^([^\.\d]+)(\d*)\.?([^'.]*)$`);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
let method = "main";
|
|
19
|
+
const processorMethod = partsName[0];
|
|
20
|
+
const processorName = partsName[1];
|
|
21
|
+
const instanceNumber = partsName[2];
|
|
22
|
+
let processorInstance = partsName[1];
|
|
23
|
+
if (typeof partsName[2] == "string") {
|
|
24
|
+
processorInstance += instanceNumber;
|
|
25
|
+
}
|
|
26
|
+
if (typeof partsName[3] == "string" && partsName[3].trim().length > 0) {
|
|
27
|
+
method = partsName[3];
|
|
28
|
+
}
|
|
29
|
+
this.configuration = SimpleObj.getValue(this.context.data, `state.processors.${processorName}`, null);
|
|
30
|
+
if (!this.configuration) {
|
|
31
|
+
this.configuration = {};
|
|
32
|
+
}
|
|
33
|
+
let channel = this.configuration.channel;
|
|
34
|
+
if (!channel) {
|
|
35
|
+
// Gets channel from parent
|
|
36
|
+
channel = SimpleObj.getValue(this.context.data, `state.processors.channel`, "websocket");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let processorSocketId = null;
|
|
40
|
+
let postUrl = null;
|
|
41
|
+
const processorsModel = this.context.getProcessorsModel();
|
|
42
|
+
if (channel == "websocket") {
|
|
43
|
+
processorSocketId = SimpleObj.getValue(processorsModel.data, `state.processors.${processorName}.socket`, null);
|
|
44
|
+
if (!processorSocketId) {
|
|
45
|
+
console.log(`No client processor websocket for ${processorInstance}`);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
} else if (channel == "post") {
|
|
49
|
+
postUrl = SimpleObj.getValue(processorsModel.data, `state.processors.${processorName}.postUrl`, null);
|
|
50
|
+
if (!postUrl) {
|
|
51
|
+
console.log(`No client postUrl for ${processorInstance}`);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// It reads the connection configuration
|
|
57
|
+
const model = this.context.getSuperContextModel();
|
|
58
|
+
|
|
59
|
+
const metadata = SimpleObj.getValue(model, `flowchart.flux.${processorInstance}.${method}.metadata`, {});
|
|
60
|
+
if ('timeout' in metadata) {
|
|
61
|
+
const timeout = parseFloat(metadata['timeout']);
|
|
62
|
+
if (!isNaN(timeout)) {
|
|
63
|
+
this.setTimeout(timeout);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if ('retries' in metadata) {
|
|
67
|
+
const retries = parseInt(metadata['retries']);
|
|
68
|
+
if (!isNaN(retries)) {
|
|
69
|
+
this.setMaxTries(retries);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const inputConnectionsConf = SimpleObj.getValue(model, `flowchart.flux.${processorInstance}.${method}.in`, null);
|
|
74
|
+
|
|
75
|
+
if (!inputConnectionsConf) {
|
|
76
|
+
console.log(`WARN: No input connection flux configuration for ${processorInstance}.${method}`);
|
|
77
|
+
//return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const inputs = [];
|
|
81
|
+
const outputs = [];
|
|
82
|
+
for (let i = 1; i < this.args.length; i++) {
|
|
83
|
+
const sourcePair = this.args[i];
|
|
84
|
+
const partsSource = /^(in|out):(b\.([^.]+)\.([^.]+)|d\.(.+))$/i.exec(sourcePair);
|
|
85
|
+
if (partsSource == null) {
|
|
86
|
+
console.log(`${sourcePair} doesn't match ^(in|out)\.(b\.([^.]+)\.([^.]+)|d\.(.+))$`);
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (partsSource[1] == "in") {
|
|
90
|
+
// It's an input
|
|
91
|
+
const buffer = this.readInputFrom(!partsSource[5], partsSource[3], partsSource[4], partsSource[5]);
|
|
92
|
+
if (buffer === undefined) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
inputs.push(buffer);
|
|
96
|
+
} else {
|
|
97
|
+
// Its an output
|
|
98
|
+
outputs.push(partsSource[2]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const namedInputs = {};
|
|
103
|
+
if (!!inputConnectionsConf) {
|
|
104
|
+
for (let i = 0; i < inputConnectionsConf.length; i++) {
|
|
105
|
+
const { key, val } = inputConnectionsConf[i];
|
|
106
|
+
const buffer = this.resolveArgument(val);
|
|
107
|
+
if (buffer === undefined) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
namedInputs[key] = buffer;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const room = this.context.getRoom();
|
|
115
|
+
//console.log(`StepProcess processorName:${processorName} processorInstance:${processorInstance} processorMethod:${processorMethod} in room ${room}`);
|
|
116
|
+
this.messageUID = IdGen.num2ord(new Date().getTime());
|
|
117
|
+
this.pendingCall = `${room}-${this.id}-${this.messageUID}`;
|
|
118
|
+
this.context.registerPendingCall(this.pendingCall, this);
|
|
119
|
+
const payload = {
|
|
120
|
+
inputs,//Inputs
|
|
121
|
+
namedInputs,
|
|
122
|
+
outputs,//Outpus
|
|
123
|
+
method,
|
|
124
|
+
processorName,
|
|
125
|
+
processorInstance,
|
|
126
|
+
processorMethod,
|
|
127
|
+
id: this.pendingCall,
|
|
128
|
+
data: this.configuration[instanceNumber],
|
|
129
|
+
room
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (channel == "websocket") {
|
|
133
|
+
if (this.context.io) {
|
|
134
|
+
this.context.io.to(processorSocketId).emit("process", payload);
|
|
135
|
+
}
|
|
136
|
+
} else if (channel == "queue") {
|
|
137
|
+
// TODO use google library to sends via pub/sub
|
|
138
|
+
const url = this.configuration.topicUrl;
|
|
139
|
+
} else if (channel == "post") {
|
|
140
|
+
const axios = this.context.getSuperContext().getAxios();
|
|
141
|
+
const options = {
|
|
142
|
+
headers: { "Content-Type": "application/octet-stream" }
|
|
143
|
+
};
|
|
144
|
+
const encoded = encode(payload);
|
|
145
|
+
const buffer = Buffer.from(encoded);
|
|
146
|
+
const postResponse = await axios.post(`${postUrl}/process`, buffer, options);
|
|
147
|
+
} else {
|
|
148
|
+
console.log("No channel configuration found!");
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async canContinue() {
|
|
153
|
+
if (!this.pendingCall) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const isPending = this.context.existsPendingCall(this.pendingCall);
|
|
157
|
+
return !isPending;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
module.exports = {
|
|
162
|
+
StepProcess
|
|
163
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const { StepBasic } = require("./StepBasic");
|
|
2
|
+
const { SimpleObj } = require("../../SimpleObj");
|
|
3
|
+
const { IdGen } = require("../../IdGen");
|
|
4
|
+
|
|
5
|
+
class StepReadSrc extends StepBasic {
|
|
6
|
+
pendingCall = null;
|
|
7
|
+
socketId = null;
|
|
8
|
+
sourceUID = null;
|
|
9
|
+
dataPath = null;
|
|
10
|
+
configuration = null;
|
|
11
|
+
constructor(context, id, commandName, argsTxt) {
|
|
12
|
+
super(context, id, commandName, argsTxt);
|
|
13
|
+
super.alwaysEvaluateCanContinue = false;
|
|
14
|
+
}
|
|
15
|
+
async execFirst() {
|
|
16
|
+
const sourcePair = this.args[0];
|
|
17
|
+
const parts = sourcePair.split(".");
|
|
18
|
+
this.sourceUID = parts[0];
|
|
19
|
+
if (parts.length >= 2) {
|
|
20
|
+
this.dataPath = parts[1];
|
|
21
|
+
}
|
|
22
|
+
const timelineId = this.args[1];
|
|
23
|
+
const timeline = this.context.getTimeLine(timelineId);
|
|
24
|
+
if (!timeline || typeof timeline.t != "number" || timeline.done) {
|
|
25
|
+
console.log(`Timeline ${timelineId} can't be used ${JSON.stringify(timeline)}`);
|
|
26
|
+
}
|
|
27
|
+
if (this.context.io) {
|
|
28
|
+
// Leo la ruta del sourceUID
|
|
29
|
+
this.configuration = SimpleObj.getValue(this.context.data, `state.sources.${this.sourceUID}`, null);
|
|
30
|
+
let localConfiguration = {};
|
|
31
|
+
if (this.dataPath) {
|
|
32
|
+
if (!(this.dataPath in this.configuration.data)) {
|
|
33
|
+
console.log(`The source ${this.sourceUID} has no ${this.dataPath}`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
localConfiguration[this.dataPath] = this.configuration.data[this.dataPath];
|
|
37
|
+
} else {
|
|
38
|
+
localConfiguration = this.configuration.data;
|
|
39
|
+
}
|
|
40
|
+
this.socketId = this.configuration.socket;
|
|
41
|
+
if (this.socketId) {
|
|
42
|
+
this.messageUID = IdGen.num2ord(new Date().getTime());
|
|
43
|
+
this.pendingCall = `${this.id}-${this.messageUID}`;
|
|
44
|
+
this.context.registerPendingCall(this.pendingCall, this);
|
|
45
|
+
this.context.io.to(this.socketId).emit("readSrc", {
|
|
46
|
+
configuration: localConfiguration,
|
|
47
|
+
timeline,
|
|
48
|
+
sourcePair,
|
|
49
|
+
id: this.pendingCall,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async canContinue() {
|
|
56
|
+
if (!this.pendingCall) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
const isPending = this.context.existsPendingCall(this.pendingCall);
|
|
60
|
+
return !isPending;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
StepReadSrc
|
|
66
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { StepBasic } = require("./StepBasic");
|
|
2
|
+
|
|
3
|
+
class StepSleep extends StepBasic {
|
|
4
|
+
startTime = null;
|
|
5
|
+
constructor(context, id, commandName, argsTxt) {
|
|
6
|
+
super(context, id, commandName, argsTxt);
|
|
7
|
+
super.alwaysEvaluateCanContinue = false;
|
|
8
|
+
}
|
|
9
|
+
async execFirst() {
|
|
10
|
+
this.startTime = new Date().getTime();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async canContinue() {
|
|
14
|
+
const minTime = this.args[0];
|
|
15
|
+
const diff = new Date().getTime() - this.startTime;
|
|
16
|
+
return diff >= minTime;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
StepSleep
|
|
22
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const { StepBasic } = require("./StepBasic");
|
|
2
|
+
const { SimpleObj } = require("../../SimpleObj");
|
|
3
|
+
|
|
4
|
+
class StepTimeLineEnds extends StepBasic {
|
|
5
|
+
async canContinue() {
|
|
6
|
+
const timeLineId = this.args[0];
|
|
7
|
+
const timeline = this.context.getTimeLine(timeLineId);
|
|
8
|
+
if (!timeline) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const finished = !(timeline.t + timeline.period < timeline.end);
|
|
12
|
+
if (finished) {
|
|
13
|
+
SimpleObj.recreate(this.context.data, "scope.progress", 100);
|
|
14
|
+
}
|
|
15
|
+
return finished;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
StepTimeLineEnds
|
|
21
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { StepBasic } = require("./StepBasic");
|
|
2
|
+
|
|
3
|
+
class StepTimeLineHasMore extends StepBasic {
|
|
4
|
+
async canContinue() {
|
|
5
|
+
const timeLineId = this.args[0];
|
|
6
|
+
const timeline = this.context.getTimeLine(timeLineId);
|
|
7
|
+
if (!timeline) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
return timeline.t + timeline.period < timeline.end;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
StepTimeLineHasMore
|
|
16
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Frame as FrameI } from 'imagescript';
|
|
3
|
+
interface Frame {
|
|
4
|
+
src: string | Uint8Array;
|
|
5
|
+
duration?: number;
|
|
6
|
+
background?: string | Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
export declare class Gif {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
frames: FrameI[];
|
|
12
|
+
loops: number;
|
|
13
|
+
quality: number;
|
|
14
|
+
constructor(width: number, height: number, quality?: number);
|
|
15
|
+
setLoops(loops: number): void;
|
|
16
|
+
setFrames(frames: Frame | Frame[]): Promise<void>;
|
|
17
|
+
addFrame(frame: Frame): Promise<void>;
|
|
18
|
+
encode(arrayBuffer?: boolean): Promise<Uint8Array | Buffer>;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import phin from 'phin';
|
|
2
|
+
import { GIF, Frame as FrameI, decode, Image } from 'imagescript';
|
|
3
|
+
import { checkTypes, checkNumber } from './utils/checkTypes.mjs';
|
|
4
|
+
export class Gif {
|
|
5
|
+
width;
|
|
6
|
+
height;
|
|
7
|
+
frames;
|
|
8
|
+
loops;
|
|
9
|
+
quality;
|
|
10
|
+
constructor(width, height, quality) {
|
|
11
|
+
if (!width)
|
|
12
|
+
throw new Error('The width of the Gif is required');
|
|
13
|
+
if (!height)
|
|
14
|
+
throw new Error('The height of the Gif is required');
|
|
15
|
+
checkTypes(width, 'number', 'width');
|
|
16
|
+
checkTypes(height, 'number', 'height');
|
|
17
|
+
checkNumber(width, 'width');
|
|
18
|
+
checkNumber(height, 'height');
|
|
19
|
+
this.height = height;
|
|
20
|
+
this.width = width;
|
|
21
|
+
this.loops = -1;
|
|
22
|
+
this.quality = quality || 1;
|
|
23
|
+
this.frames = [];
|
|
24
|
+
}
|
|
25
|
+
setLoops(loops) {
|
|
26
|
+
if (!loops)
|
|
27
|
+
throw new Error('The loops are required');
|
|
28
|
+
if (isNaN(loops))
|
|
29
|
+
throw new Error('The loops needs to be a number');
|
|
30
|
+
if (loops <= -1)
|
|
31
|
+
throw new Error('The loops cant be less than -1');
|
|
32
|
+
this.loops = loops;
|
|
33
|
+
}
|
|
34
|
+
async setFrames(frames) {
|
|
35
|
+
if (!frames)
|
|
36
|
+
throw new Error('The frames are required');
|
|
37
|
+
if (!Array.isArray(frames))
|
|
38
|
+
frames = [frames];
|
|
39
|
+
if (!frames.length)
|
|
40
|
+
throw new Error('The frames are required');
|
|
41
|
+
if (frames.length <= 1)
|
|
42
|
+
throw new Error('You need to add more than one frame');
|
|
43
|
+
for (const frame of frames) {
|
|
44
|
+
await this.addFrame(frame);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async addFrame(frame) {
|
|
48
|
+
if (!frame)
|
|
49
|
+
throw new Error('The frame is required');
|
|
50
|
+
if (!frame.src)
|
|
51
|
+
throw new Error('The src is required');
|
|
52
|
+
const img = new Image(this.width, this.height);
|
|
53
|
+
if (typeof frame.background === 'string') {
|
|
54
|
+
const imageres = await phin(frame.background);
|
|
55
|
+
const buf = Buffer.from(imageres.body);
|
|
56
|
+
frame.background = new Uint8Array(buf);
|
|
57
|
+
}
|
|
58
|
+
if (typeof frame.src === 'string') {
|
|
59
|
+
const imageres = await phin(frame.src);
|
|
60
|
+
const buf = Buffer.from(imageres.body);
|
|
61
|
+
frame.src = new Uint8Array(buf);
|
|
62
|
+
}
|
|
63
|
+
if (frame.duration && isNaN(frame.duration))
|
|
64
|
+
throw new Error('The duration needs to be a number');
|
|
65
|
+
if (frame.duration && frame.duration <= 0)
|
|
66
|
+
throw new Error('The duration cant be less than 0');
|
|
67
|
+
frame.duration = frame.duration || 1000;
|
|
68
|
+
if (frame.background) {
|
|
69
|
+
const _background = await decode(frame.background, true);
|
|
70
|
+
if (_background instanceof GIF)
|
|
71
|
+
throw new Error('Gifs are not supported at this moment, please get the frames of the gif and put them as frames');
|
|
72
|
+
img.composite(_background);
|
|
73
|
+
}
|
|
74
|
+
const _img = await decode(frame.src, true);
|
|
75
|
+
if (_img instanceof GIF)
|
|
76
|
+
throw new Error('Gifs are not supported at this moment, please get the frames of the gif and put them as frames');
|
|
77
|
+
img.composite(_img);
|
|
78
|
+
this.frames.push(FrameI.from(img, frame.duration, 0, 0, FrameI.DISPOSAL_BACKGROUND));
|
|
79
|
+
}
|
|
80
|
+
async encode(arrayBuffer = false) {
|
|
81
|
+
const gif = new GIF(this.frames, this.loops);
|
|
82
|
+
const arrayBuf = await gif.encode(this.quality);
|
|
83
|
+
return arrayBuffer ? arrayBuf : Buffer.from(arrayBuf);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function checkTypes(v, type, name) {
|
|
2
|
+
if (typeof v !== type) {
|
|
3
|
+
throw new Error(`${name} needs to be a ${type}, recieved: ${typeof v}`);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export function checkNumber(v, name) {
|
|
7
|
+
if (isNaN(v))
|
|
8
|
+
throw new Error(`${name} needs to be a number, recieved: ${typeof v}`);
|
|
9
|
+
if (v <= 0)
|
|
10
|
+
throw new Error(`${v} needs to be a number greater than 0`);
|
|
11
|
+
}
|