medias-fakerator 1.0.0-dra

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 (37) hide show
  1. package/assets/fonts/Chirp-Regular.ttf +0 -0
  2. package/assets/fonts/Noto-Bold.ttf +0 -0
  3. package/assets/fonts/Noto-Emoji.ttf +0 -0
  4. package/assets/fonts/Noto-Regular.ttf +0 -0
  5. package/assets/fonts/SfProDisplay.ttf +0 -0
  6. package/assets/images/android/background-call.jpg +0 -0
  7. package/assets/images/google/google-lyrics.jpg +0 -0
  8. package/assets/images/google/google-search.jpg +0 -0
  9. package/assets/images/instagram/fakestory.png +0 -0
  10. package/assets/images/instagram/instagram-verified.png +0 -0
  11. package/assets/images/iphone/background-call.jpg +0 -0
  12. package/assets/images/iphone/background.jpg +0 -0
  13. package/assets/images/iphone/battery.png +0 -0
  14. package/assets/images/iphone/copy.png +0 -0
  15. package/assets/images/iphone/delete.png +0 -0
  16. package/assets/images/iphone/forward.png +0 -0
  17. package/assets/images/iphone/pin.png +0 -0
  18. package/assets/images/iphone/plus.png +0 -0
  19. package/assets/images/iphone/reply.png +0 -0
  20. package/assets/images/iphone/report.png +0 -0
  21. package/assets/images/iphone/signal.png +0 -0
  22. package/assets/images/iphone/star.png +0 -0
  23. package/assets/images/iphone/wifi.png +0 -0
  24. package/assets/images/pattern_02.png +0 -0
  25. package/assets/images/tiktok/tiktok-verified.png +0 -0
  26. package/assets/images/tweet/like.png +0 -0
  27. package/assets/images/tweet/other.png +0 -0
  28. package/assets/images/tweet/reply.png +0 -0
  29. package/assets/images/tweet/retweet.png +0 -0
  30. package/assets/images/tweet/share.png +0 -0
  31. package/assets/images/tweet/twitter-verified.png +0 -0
  32. package/assets/images/youtube/youtube-verified.png +0 -0
  33. package/index.js +39 -0
  34. package/lib/generators.js +3220 -0
  35. package/lib/quote-generator.js +1621 -0
  36. package/lib/utils.js +166 -0
  37. package/package.json +24 -0
package/lib/utils.js ADDED
@@ -0,0 +1,166 @@
1
+ const EmojiDbLib = require('emoji-db');
2
+
3
+ let emojiDb;
4
+ try {
5
+ emojiDb = new EmojiDbLib({ useDefaultDb: true });
6
+ if (!emojiDb || typeof emojiDb.searchFromText !== 'function') throw new Error('Gagal menginisialisasi database emoji');
7
+ } catch (error) {
8
+ console.error('Error saat inisialisasi database emoji:', error);
9
+ throw error;
10
+ }
11
+
12
+ function parseTextToSegments(text, ctx, fontSize) {
13
+ try {
14
+ if (typeof text !== 'string') text = String(text);
15
+ if (!ctx || typeof ctx.measureText !== 'function') throw new TypeError('Invalid canvas context');
16
+ const finalSegments = [];
17
+ const rawLines = text.split('\n');
18
+ rawLines.forEach((line, index) => {
19
+ if (line === '') {
20
+ } else {
21
+ const segmentsInLine = [];
22
+ const emojiMatches = emojiDb.searchFromText({ input: line, fixCodePoints: true });
23
+ let lastIndex = 0;
24
+ const processChunk = (chunk) => {
25
+ if (!chunk) return;
26
+ const tokenizerRegex = /(\*_.*?_\*|_\*.*?\*_)|(\*.*?\*)|(_.*?_)|(~.*?~)|(```.*?```)|(\s+)|([^\s*~_`]+)/g;
27
+ let match;
28
+ while ((match = tokenizerRegex.exec(chunk)) !== null) {
29
+ const [fullMatch, boldItalic, bold, italic, strikethrough, monospace, whitespace, textContent] = match;
30
+ if (boldItalic) {
31
+ const content = boldItalic.slice(2, -2);
32
+ ctx.font = `italic bold ${fontSize}px Arial`;
33
+ segmentsInLine.push({ type: 'bolditalic', content, width: ctx.measureText(content).width });
34
+ } else if (bold) {
35
+ const content = bold.slice(1, -1);
36
+ ctx.font = `bold ${fontSize}px Arial`;
37
+ segmentsInLine.push({ type: 'bold', content, width: ctx.measureText(content).width });
38
+ } else if (italic) {
39
+ const content = italic.slice(1, -1);
40
+ ctx.font = `italic ${fontSize}px Arial`;
41
+ segmentsInLine.push({ type: 'italic', content, width: ctx.measureText(content).width });
42
+ } else if (strikethrough) {
43
+ const content = strikethrough.slice(1, -1);
44
+ ctx.font = `${fontSize}px Arial`;
45
+ segmentsInLine.push({ type: 'strikethrough', content, width: ctx.measureText(content).width });
46
+ } else if (monospace) {
47
+ const content = monospace.slice(3, -3);
48
+ ctx.font = `${fontSize}px 'Courier New', monospace`;
49
+ segmentsInLine.push({ type: 'monospace', content, width: ctx.measureText(content).width });
50
+ } else if (whitespace) {
51
+ ctx.font = `${fontSize}px Arial`;
52
+ segmentsInLine.push({ type: 'whitespace', content: whitespace, width: ctx.measureText(whitespace).width });
53
+ } else if (textContent) {
54
+ ctx.font = `${fontSize}px Arial`;
55
+ segmentsInLine.push({ type: 'text', content: textContent, width: ctx.measureText(textContent).width });
56
+ }
57
+ }
58
+ };
59
+ emojiMatches.forEach(emojiInfo => {
60
+ const plainText = line.substring(lastIndex, emojiInfo.offset);
61
+ processChunk(plainText);
62
+ segmentsInLine.push({
63
+ type: 'emoji',
64
+ content: emojiInfo.found,
65
+ width: fontSize * 1.2,
66
+ });
67
+ lastIndex = emojiInfo.offset + emojiInfo.length;
68
+ });
69
+ if (lastIndex < line.length) {
70
+ processChunk(line.substring(lastIndex));
71
+ }
72
+ finalSegments.push(...segmentsInLine);
73
+ }
74
+ if (index < rawLines.length - 1) {
75
+ finalSegments.push({ type: 'newline', content: '\n', width: 0 });
76
+ }
77
+ });
78
+ ctx.font = `${fontSize}px Arial`;
79
+ return finalSegments;
80
+ } catch (error) {
81
+ console.error('Error in parseTextToSegments:', error);
82
+ return [];
83
+ }
84
+ }
85
+
86
+ function rebuildLinesFromSegments(segments, maxWidth, ctx, fontSize) {
87
+ try {
88
+ const lines = [];
89
+ let currentLine = [];
90
+ let currentLineWidth = 0;
91
+ const getFontString = (type, size) => {
92
+ switch (type) {
93
+ case 'bold': return `bold ${size}px Arial`;
94
+ case 'italic': return `italic ${size}px Arial`;
95
+ case 'bolditalic': return `italic bold ${size}px Arial`;
96
+ case 'monospace': return `${size}px 'Courier New', monospace`;
97
+ default: return `${size}px Arial`;
98
+ }
99
+ };
100
+ segments.forEach(segment => {
101
+ if (segment.type === 'newline') {
102
+ lines.push(currentLine);
103
+ currentLine = [];
104
+ currentLineWidth = 0;
105
+ return;
106
+ }
107
+ if (segment.width > maxWidth && segment.type !== 'emoji') {
108
+ if (currentLine.length > 0) {
109
+ lines.push(currentLine);
110
+ currentLine = [];
111
+ currentLineWidth = 0;
112
+ }
113
+ let tempStr = '';
114
+ const originalFont = getFontString(segment.type, fontSize);
115
+ ctx.font = originalFont;
116
+ for (const char of segment.content) {
117
+ const measuredWidth = ctx.measureText(tempStr + char).width;
118
+ if (measuredWidth > maxWidth) {
119
+ lines.push([{ type: segment.type, content: tempStr, width: ctx.measureText(tempStr).width }]);
120
+ tempStr = char;
121
+ } else {
122
+ tempStr += char;
123
+ }
124
+ }
125
+ if (tempStr) {
126
+ currentLine = [{ type: segment.type, content: tempStr, width: ctx.measureText(tempStr).width }];
127
+ currentLineWidth = currentLine[0].width;
128
+ }
129
+ return;
130
+ }
131
+ if (currentLineWidth + segment.width > maxWidth && currentLine.length > 0) {
132
+ lines.push(currentLine);
133
+ currentLine = [segment];
134
+ currentLineWidth = segment.width;
135
+ } else {
136
+ if (segment.type === 'whitespace' && currentLine.length === 0) return;
137
+ currentLine.push(segment);
138
+ currentLineWidth += segment.width;
139
+ }
140
+ });
141
+ if (currentLine.length > 0) {
142
+ lines.push(currentLine);
143
+ }
144
+ return lines;
145
+ } catch (error) {
146
+ console.error('Error in rebuildLinesFromSegments:', error);
147
+ return [[]];
148
+ }
149
+ }
150
+
151
+ function getContrastColor(hexColor) {
152
+ if (!hexColor || typeof hexColor !== 'string') return '#FFFFFF';
153
+ const hex = hexColor.replace('#', '');
154
+ if (hex.length !== 6) return '#FFFFFF';
155
+ const r = parseInt(hex.substring(0, 2), 16);
156
+ const g = parseInt(hex.substring(2, 4), 16);
157
+ const b = parseInt(hex.substring(4, 6), 16);
158
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b);
159
+ return luminance > 140 ? '#000000' : '#FFFFFF';
160
+ };
161
+
162
+ module.exports = {
163
+ parseTextToSegments,
164
+ rebuildLinesFromSegments,
165
+ getContrastColor
166
+ };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "medias-fakerator",
3
+ "version": "1.0.0-dra",
4
+ "description": "AIO Faker generator by Iruka Devs",
5
+ "main": "index.js",
6
+ "author": "Iruka Devs",
7
+ "scripts": {
8
+ "test": "jest"
9
+ },
10
+ "dependencies": {
11
+ "@ffmpeg-installer/ffmpeg": "1.1.0",
12
+ "canvas": "^3.2.0",
13
+ "emoji-cache": "^2.0.1",
14
+ "emoji-db": "github:Terror-Machine/emoji-db#master",
15
+ "fluent-ffmpeg": "^2.1.3",
16
+ "fs-extra": "11.3.2",
17
+ "lru-cache": "^11.1.0",
18
+ "runes": "^0.4.3",
19
+ "sharp": "^0.34.3"
20
+ },
21
+ "devDependencies": {
22
+ "jest": "^30.2.0"
23
+ }
24
+ }