aegis-framework 0.2.1 → 0.3.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.
@@ -989,6 +989,649 @@
989
989
  */
990
990
  uid: function (prefix = 'aegis') {
991
991
  return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
992
+ },
993
+
994
+ // ==================== Form Utilities ====================
995
+
996
+ form: {
997
+ /**
998
+ * Serialize form to object
999
+ */
1000
+ serialize: function (selector) {
1001
+ const form = Aegis.get(selector);
1002
+ if (!form) return {};
1003
+ const data = {};
1004
+ const formData = new FormData(form);
1005
+ formData.forEach((value, key) => {
1006
+ if (data[key]) {
1007
+ if (!Array.isArray(data[key])) data[key] = [data[key]];
1008
+ data[key].push(value);
1009
+ } else {
1010
+ data[key] = value;
1011
+ }
1012
+ });
1013
+ return data;
1014
+ },
1015
+
1016
+ /**
1017
+ * Reset form
1018
+ */
1019
+ reset: function (selector) {
1020
+ const form = Aegis.get(selector);
1021
+ if (form) form.reset();
1022
+ return form;
1023
+ },
1024
+
1025
+ /**
1026
+ * Fill form with data
1027
+ */
1028
+ fill: function (selector, data) {
1029
+ const form = Aegis.get(selector);
1030
+ if (!form) return;
1031
+ Object.entries(data).forEach(([name, value]) => {
1032
+ const field = form.querySelector(`[name="${name}"]`);
1033
+ if (field) {
1034
+ if (field.type === 'checkbox') {
1035
+ field.checked = !!value;
1036
+ } else if (field.type === 'radio') {
1037
+ const radio = form.querySelector(`[name="${name}"][value="${value}"]`);
1038
+ if (radio) radio.checked = true;
1039
+ } else {
1040
+ field.value = value;
1041
+ }
1042
+ }
1043
+ });
1044
+ return form;
1045
+ },
1046
+
1047
+ /**
1048
+ * Simple validation
1049
+ */
1050
+ validate: function (selector, rules = {}) {
1051
+ const form = Aegis.get(selector);
1052
+ if (!form) return { valid: false, errors: ['Form not found'] };
1053
+ const errors = [];
1054
+ Object.entries(rules).forEach(([name, rule]) => {
1055
+ const field = form.querySelector(`[name="${name}"]`);
1056
+ const value = field?.value || '';
1057
+ if (rule.required && !value.trim()) {
1058
+ errors.push(`${name} is required`);
1059
+ }
1060
+ if (rule.minLength && value.length < rule.minLength) {
1061
+ errors.push(`${name} must be at least ${rule.minLength} characters`);
1062
+ }
1063
+ if (rule.pattern && !rule.pattern.test(value)) {
1064
+ errors.push(`${name} is invalid`);
1065
+ }
1066
+ if (rule.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
1067
+ errors.push(`${name} must be a valid email`);
1068
+ }
1069
+ });
1070
+ return { valid: errors.length === 0, errors };
1071
+ }
1072
+ },
1073
+
1074
+ // ==================== HTTP/Fetch Utilities ====================
1075
+
1076
+ http: {
1077
+ /**
1078
+ * GET request
1079
+ */
1080
+ get: async function (url, options = {}) {
1081
+ const response = await fetch(url, { method: 'GET', ...options });
1082
+ return options.raw ? response : response.json();
1083
+ },
1084
+
1085
+ /**
1086
+ * POST request
1087
+ */
1088
+ post: async function (url, data, options = {}) {
1089
+ const response = await fetch(url, {
1090
+ method: 'POST',
1091
+ headers: { 'Content-Type': 'application/json', ...options.headers },
1092
+ body: JSON.stringify(data),
1093
+ ...options
1094
+ });
1095
+ return options.raw ? response : response.json();
1096
+ },
1097
+
1098
+ /**
1099
+ * PUT request
1100
+ */
1101
+ put: async function (url, data, options = {}) {
1102
+ const response = await fetch(url, {
1103
+ method: 'PUT',
1104
+ headers: { 'Content-Type': 'application/json', ...options.headers },
1105
+ body: JSON.stringify(data),
1106
+ ...options
1107
+ });
1108
+ return options.raw ? response : response.json();
1109
+ },
1110
+
1111
+ /**
1112
+ * DELETE request
1113
+ */
1114
+ delete: async function (url, options = {}) {
1115
+ const response = await fetch(url, { method: 'DELETE', ...options });
1116
+ return options.raw ? response : response.json();
1117
+ }
1118
+ },
1119
+
1120
+ // ==================== Cookie Utilities ====================
1121
+
1122
+ cookie: {
1123
+ get: function (name) {
1124
+ const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
1125
+ return match ? decodeURIComponent(match[2]) : null;
1126
+ },
1127
+ set: function (name, value, days = 365, path = '/') {
1128
+ const expires = new Date(Date.now() + days * 864e5).toUTCString();
1129
+ document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=${path}`;
1130
+ },
1131
+ remove: function (name, path = '/') {
1132
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}`;
1133
+ }
1134
+ },
1135
+
1136
+ // ==================== URL Utilities ====================
1137
+
1138
+ url: {
1139
+ /**
1140
+ * Get query parameters as object
1141
+ */
1142
+ params: function (url = window.location.href) {
1143
+ const params = {};
1144
+ new URL(url).searchParams.forEach((v, k) => params[k] = v);
1145
+ return params;
1146
+ },
1147
+
1148
+ /**
1149
+ * Get single parameter
1150
+ */
1151
+ param: function (name, url = window.location.href) {
1152
+ return new URL(url).searchParams.get(name);
1153
+ },
1154
+
1155
+ /**
1156
+ * Build URL with params
1157
+ */
1158
+ build: function (base, params = {}) {
1159
+ const url = new URL(base, window.location.origin);
1160
+ Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
1161
+ return url.toString();
1162
+ },
1163
+
1164
+ /**
1165
+ * Get current path
1166
+ */
1167
+ path: function () {
1168
+ return window.location.pathname;
1169
+ },
1170
+
1171
+ /**
1172
+ * Get hash without #
1173
+ */
1174
+ hash: function () {
1175
+ return window.location.hash.slice(1);
1176
+ }
1177
+ },
1178
+
1179
+ // ==================== String Utilities ====================
1180
+
1181
+ string: {
1182
+ capitalize: function (str) {
1183
+ return str.charAt(0).toUpperCase() + str.slice(1);
1184
+ },
1185
+
1186
+ titleCase: function (str) {
1187
+ return str.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');
1188
+ },
1189
+
1190
+ camelCase: function (str) {
1191
+ return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
1192
+ },
1193
+
1194
+ kebabCase: function (str) {
1195
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[\s_]+/g, '-').toLowerCase();
1196
+ },
1197
+
1198
+ snakeCase: function (str) {
1199
+ return str.replace(/([a-z])([A-Z])/g, '$1_$2').replace(/[\s-]+/g, '_').toLowerCase();
1200
+ },
1201
+
1202
+ slugify: function (str) {
1203
+ return str.toLowerCase().trim()
1204
+ .replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, '');
1205
+ },
1206
+
1207
+ truncate: function (str, length, suffix = '...') {
1208
+ return str.length > length ? str.slice(0, length) + suffix : str;
1209
+ },
1210
+
1211
+ pad: function (str, length, char = ' ', end = false) {
1212
+ str = String(str);
1213
+ return end ? str.padEnd(length, char) : str.padStart(length, char);
1214
+ },
1215
+
1216
+ reverse: function (str) {
1217
+ return str.split('').reverse().join('');
1218
+ },
1219
+
1220
+ count: function (str, search) {
1221
+ return (str.match(new RegExp(search, 'g')) || []).length;
1222
+ },
1223
+
1224
+ between: function (str, start, end) {
1225
+ const s = str.indexOf(start) + start.length;
1226
+ const e = str.indexOf(end, s);
1227
+ return s > start.length - 1 && e > -1 ? str.slice(s, e) : '';
1228
+ },
1229
+
1230
+ template: function (str, data) {
1231
+ return str.replace(/\{\{(\w+)\}\}/g, (_, key) => data[key] ?? '');
1232
+ }
1233
+ },
1234
+
1235
+ // ==================== Array Utilities ====================
1236
+
1237
+ array: {
1238
+ unique: function (arr) {
1239
+ return [...new Set(arr)];
1240
+ },
1241
+
1242
+ shuffle: function (arr) {
1243
+ const a = [...arr];
1244
+ for (let i = a.length - 1; i > 0; i--) {
1245
+ const j = Math.floor(Math.random() * (i + 1));
1246
+ [a[i], a[j]] = [a[j], a[i]];
1247
+ }
1248
+ return a;
1249
+ },
1250
+
1251
+ chunk: function (arr, size) {
1252
+ const chunks = [];
1253
+ for (let i = 0; i < arr.length; i += size) {
1254
+ chunks.push(arr.slice(i, i + size));
1255
+ }
1256
+ return chunks;
1257
+ },
1258
+
1259
+ flatten: function (arr, depth = Infinity) {
1260
+ return arr.flat(depth);
1261
+ },
1262
+
1263
+ compact: function (arr) {
1264
+ return arr.filter(Boolean);
1265
+ },
1266
+
1267
+ first: function (arr, n = 1) {
1268
+ return n === 1 ? arr[0] : arr.slice(0, n);
1269
+ },
1270
+
1271
+ last: function (arr, n = 1) {
1272
+ return n === 1 ? arr[arr.length - 1] : arr.slice(-n);
1273
+ },
1274
+
1275
+ sample: function (arr) {
1276
+ return arr[Math.floor(Math.random() * arr.length)];
1277
+ },
1278
+
1279
+ groupBy: function (arr, key) {
1280
+ return arr.reduce((groups, item) => {
1281
+ const k = typeof key === 'function' ? key(item) : item[key];
1282
+ (groups[k] = groups[k] || []).push(item);
1283
+ return groups;
1284
+ }, {});
1285
+ },
1286
+
1287
+ sortBy: function (arr, key, desc = false) {
1288
+ return [...arr].sort((a, b) => {
1289
+ const va = typeof key === 'function' ? key(a) : a[key];
1290
+ const vb = typeof key === 'function' ? key(b) : b[key];
1291
+ return desc ? (vb > va ? 1 : -1) : (va > vb ? 1 : -1);
1292
+ });
1293
+ },
1294
+
1295
+ diff: function (arr1, arr2) {
1296
+ return arr1.filter(x => !arr2.includes(x));
1297
+ },
1298
+
1299
+ intersect: function (arr1, arr2) {
1300
+ return arr1.filter(x => arr2.includes(x));
1301
+ },
1302
+
1303
+ range: function (start, end, step = 1) {
1304
+ const arr = [];
1305
+ for (let i = start; i <= end; i += step) arr.push(i);
1306
+ return arr;
1307
+ }
1308
+ },
1309
+
1310
+ // ==================== Object Utilities ====================
1311
+
1312
+ object: {
1313
+ clone: function (obj) {
1314
+ return JSON.parse(JSON.stringify(obj));
1315
+ },
1316
+
1317
+ merge: function (...objects) {
1318
+ return objects.reduce((acc, obj) => ({ ...acc, ...obj }), {});
1319
+ },
1320
+
1321
+ isEmpty: function (obj) {
1322
+ return Object.keys(obj).length === 0;
1323
+ },
1324
+
1325
+ pick: function (obj, keys) {
1326
+ return keys.reduce((acc, key) => {
1327
+ if (key in obj) acc[key] = obj[key];
1328
+ return acc;
1329
+ }, {});
1330
+ },
1331
+
1332
+ omit: function (obj, keys) {
1333
+ return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
1334
+ },
1335
+
1336
+ keys: function (obj) {
1337
+ return Object.keys(obj);
1338
+ },
1339
+
1340
+ values: function (obj) {
1341
+ return Object.values(obj);
1342
+ },
1343
+
1344
+ entries: function (obj) {
1345
+ return Object.entries(obj);
1346
+ },
1347
+
1348
+ fromEntries: function (entries) {
1349
+ return Object.fromEntries(entries);
1350
+ },
1351
+
1352
+ get: function (obj, path, fallback = undefined) {
1353
+ return path.split('.').reduce((o, k) => (o || {})[k], obj) ?? fallback;
1354
+ },
1355
+
1356
+ set: function (obj, path, value) {
1357
+ const keys = path.split('.');
1358
+ const last = keys.pop();
1359
+ const target = keys.reduce((o, k) => (o[k] = o[k] || {}), obj);
1360
+ target[last] = value;
1361
+ return obj;
1362
+ }
1363
+ },
1364
+
1365
+ // ==================== Date Utilities ====================
1366
+
1367
+ date: {
1368
+ now: function () {
1369
+ return new Date();
1370
+ },
1371
+
1372
+ format: function (date, format = 'YYYY-MM-DD') {
1373
+ const d = new Date(date);
1374
+ const pad = n => String(n).padStart(2, '0');
1375
+ return format
1376
+ .replace('YYYY', d.getFullYear())
1377
+ .replace('MM', pad(d.getMonth() + 1))
1378
+ .replace('DD', pad(d.getDate()))
1379
+ .replace('HH', pad(d.getHours()))
1380
+ .replace('mm', pad(d.getMinutes()))
1381
+ .replace('ss', pad(d.getSeconds()));
1382
+ },
1383
+
1384
+ ago: function (date) {
1385
+ const seconds = Math.floor((Date.now() - new Date(date)) / 1000);
1386
+ const intervals = [
1387
+ [31536000, 'year'], [2592000, 'month'], [86400, 'day'],
1388
+ [3600, 'hour'], [60, 'minute'], [1, 'second']
1389
+ ];
1390
+ for (const [secs, unit] of intervals) {
1391
+ const n = Math.floor(seconds / secs);
1392
+ if (n >= 1) return `${n} ${unit}${n > 1 ? 's' : ''} ago`;
1393
+ }
1394
+ return 'just now';
1395
+ },
1396
+
1397
+ isToday: function (date) {
1398
+ const d = new Date(date);
1399
+ const today = new Date();
1400
+ return d.toDateString() === today.toDateString();
1401
+ },
1402
+
1403
+ isYesterday: function (date) {
1404
+ const d = new Date(date);
1405
+ const yesterday = new Date(Date.now() - 864e5);
1406
+ return d.toDateString() === yesterday.toDateString();
1407
+ },
1408
+
1409
+ add: function (date, amount, unit = 'day') {
1410
+ const d = new Date(date);
1411
+ const ms = { second: 1000, minute: 60000, hour: 3600000, day: 864e5 };
1412
+ return new Date(d.getTime() + amount * (ms[unit] || ms.day));
1413
+ },
1414
+
1415
+ diff: function (date1, date2, unit = 'day') {
1416
+ const ms = Math.abs(new Date(date1) - new Date(date2));
1417
+ const divisors = { second: 1000, minute: 60000, hour: 3600000, day: 864e5 };
1418
+ return Math.floor(ms / (divisors[unit] || divisors.day));
1419
+ }
1420
+ },
1421
+
1422
+ // ==================== Number Utilities ====================
1423
+
1424
+ number: {
1425
+ format: function (num, decimals = 0, locale = 'pt-BR') {
1426
+ return new Intl.NumberFormat(locale, {
1427
+ minimumFractionDigits: decimals,
1428
+ maximumFractionDigits: decimals
1429
+ }).format(num);
1430
+ },
1431
+
1432
+ currency: function (num, currency = 'BRL', locale = 'pt-BR') {
1433
+ return new Intl.NumberFormat(locale, {
1434
+ style: 'currency',
1435
+ currency
1436
+ }).format(num);
1437
+ },
1438
+
1439
+ clamp: function (num, min, max) {
1440
+ return Math.min(Math.max(num, min), max);
1441
+ },
1442
+
1443
+ random: function (min = 0, max = 100) {
1444
+ return Math.floor(Math.random() * (max - min + 1)) + min;
1445
+ },
1446
+
1447
+ percent: function (value, total) {
1448
+ return total ? Math.round((value / total) * 100) : 0;
1449
+ },
1450
+
1451
+ bytes: function (bytes, decimals = 2) {
1452
+ if (bytes === 0) return '0 B';
1453
+ const k = 1024;
1454
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
1455
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1456
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
1457
+ },
1458
+
1459
+ ordinal: function (n) {
1460
+ const s = ['th', 'st', 'nd', 'rd'];
1461
+ const v = n % 100;
1462
+ return n + (s[(v - 20) % 10] || s[v] || s[0]);
1463
+ }
1464
+ },
1465
+
1466
+ // ==================== Clipboard Utilities ====================
1467
+
1468
+ clipboard: {
1469
+ copy: async function (text) {
1470
+ try {
1471
+ await navigator.clipboard.writeText(text);
1472
+ return true;
1473
+ } catch (e) {
1474
+ // Fallback
1475
+ const ta = document.createElement('textarea');
1476
+ ta.value = text;
1477
+ ta.style.position = 'fixed';
1478
+ ta.style.opacity = '0';
1479
+ document.body.appendChild(ta);
1480
+ ta.select();
1481
+ document.execCommand('copy');
1482
+ document.body.removeChild(ta);
1483
+ return true;
1484
+ }
1485
+ },
1486
+
1487
+ paste: async function () {
1488
+ try {
1489
+ return await navigator.clipboard.readText();
1490
+ } catch (e) {
1491
+ return null;
1492
+ }
1493
+ }
1494
+ },
1495
+
1496
+ // ==================== Toast/Notification ====================
1497
+
1498
+ toast: function (message, options = {}) {
1499
+ const { duration = 3000, type = 'info', position = 'bottom-right' } = options;
1500
+
1501
+ // Create container if not exists
1502
+ let container = document.getElementById('aegis-toast-container');
1503
+ if (!container) {
1504
+ container = document.createElement('div');
1505
+ container.id = 'aegis-toast-container';
1506
+ container.style.cssText = `
1507
+ position: fixed; z-index: 99999; display: flex; flex-direction: column; gap: 10px;
1508
+ ${position.includes('top') ? 'top: 20px' : 'bottom: 20px'};
1509
+ ${position.includes('left') ? 'left: 20px' : 'right: 20px'};
1510
+ `;
1511
+ document.body.appendChild(container);
1512
+ }
1513
+
1514
+ const colors = { info: '#3498db', success: '#2ecc71', warning: '#f39c12', error: '#e74c3c' };
1515
+ const icons = { info: 'ℹ️', success: '✅', warning: '⚠️', error: '❌' };
1516
+
1517
+ const toast = document.createElement('div');
1518
+ toast.style.cssText = `
1519
+ background: ${colors[type] || colors.info}; color: white; padding: 12px 20px;
1520
+ border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);
1521
+ font-family: -apple-system, sans-serif; font-size: 14px;
1522
+ display: flex; align-items: center; gap: 10px;
1523
+ animation: aegisToastIn 0.3s ease;
1524
+ max-width: 350px;
1525
+ `;
1526
+ toast.innerHTML = `<span>${icons[type] || ''}</span><span>${message}</span>`;
1527
+ container.appendChild(toast);
1528
+
1529
+ // Add animation styles if not exist
1530
+ if (!document.getElementById('aegis-toast-styles')) {
1531
+ const style = document.createElement('style');
1532
+ style.id = 'aegis-toast-styles';
1533
+ style.textContent = `
1534
+ @keyframes aegisToastIn { from { opacity: 0; transform: translateX(100px); } }
1535
+ @keyframes aegisToastOut { to { opacity: 0; transform: translateX(100px); } }
1536
+ `;
1537
+ document.head.appendChild(style);
1538
+ }
1539
+
1540
+ setTimeout(() => {
1541
+ toast.style.animation = 'aegisToastOut 0.3s ease forwards';
1542
+ setTimeout(() => toast.remove(), 300);
1543
+ }, duration);
1544
+
1545
+ return toast;
1546
+ },
1547
+
1548
+ // ==================== Random Utilities ====================
1549
+
1550
+ random: {
1551
+ int: function (min = 0, max = 100) {
1552
+ return Math.floor(Math.random() * (max - min + 1)) + min;
1553
+ },
1554
+
1555
+ float: function (min = 0, max = 1, decimals = 2) {
1556
+ return parseFloat((Math.random() * (max - min) + min).toFixed(decimals));
1557
+ },
1558
+
1559
+ bool: function (probability = 0.5) {
1560
+ return Math.random() < probability;
1561
+ },
1562
+
1563
+ pick: function (arr) {
1564
+ return arr[Math.floor(Math.random() * arr.length)];
1565
+ },
1566
+
1567
+ color: function () {
1568
+ return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
1569
+ },
1570
+
1571
+ uuid: function () {
1572
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
1573
+ const r = Math.random() * 16 | 0;
1574
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
1575
+ });
1576
+ }
1577
+ },
1578
+
1579
+ // ==================== Validation Utilities ====================
1580
+
1581
+ is: {
1582
+ email: function (str) {
1583
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
1584
+ },
1585
+ url: function (str) {
1586
+ try { new URL(str); return true; } catch { return false; }
1587
+ },
1588
+ number: function (val) {
1589
+ return typeof val === 'number' && !isNaN(val);
1590
+ },
1591
+ string: function (val) {
1592
+ return typeof val === 'string';
1593
+ },
1594
+ array: function (val) {
1595
+ return Array.isArray(val);
1596
+ },
1597
+ object: function (val) {
1598
+ return val !== null && typeof val === 'object' && !Array.isArray(val);
1599
+ },
1600
+ function: function (val) {
1601
+ return typeof val === 'function';
1602
+ },
1603
+ empty: function (val) {
1604
+ if (val == null) return true;
1605
+ if (Array.isArray(val) || typeof val === 'string') return val.length === 0;
1606
+ if (typeof val === 'object') return Object.keys(val).length === 0;
1607
+ return false;
1608
+ },
1609
+ mobile: function () {
1610
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
1611
+ }
1612
+ },
1613
+
1614
+ // ==================== Log Utilities ====================
1615
+
1616
+ log: {
1617
+ info: function (...args) {
1618
+ console.log('%c[INFO]', 'color: #3498db; font-weight: bold;', ...args);
1619
+ },
1620
+ success: function (...args) {
1621
+ console.log('%c[SUCCESS]', 'color: #2ecc71; font-weight: bold;', ...args);
1622
+ },
1623
+ warn: function (...args) {
1624
+ console.log('%c[WARN]', 'color: #f39c12; font-weight: bold;', ...args);
1625
+ },
1626
+ error: function (...args) {
1627
+ console.log('%c[ERROR]', 'color: #e74c3c; font-weight: bold;', ...args);
1628
+ },
1629
+ debug: function (...args) {
1630
+ console.log('%c[DEBUG]', 'color: #9b59b6; font-weight: bold;', ...args);
1631
+ },
1632
+ table: function (data) {
1633
+ console.table(data);
1634
+ }
992
1635
  }
993
1636
  };
994
1637
 
@@ -1005,4 +1648,3 @@
1005
1648
  console.log('%c⚡ Aegis v' + Aegis.version + ' loaded', 'color: #00ff88; font-weight: bold;');
1006
1649
 
1007
1650
  })();
1008
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aegis-framework",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Lightweight AppImage framework using WebKit2GTK and Python - An alternative to Electron that creates ~200KB apps instead of 150MB!",
5
5
  "keywords": [
6
6
  "appimage",