devicely 2.0.11 → 2.1.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/bin/devicely.js +1 -1
- package/lib/.env.example +20 -0
- package/lib/androidDeviceDetection.js +1 -1
- package/lib/appMappings.js +1 -1
- package/lib/deviceDetection.js +1 -1
- package/lib/devices.js +1 -1
- package/lib/doctor.js +1 -1
- package/lib/executor.js +1 -1
- package/lib/frontend/static/js/main.96600727.js +3 -1
- package/lib/logger.js +1 -1
- package/lib/server.js +1 -1
- package/package.json +7 -2
- package/scripts/shell/android_device_control.enc +1 -0
- package/scripts/shell/connect_android_usb_multi_final.enc +1 -0
- package/scripts/shell/connect_android_wireless.enc +1 -0
- package/scripts/shell/connect_android_wireless_multi_final.enc +1 -0
- package/scripts/shell/connect_ios_usb_multi_final.enc +1 -0
- package/scripts/shell/connect_ios_wireless_multi_final.enc +1 -0
- package/scripts/shell/ios_device_control.enc +1 -0
- package/config/apps_presets.conf +0 -271
- package/config/devices.conf +0 -24
- package/scripts/shell/android_device_control.sh +0 -64
- package/scripts/shell/connect_android_usb_multi_final.sh +0 -64
- package/scripts/shell/connect_android_wireless.sh +0 -64
- package/scripts/shell/connect_android_wireless_multi_final.sh +0 -64
- package/scripts/shell/connect_ios_usb_multi_final.sh +0 -64
- package/scripts/shell/connect_ios_wireless_multi_final.sh +0 -64
- package/scripts/shell/create_production_scripts.sh +0 -64
- package/scripts/shell/install_uiautomator2.sh +0 -64
- package/scripts/shell/ios_device_control.sh +0 -64
- package/scripts/shell/organize_project.sh +0 -64
- package/scripts/shell/pre-publish-check.sh +0 -64
- package/scripts/shell/publish-to-npm.sh +0 -64
- package/scripts/shell/publish.sh +0 -64
- package/scripts/shell/setup.sh +0 -64
- package/scripts/shell/start.sh +0 -64
- package/scripts/shell/sync-to-npm-package-final.sh +0 -64
- package/scripts/shell/sync-to-npm-package.sh +0 -64
- package/scripts/shell/test-local-package.sh +0 -64
- package/scripts/shell/verify-shell-protection.sh +0 -64
package/scripts/shell/setup.sh
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: 'ed4f31a56e84a775becd5c8bddf461cf',
|
|
33
|
-
content: 'ca41a0145e404869a7da5d1a50fcd21f6e933d855a402cc50db21e2bb8ec995720a88c71f1481e9ed8d025285e0ed5b6da7b12e9fc2d8d1fd15eabc11cb0b250695a98978675a5c7f719592bd5b988286590bc4c4abc80d2b812327e1c2345242b15855afab3966406f5e46aa6b62370e8b1df2b713ab5e6cd92bf4b4f199e9ac32a0ecfa488188dc866af6453e65eb2c38603690407a22a3417b76d851f521b35025f834d9dd080e8b62f69457f654be2258ecda6cec4ee3d47d0c3b701d85cdd40f7765a5b935a13790b9776d49db7fd5765744fc43f2e9bf4c1d2b3bc717568a3d911b9f995c196724c63ca12dae2c4a07aedda593b5b223ba4123795f22f9c27f849f0e081d18e2152827c6c558ad146af85760f7a17066d5be15a00d07bca87fe7f86d868d14f4bcf97824f2f74fb9c995401bdc2e00bab7e5576a90b5f2845eaff44764d63770cef7820d1fffd7eea3b1fc5249857fca117dba0bd5efaa8d1671a4ff7eb48486b71cdff04c30ed18625d13efc13a5c71aa2b71c435d7b03a10c7b68c9c3983fe672edde35d52deeb9bf9cbc08527cdef95fae88357ad2300c01185dbca6a6d3be03e83dfe6aa3ba8445591c7fd46edd624dc56da190b7efee4e15009ed28cb0f1ea75ab57cb31d327a918535f048a8f7a2db715088b3f1f14f0d2d76c25d185fe26c16068ab68a47c498f28d2fa22271fbc240b7c5c03f8e0258581aa7bc61609fb99e6e6c2bee43995846d169772186505018d473319b810ba070549c8e9e9a9fd801ac8dad5801d17455ed46c60f5a7195f21e952a8f94bf3ecad19dce8d9ee28a24e365677ba798651d3a319f4eba293e5d3c9755a567958b21901b458850ad0ee78e343423bfeeaf2f29df3028dea0b965c35dc77a14f5aa61dd55e4cfb23ebaece40f949d2b00b3c7c418e8f73b952e1f213938e09004e87c826f0e0e59b59caf7297bf8e87661fcf5641b7b000c52c4669b849ee1d16e9d110aebf9e1514d7316d0946410c121cdc38d9a66930a48d2661aa1f869ba8c067655a5ef624568014a9443cb277882c99a14d26d233a0d991ab400f9e63a963f47ca94f91f8fde639a8cd025e79f440f345daa3e2e073a31b8b6d80f1e0341cbf876c2aca82a275eeac86ebfd8e922ffa4dacb7bd3f5d63a4e50b0cf64b646e71224ac323258dc5b2d8dd007276a0289cfe9d595e63212f651fba62a83658acbd17dda20ae775610bfbf2f2513ee82f72e7e02aef2671aae35bc794239f42af4a5e1aa1a71757e495071e52864a81da508b59d0f29ae2846e2a84b27c69f72e9b79a526718f210b7dc13596c3a06047c063e464c23dfc9152a02e6007a2ef2bc67b00e5981c7f1306194cd1c3aafdae0bce9cb789fb4d5543cd4e4f74ee224a1a6f023a32c65ac227582b7fa82ed87cbf1281766d9848d0db1cde48d721ecb094fd00af24586ece9fdafcd9b7511e7e771d1d29d0982290614d5ad5cd1abdf21614f7c6b63393c52e8ab6e4a2ebf1e0cea45fad51b825692a5308a48ea821661916b5fc162f1e6587e59d6984afe0de5539b307751f39c2124de9c8e146e9e9019cb90856a482c809f83ef4c662f97c8fa730c6b52fea1788ba5c49502013f323a66f92cfccf8e73d745e290a3aec507874338c49bbacb45eb14987453d5e75d13681d8a6420230fbc05de68be172aea08cda5ca0529cb8fdd05b62d3282bfe7d9330ad9ab6d36a29d9c52c74c26bdff9545b220044488582ab5a15dd1b22af79421b88d0a07898e5151c4238fb5fd954d2ac0a37d13d869721fe4dccdea37b33cedaa7f3f8e17ed4888b76498e42e053406f139e4c3054dea3d9d3417700c964da39edf985be17fafffd8261db9273fbc6aca7e31435ea70b0cecf38d6c8fd8e2eadae55f8336e03bf55408ae66b34639cededfee97e24d7fb9e87f5b9cc5e113a161f00c2a881745bf7953ed3090d4a52999d4d4cb959758da957d0ade288f9ac8d91851e93f9d2e57cd3e20b42c93d7895db383a354d770bdfb9cf166a9f3036516cc397516a79d4695a58ae694cf7fae75acd12e0bab16b2f1d66a8277f49b9e67fe0dcc2d296629f970102bfbd75918183565755eec3793a0631c80f844ead372902eb50b30bf0030da1585ab82b093411e1eb8e27ba1c0434d8d004d5d0f6f89a0b1475b8270e86cb0034d45017505cc9de7c3605b660dab060b2093e3c6a2954a87d8f203c23b2d290acf3c9abb25367b9dd503d928a2cbf465a369313cb3e58f84869709f447f0d7f4108da5156c845a294ebb9f7fa9899a1ffdb913d776e841861573b4e9f7a8e3f921d3f0ae008415cf9be3edde956e26ad6fae6a61ebc85162c498ac4a3544ba70479f62d7f4bc044d8e46da6fe1f156ef8c5538658f765b52a281ae7c3933aca3139e5ccdbc24201e7184aecd95ff5e4c813f28c223877b4050a55a91b5b25c53160d49b48f6a9d248a17104ca598cbfec85d9532ef8842cb3bc527e01a16906d8d38b96ded967b3932620202e14cdff9be1ff95aef720655bc9f1bbc9f864988172d209476db106a012f44bc3ed90103fa41a606eb383901b1277e04e3adbe74abaa2a7bd7a5a6ef80cfce94495f3fb5580f1dd392712d9280d2c4a0dd6d309e651ac9c1c3574d054531f2abc024a963846bbeac0985ae54d32e95efba08b921bf656b50b710349caef8c2bf757c770920acd0615e7be4b17ffebe99464b3d2445513e3293357753bebd9a74c48eced34a0962d403fa83c71e8d688c274b34185adc9fc9a818a7ddeec6609436654c689db483d11dc8ba7f66176e76d2d2412dcab7a898a6756dc9e36d6291a96c2cb0010cfd03ff63100ba6c7d8157dde0dc248b55027b1568e13cbf55c9ab8f3ad09b397ef73ab68c471dce15012a59a7729a65492e0f3316129f7b854a2f8079897f73a1af88352b2c1f45a603a2821c89e4cd7998c98dafd3e56b5555b7dd87704bce422af976d7656cacd1be36b4ac825bdafa03fd78739c58d8314b9f0f3353205b82e1d37332cf0301ee0cc525e2360367d7b1ef1fa85dbee3c91c795e663ca20354f858994d4cea18e2b6ac24f14ba15ae6695587841dd1f77beb0bf482efd2ba8290f8ed92235da5419352bde54d3e38c7e19fae0caf7ef609abf5af8d1ed29371a33f76162a797294d30b4d44122f3103a92329a945b885270a3a99fbeec35542ed7c10b9dc6944452def11eb090aded47e5e7933e074c059a6eb8a14e171b9fefca193c9f755a48bc43a802adc042bf048d348ab00d22ae4d60d2cd12ea826e7b1ce0f704d21a25dfcdb7b129a541c1016c4b3647c7ea406e9144c98fca117893b4ff49c5b2d5a7b2bb41a7b5db359668d09b89b552b08256a4167e2b5c5f84467b67fd1425be365abfb8b7d3fd13eb889ae4348ecc5c57a46fd3737cbd33423f6f688c30e81d0049e21482cd274144f9573445fea5011a68077f9bdad8dfcc0c0afc92607203692dbb83d9684306121458c57847ba6c98fcfa9999c76a634468ebf796233694afabae32f973ae0903e1a4c38e1a22bb3637fff7792c53a7564c3aa90ab536388f4823d31573bf70f401766b39b66554695ba873a0ff81ca90610179a29bee99baa011b1995429f37a667d67a66f2c8d40b21518692468c4e8090c126bd1e75478d0fd1825dc9add533c7af7028508dea2c4da48f9245289df325b2e05a6c95a7e857048d0114d3e10d6dd3044b76dfd65097133f735c085afdee29f1eb426cf76b7432bfb0bbf1e042264b369277ca3f663a67419274b77a590cbb412f84dfa45c785ac9b71693a0ecfa1809a507e176700e7a007a123e7b70c6b4f3c78b9e50d61b08fad1be49e28a6597f416280b760379b1517d7b4af4346411e5c6ae0d493653282c2ee4cde8a9ecd360a39f2b2e90bfd10b4389073a48e03c518dfb0a156e71715066e408aaae1d5635f6edbe65dc66a6e34ff59e167a188253b348aca43eca2da9f63a57230eb6994747180223cc70234a9e1d3e32f13d18b4bff8ec8fa8a10c32595fe60047614b92f4c6d89eba0efd996ee1713637f985fae8526ad452d5bbe45d829c8361ece3075ef7a75ddeec61842fa98cf6487db22fa2825753c1a8722bd6bc3125ce34f4fe5565ee4dabcafb23e57cdbaaac8ceab7490d42c7473b8f8436b45363b0c4bafaba01a157d43cffa7500073a79c58b891e0b27d584fff1bb6903e85f72f4a4f8523488528bde98749adc7953ec54d1044788a1ca77a969b09e41987582a24ea51418393cd76951b2ac085d8230c762828086e334d0508d597480f09a7631549374b6619fadf83c071b44ebbd02f1d391e81beb84c36c77603c7c152a1798d142a5f860d6f4a13baf68225f95db4edd268a3fd1af438691f82f98254c3bf197855f49f38c38dc9daeee1fc0a73cf01df5eaa81ed7928d75d39ec22ef42bd3cf8bc131bd6951f6add0cf4bb9ca2a5a83aaffed9dd86767eecf1cd43a6a735a536e97debfa0935d6184e0894e2a6488cefbab3cebbe787eda28b9e038638c4784d1c872bc60290db9c1613ec46122dc11beb856c549667bbedf864ea95b08052c9394b8f92eb95f70db5c61c86516a5e4c35dc7cf0509193a64517ea9c2ad565223aaf6e4259b1ceb6e9313ada556932ebd22b7d82e151cb937dea71fb0fe65b6dfbd54eed50e335cc0b4c59fe9f4e63586b761bd9d9c53b5809a33c23ad05edf7bf6709ff59f09d9aa8146dbeea57bbac74fe9a1fabe827aeace7bfc52995facea95e48a4ed95d74294f12'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|
package/scripts/shell/start.sh
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: '25fb07f0b6995dca1dfe9be1c4baaa55',
|
|
33
|
-
content: 'fa45db259c9015ac214489048406df5ec1abe2d7e3d2d52793f9ebc447809c49d18c79928acc52f5ee6db349b177e94a0b8a7bbd797f2d8643edde1147df8dc267906a98798b29d3ea1ba463277bc4d785ccba113db7041b3f34d50c161f7cfcabbdec34fd0fd42d807affc54b4bf8972855b20e22febb6ba7c4456889f2d979ec8c5d350ebff20fc51ee3cac43909ae6e5783bc551bf42e3314f37ed317f3554e21eb473a2745d3d7ba3da391668a1ad041341a3867a1b027a95bccf3e15cff983307f15a809061e7b2a8b45a46be2f146f7d65b5d0f0732385a66a842a7f781e85db396aabc9c09b8b4e3596e2a811944657b100cc53d58de00f80137a74b23e7b94d27ebf90d8d266862c3fda144e2910d38b37fb12b38a5e7b959e2cf27ec0ddb1aa2a51bd0e14bc00db812fbabf69844bad0f9e13d5c6a924af08e7a4b5c0546c869d3191825f58ee8e8131911db41bcf56282b7a58a200ea1d4a86b5f4ac460e9ff6512937e1a0861e69df98cdaf836a00c4eab45bea6b2058bbbfb678ca24447894370a62426bbb522a4cf5e720f7bb7cf816e1880c42073a450936140af0afd5fed39d909072f7dcec1da4c6a8ded99e36802173ac5b62773997aa7d269312b7af0f269ddffaca91953eb908c6f4a5a81a10520943fceecf087eaac6f231f472b8c08fd85a7726a6e1d1c33dd2caa1b9629beddf2d8e697bb8651058454d0c8a8eae578ba4ac72b36bd69a96abc2385a02936677b1ea0b5de75d1cd0734906a72aa08be67887c4bd48cc25e18c422a6522089e4127a86ddc1e6c9c73d60417301e593d1e18fa2ae79e8a6f7c7b3e4c686712e0a732007455d89f752aaef7d9d0426b6ab704511d06b8a5e5e5ec5e9e4a1e9a7d887db1770ccb4091b0e2e43d10499acfd449a35f8baffcfda3e21905c5665509084cf44d08b53563f311f1c3287efaa94a74dfd274a237327219a0ae1cb515fa11b52b625f74c199990cd63c0e4256b361c83c13f684da9c97ca13eb1cf4dbb3a05f8f5c5368c59ebe9cc351f7829908c56377326366ae408f00fe5c92cf2681989d5a91c6d17fe87ff9898bebbb5eea04cc82a72d82752a18dc0b918280cbd2c08f69d3b35b7588c5c0c1c7fc33091e7cd5fe2baaef699643963a824f1989b547abaf1f0df88d0b0f91edda6ba4bf76c50777a754491033cbbbf8c23691006428f25d837928d98a4584e8f61c724aa98d2e197e465b31a5ce42243a076a34e657f0dd87998b7892b3f6ca989ea552c2028f8b555dcf555fbf1f76ffd6b7afbc08c93c405ac96399377aea92424317211024db0a70f00eab87de4ad7bd66e11d747730d4b87661580c26ab240e786b74f0f38bca7740be2cf2c1d469b53d2fc67d5ae5db907bcd9eefd9900bbdec3f6c6a8cf44c8ddba07bd1d9db8add90f3118c80190ec320dadb7a23d93e3cabeb76e5db89e193cea9251224cf9ad5aa446c4defb7005d56d254954e6ee3ea8c0b6bd31e520d94dc1ab14d0189d3f27e420484c3849384d3023d581cf73157dfa89c7fd6bb608e5de3d87f7e94d0a1f0a14c4bdaf54fe3e6653c755b6ccb94f7405a30fed32c9399f5d9c7f54ef4d0caed4700938ea026e629a7d3d7c599ef22f86c6cb9585f6cc9a0483d244da2f6d57e0769e779f987ad3a424310a2dea3a5039f43b3f2540b4b2017e604d94958765273603efe01479738cfaf1f3d273cc40228a459e31aab348d8d94c38537f105c3a74304a1bc976dd662c0f1b783d099065b91d4442eea4d2728af29cd37e181b88b9b1789cdf3c5cc37e8f7015ea60f9b6e3f3cb19745a176ef44d4b7ce38c33078d1b268f40a0dee021988f2b55413e5ada6f7c0877d8d0cc7ef7502c955b258d45ad0967b263641e3b52d993fc150c8ff4ba0788fc659b73e2640cda89daa5c0af65fcd4db9094c17e9843ff9c347f6b011b6b7708b86a96c343a69e1e4b3c526b31c76641940ea361429ded685f7a8abf4afeeba564660b1a023f5a495744ac601f0a7ad396cd460b0513844b3424bab0d811c8592d1c39bbe6f30194ec4d6c4c2bb0c4ae885d5f858b8eb025199a86f9352b0de0a0038a0f38c6769f0c972b1b6db998434e9a983b049d52d079a0b521613a6acbee7cdf313f277c4036c2161b6b15b414342495a95f167776359fb4697478f6992b7f19c49'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: '2a47b55ad55aed4cd6eb514c379bcb52',
|
|
33
|
-
content: 'fe4c5d1bce3c9ca683a0304f48085b5d57e9d5f941cbafaedead74e18b9d0473f01d3eeeb123573f875602c7d8616b03838fb897b0165d14cf9d2b09ef0152d072b9ca363944758577d4b0b54614331eebff2e1809d17620815032fad0122d29689067f1307706bcfbdc6641ceb3d548078399fe572541f1ae912ff99640f7f91d210135869f87c77f67c77215ba73ce7878c92fb107b92712ec84423c02fd1308db66522ed27943541a633b98f26bacf712926ac386abea488a16742f9cde966d8dea5fe10448619a57dc5905aa2864f23ed9065b45343f908011a2b83cb950bb42c04c38d4984813973578d3748f4d0aee37d96665ca48966aab2c917ff01ac8df833c05edc3ee1d44b7a6b537cb29d7fad0a8706b529f8085fc1606ac49f7c947e9c5212638c83b171961ed3d820bd1a5dd1f3549a200e21935928f369cb411c9235a0a4fb164ae45f4639c7ce97f951b2279e74acc09601bce79a15223f819d65b6d877637457e59e1d0c710968e9ebae23f86cc0c9a0c774b3794e0ff724382c4eff02448df47808e74f38ce5bbbeb0a7933c69c9e0ca3e5621d1351bd7e3c0549f1cb0cc304bcb5c137b608b91effb5ccd13d518f8f2cc46a3eed382def34c7f7d36e9a4294e86360dd78b4061a81c6f5f69d7d2de98898e20bb12a5a1224b4cffa8864e1b7b8448ddf84dd4348dc4481e0ac6500aafbadb024131a6204c8fc4ce4105a57080a8ede9470991e7824b640b8b58d61931751db8a31df1b0f2dff2e65db24c6f9904eabbd47941cb860357e31f8ab660533a317b0984afc99e54b32aaece446a816911e6445f8c5aa0458ea3a2ef004fa243ac4e6fa80956bfc43ca6e2cdf7ee2eea82c507bf9b21e4bdf51507564cd4da805199cac6f2dc1554ec63071385d4ca056b2ea55ca330e90e8067c2c67a0cba03d70fddcc7bc794cf6cc17495aaae25be8d0860bf601182ec9943f41127ee7462b760599a68ee18a6c1658470f632739d26ba54ab2cbe75c88b72a6030c40523c7055582c59c5ff630391b800984f34f43c953ccefff23221649212eac59462c77e6ad2032ce7813d58fe53899711d3072c45a38886e986540ddb6f61085b951c3277ce54e03fea82bd544e5dbf7d31168e383a6762c647e4d31b1a4fff1c507dfd3fd6e184cb543dcbb20c29bd1a8d817e4902c65b6b70f3a1639a8395f7453cbd677bd85f0bd857d23c33949aab0dbf4b5b7f0b73e05d223227bb709f641fdfc57e24ccedff37ebbab2482064555c2dcb1710315c98d4af740691b0d1540471535801f49b8c430f565516bb157aab2cf7a3296d32d7464dd924b1046259ee15bd5232cdb9f14a641b6bf0ee2cbdd5ed895de53e405593167bf7f13ff0c7b460a5b408f59f3844329d1ef3d09dd92d97de691658030220076636d2a9aa7dd18c5d27144b285f8004e753a01c689b3f400c45cf5c73770f111eb0b5008b9957f14ab74bc9cc22d1eb54b88999156b61320101c7a827f893fa28fb4ecc78de7a033f698cf83d1d3bdf3e884a62537550ed4cde66258445cc0768cddc7a7ca1d4fb9ee1e0660b50c9200bb83bcada75f1ce6ebce55e0e7cca98e7bc8f50a8e3d2cfb1b8a57f2b168317a1e258eca344b0b92fbd8165506038a4c12ecf2b3cadbbf0855b8b3849fc8a76061a4a799f54c787d70cc173870231c37941255f2d32ea942004d9a944920179c9e669481fcace4be67e807032e3fc96e883029839eacb3d4781ed505029fd0a61d650a0bce46fe731980ba34a1f563c770814bb535e5185d064b7d243c5f39bc28a8c9cbc683c37b5836fa3c2a0b2064b33ba8214a19abd0f5f28695587b84e9d34ac69985b1506be961884663978687a92dea9b9d33455eaae2ee541ec2fddf4639ad4f13868c6d66eb85b7be8dc0781e7b925e06da6ee3091b30e97761c418227fd125249e539cad9e42c5928f72bdaf9c780c0c5db8ffa6865f5ff378c75177a6a55d6243e76b3962838f0c75588899341cba6e570bfa142b8718261bd818c9bb11e91455d047be9a6f3ae92b758b9b718b88944837c05c5cce040ff206ee10c12c332d099e086c667fcdfa009faf0391e442cd1a98759f12e9f460844c3fc238b9963cb9179b66ef1e5a012cc4faa34ed205859f4b5b05e5fb567a6e08cb9100862555325cc83800721041ce3dfaf1c2d4ad2b1d4705b576ef1076be5a4cdf7bce6cc42c40723a0c8fe1b2abf0769fec7645f4a750063eb9349078205eaf93dc84a9e10023385e2b6839f0abe69b50f5eb7e3fec12897886cb3db9be7cba0f082bf6e495f1bb0a952ec50857501e60b4c1fe6ab25cf5072551a7ed30a70e88a72e599ecc067230c211567de6d9ea1170eb136abefa95f7596ef32bfd4e92515be0bd477daffb4d2ad343903c50c44af76cbd9010fb97de97c4cfa21b418177d1b4b1a00396316568179e89ed33422d8c2b0fa5bb9ffb839381a6f790a1f1e61af9084ba4b08fe8d9bb27a60d702ef9d65b19637c4abb3a6ccf53bebe5befffb2402d40d7441f21c5b3662dc88290c9a158e3e8d2dc363b124782573b90bfc5ce324588f04f1fc1592a29a57f39ddfd5faab489ee7f6bd0bc806f4c96f394c29f3d7b22c6e179782ebebb58b'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: '26d8e3be28fcc9ed6f8379efe170255a',
|
|
33
|
-
content: 'a1a5988dbb9e7fe78adfab3e8be645350a5a6e4fe93e9d25bd0fa10b585e66f290ef39fd1176fb1865915da4662b1832079c388a3f0e0a6da598bd310b3964e3b692bc5488531cd0455be71952eca20f57c9865e379040b8b1c5ceabcd69f15ab3dff903472cdd0a00c69a2bb0eaa0190c61b171560a1ee8e4a1071a5b4a33805876a215b6ee12944dc44826f27b140ea8063b66cda33ec185ab45f20b9205d2ff2098eee4af03a77803b9f79592727f7552f24972700e4d77747d70a8c2c9d1d5bfca2fdbd82a3fc8c01a5d248d65cb34cfb53969a712655d6540cbb35a08f4316f746bd5e4ca458f4c17abaee672665df664912ed32ba5510a9a501d45752677a843a73f06254c4d34135e973937724b5a0013321b3496d8de2dd3b480a5adb00186cb8f627c99fd8cd28ca2c0b941f1d0b5a12d5fdd77a2231b1902ac98f61c4084f3eb148b92d8a88c7ddae7cf9a912e8bead3744cd5d21f9c202512b72c7b1715416b80370ac0171b62902a4782f652465620e126d6320fbababa3deeef8b11f2de0fa56af8fda1997b71c5eabc4e183088af6f3fb5b7debeefa6baad08281ca0db84aee2b180ab37ee0c03ee0d510350f3a8a62d8bbcf2b78a0a01a60deae27d364d2ad02e65ed3417eb1d74ca72479dfbe8c8f9fe377914199975f8bcdc92a1b76dd099cfc420af019a44e853d66a840e8722b826258f5049b7925c7050a50461e549f2b959a4d3dfbe641effd361db9536ae1cd612ad056664eb846355b113864d18dd639ada0a919f0213d69984aa6bc66aafde283e5e3e84610169ad3d5247ac1a03dd85aa45d5726596dbd7264bddb18e3f0fc07a42ce57096e1e2fb2c60a129457fa93910bf82d00584d34a6cad44a3c6c37c44d40a7c9ba0d6ccb86c9201a256e862e10a1868c83ed7921dbda22ecddfb0359738a33634c07cdc05217f976a7ce6db5623bb5b7b93b860bde064f0d558eb9985af6086c7343fb8646df66110e50c00bb9693fb0886d8b1ce0e55e12f08e88d29c30088fc3ae88fa43dd249fbf28500664704f52b229140361649eabc62895cf1f0876ec44f4da522e610723bc7a955f82e35199313816cb395455757c794843975374c744bfb81c3367af7a75ac299f1b96ef18c41cd6d8ac2d49982cbdd38fab9e5e8e9f22c2b4739a7d8005fe8e42d81665eb5deb97850d737c204256d2a065f01b60928e10b1c0a5a87631ad9973933d1d8ffe4b929dd83a77f45ae717fd915af5b8ba17a939a2c46ec8c8345e19fb02cea7af221f9d7a03f518162c9490de1a95742c40349f9af4be9123cd6eb95c600240b1b89677c51bb07e82e6e429e46f1516f44fb1eb7ab538155d3c66c7fd06ab74b2f9c6fee2cc231afff6c9624f0ca01562491b4e3dc0079af58d5e42a293172ae72f047a135b0bee587621906e47f48097ab1b145c6b7b4cd1f05f3c7d83eb76dc43e8835760e042ed3ed2259ba802224de4d20a634c969c3502d599e92fbc7bcbea4c56a9ae0edbea944b59ef8b3662198750a429551404d466674b947651be071619790ea24fb98fd89830203117fe2b6dde0bb50ed89adb384461ea53a1b99168a247277e83512682f756d40f80dcd79bc180d17ced3a915427494e500410e7f99b701d761e1eabacd72430f69b518fcc3deabfca596c7d3eb3a1657175f9d12c7de7566cd5baec12f197f75e38090a0f8f0f0f264b6bedcdb1f6d75ee629d032c2995d7310425aa54a0d77705f068381c2b6245a59af170a8b74bab3b8c2a2b7b22dfc46d8d9063eaad841fbad2919d3c3ea2e499018c76cea465ec0412a2859bdec57f5ccf850f0abc9eb5d23a1e66eece680ac83cf954664cad88e8b9f715975d78fe3a53b8a88a0a77cfbecb7b974bcc8432aad389c6a9ae573bfe08b3b21a261a5efb0a07da83222f329b4ad13613a54819f6eb7307471266859a1427d500ad7092ff92ce89d5f323ef08afd7e7ef27127cf62ca5c60b77a0590bb5a3be70be18d1e9936dda487b65d28f6b9d7da795ab949cf9c827fff59b77019da234eee10b848d5dfcdbd8668fbb284d4c49104aa16c5346a5405314b5981f70be8451db67eefac1deb614fbb45a8cf7842009d181e40eaa7706c98c24465861e7312cb7fcd9a97fb539dbf4e4419fadbbeb751e88e81d04a77ce0db8613c581f9d5c49c630e54460c1ea9a8c8cf15924a2d4b5d72fd8349bb4fd3a598ab1adfee7838ff20d1862e6de2232ae462bf3f1539be753d0998fb696f45b3a23d36d6812a5b18942881d2fcd6c589a21f027a7e45e6fe4c081c1784516d7e653a0f226f47d4e2b9d0432127ca2a9a2de9dee8512a8d5019ab58e6086510702125ea26ecf0686f705a0cdc18208c06e403ed961b4785b91b934ffcd91d520f19d0202d4d354325e193a069b9a915f68ec4eba0587e599718ee623a87e7a1eab2e5ffa189bfbca88fd4584d0f0836202f34a5bdc9fef537ca027d38ef4d9150bb0ba30da1b892c79bb5c451ba72bd57f556fbb2d8041438b8987a4f670a2b39be543296d33dbc04d4b8b23effe1bcca5a764307e2cf92a990b052c0b70eb6f70766dcd3e51a8ee33fe306bece6a710bc178eea788cafb88f650cbcecd328aef46f0c472c10872df069d83828f744c78b1f008709d8ed993af430ca7f97d49f70c606ce2cfeef42cd7784d1a7a2bd23f57dcc0bc1f92aa1d4004b8d68616dcb304c3a65e81df9da10ab22f27178ca6869a165716698c27f2f02bd200cb51a6458fbb7852685f7120e5046ee2f003147e36240e285db32f8def359d41af92276bf5982679715f0012b730a6aef17ecfdcd4cfe865507b1f69ee51aa1e8f03719fcdd2eaccc642609682641c77c4b184393635c88b4fc0686ac61393de39f696c214beba37b2f2e39670b5031189d91c82517ed8916c5aea73cc2b246fdb9293341fb42a8788969ae0c5d7b3ece97a9fae723197b02ca04f61cfbded75e499c5d4f8ce70e4528cdee6c01adfc82dcc04aefa827d47473002127b9651e1bf2aae1839eaf569fd6695fd9f90b3c4cb896a0c6ab9e8781f99839992aad606bd3be22d18269f72b8551e7925adea9955a94d600a44153ac8a40dc32726c73b59abe66f9e45b236b6216a1430d506e5b0ea8418acf5add23a1b88dc66ddf797605c6cf87d6194d09b828136d7e4148d2b9c12b9985ebd83da65a5a843b8a5a5079f0d11dc49799aefc4115dc4c885d5d7b75fc911b2c120eaa2f603cb52a53c7e29032aead337d3d2b0f1e5d1ba2fe4c84913ee183ca9e32ab9a19e785d845e33db496444c7e48c1987c5261a31992a62b93d340523e1d094bc6be47c6e0ca8a4b787c3cd9c233e6b7769981ed0395f491ba254daf0c077bb928cfd25aaaa8230b05250ef3fdea2e1204ac75f150b29036f96b2f91b9a45914b1740ba8062ac44cad0c8ad36f59221206e62f0091b4d8d21b0051425ab9a9b37d2876a1708e36ae37757a19fc6004a2aeefd248928b7fb1762409f8e1c13bbbb369a670e9ddc0206b277f0b62a76063fc7ac0e5e8d3b37651e30a78d022faf881e2428c5315e94caa13954c5a283780c5ff5810ea3d2718e2b16e800694de1a6ebbdc63dc48143f66ba0917a5fa11f9c3f8f49ab4cfcc086e4d8ceebc8c738673c5eafb0417d134ede0fcc79e42b4e3b78749c1297baf00e2ffcbf5d9ab139e180385344bdeaf86619fca1ff797452f0dac453bee86123a846f6c0e673b04e8687787f748e01dfc1b841ff6c3cad074ca7cfe96aa219dda166504331e20be87d1510a4abfe089b694d8dd15e588fd6159dd3105ae88df884dd30fe9a17171b77431e72a389e102c69bfe5bc15a2d012c0df5fd21408a77fca826c8386bcbc73844afb56c93ce22f6bcfc19092de2edbfa595dfb2cbdd5afed6d3bcd8e935e631f395ff77ec5622ead476e5bbcd57e8d1051e9e7b6c31111e4faeedbc704373a49cc7a11950d2b8aa62c08d6290ac48d11d88f14562a4ebcee2c9bbbbf6c37bb60282f08604b2f46f63a9ab42ad3626a24b86c380355339c5a06320e1d00064f8e8831b7543f05c24e1c2d2c748204eeb2a5004c46a3173d54e30df07163978b1bd0a319840c7a523fefbafd47223ab4e7dbd42d3bb5e2a77a01ff5442d7ced6a70943648aea404544569a6c1cc5814ea59bda77a07d59cf454aeb21bababdd2d209b047eba1df80a3024611941eda31f47254e75d768988d4f0743bca28c5e2291497403a1559c284acecbb3235fea13ea372804e51e7aec6efaea82cc980d53b2079e493d8205799631c2dac4ff9ea5d16acf13c0dc7a144bf0f682e1b02a6edd03340f7c591ac0072350a9bce802de9b90941504153efba54a1f1f664bdc9781d1e3bbdc3c81dd630d572a55c691cc2f89abfd692197375794b1e699a9dd2a02a2f6c24ad7dab2646baa0ce03447fb80c627a019ec8ab99bc610ba3013cc0742f55c6bd8c8179426cdfebd49a6bf984f8e783e3929791839064162c4f810fe243cb7737db9cec11532ace85d65574f2f0997142a558ca22cff915a5fb207bd5ca59975bdb7051fb33fd8072897e3258709702b9ceeebeaab21bf054fde4207dfcaab2f402fc3d3da85a311ed1b1e1ba5fa9c43de2059ba607c8be2d0f010f223a3cedbfe3823c21bd16cf55588ccd947ea06de92c0cbe84b580ac9e47c69f931e6ca750b046c2682dcb4e9a7523f12f750aea43d3b477e578a8dda5cb49cb7cc24a217b65fe9cee1ce06d6bd4e080c7753aa812a72241a1effb23efd19aa754663bda76f41b2698148b01ce6e42c5de1d'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: 'f7ed8271877d0018eaaf14381f9caa8e',
|
|
33
|
-
content: 'cb365b38b0806afe32a6b2c341332257134767057cf47cb13583fe41153bad0a08d955e528464ad19699fc420ed9a0feafc21e6454eb71e7a71bf3a78c007c5594d47106e6579dd8429f6d2124963918d8fa33a097ec88806adc41e2daf579ac395c419855fc5a1e1c59116a54a4877cf97786345950ea0257f074903407bdbf30529f5bc2780725a5de88e432ceb66ff2fa0451f066335e31b72a8bc4e57ed81c3c5481483bc87f548fa33bf986b88b055c4229485ebd1ede270cd94fd9f144f6880efcf0d453d2e8144e2d6216170195db3210319bd55a568e3ed112a23d331b9e0c2079bc260d08c64af34b68ad2080ab12e5e46fb67d1ad7e8b409af149307fa61935135260988b09faab820cea5bfa32b7726c39fb482d07326c605334a63ac49fde31a45a05130a67958d379f327b42760cbac3fd6807702f198c20e19711e795252b9a31de1a6e6ec877b527c0c923afd944b6ddb4353c5fe59bc7983a61666696c73785303d130a3135ce5df2ee3c1563cbbc4911ac8d254c571e9253b12ad5f5cc48f09a994ba2626476f1d64677e4ca1aaf9499513d15ca889f7d864f33fb67e90f638ca57d7dbe434db07b6359c4e22882d3535a612cfdf0a2b39eaf730508187270b0e1c142d11bf5ba3e1dd490ca6ae5a5b6e5f045f5ca26453bc130d3de1e897a2a3638f2e7ce0fe2ba16e6fbdb265b4d3456cd6b2968de51ef595ccc1af30a51ed3371b9d922aa74e90858334a3754dfc9dd08f17095cf6dfeb5b4b0965d962667c3d0d342de4f76517883900cd866f74f936bf21dccfe2a047f3ce1fb39afe488a716d76116b50c6e43fcd9fb2977b168e6bb47833ffaeb32e1219ed9b604eef7c6278c6e5a9ccb42fd3cf81bd59c2cd3b1b96a50359a7f9226f995220461675b709106f99b4a7fe9f237fd29fa8abc64f61ab19ebda6b42198089362f34b747ec0c77cffba9a58fdcd0cd8d1ef69846e117ea5902e1f8616435be94c5fdc69985cd815dae03caf542497888c297ca1bf958e4ff013c48730da4b55942b70180dfc999adaa8a17dcb3214e73304142ebee68beaa79988e45ca2b71c68bf4ad26799802d57c423b01e306f7ead89537fb8adb9ec79873a8a7fb2752552734ee9f194648768a1d8934805261eee463211afa93405a1f7af89accae10600fe676eb967c0e781606c5ddd2693589e6253dde62a9e1060938869a0f2e255fafd578f6f6cf1360afa1dd0d08872172338185efbea382bdae5ceb49a011acb401c888550dd2e620187a037090bd3aed6e5683b5e31f9ef62df84270151268fd92f936b47487f6effe4a3cec2e9c28e088b460c10328c308a9677c46d17387490d7340f970e7efc6ed9933415705e938424dbff3fa7dbff77fcc3afc7df94acbc4fa00b2dbd634eef703fba487c3d78a0bbbb5703b9f596e935a9bf6671d5ec86d42354384fd4c18fcf698c044a89f729a0c1aecc69e069a96918ac78ebef24621d64d397e21e12de1990a829cb7eedb18599041143306c0a020a4696caf9d79891f91f578ec35ef309cb2f70e7368e2bc106d220063bd97c08fb468cfba020dd43de820a848d7f98dee3ad9bc858d4666178936a88fe2702f386fbab3be86372a2259a44fc91faeb5a7db6fb1af262a1341f86f8474f8a8745cf44e08445d38643342299b920778119707a9a7fa431e314ed098bbedf7139ec92ee1ad8df81c6e61096669688af7ebd34f8d45b8df46172756a2db73556f7e98a685ab8ce54fc38d98c7e13fbbd54dad171454decc7a9eb44cfadb267a58da8a77bebb8ffb24e44514b304e43417119e380448a50fdcd6d8625cd8d029bd88c5131d578d6ee4ff13a64141bb8c94fb56556a69b2c467a238557656d40af84f0a40fed36ce2eb7234e8ccbbbd90aa962813fa5a3c2453364decb0fabecbd3064b8ca7b1a7fddc18d782587a53737e4b44bae27fd4a639a8b92948cf808471e2260d8364452eaefc70b0425fc7e460b635518e7dd573f44112e1c079319042de61414848e944f7df8100d7118a27a7b97ef189b92ccba24d7b1fd93ba1084d2fc5177b55037af16a2dca929680660255f3cf054376b8deeedae39b9e593f62c0d5e7ed2185a766b1825e7690ea20bcbf505954fe7476314e870ffa8da79f129caaa1a30306e978d7a4b48227b172fa93f4a932b706fab350f7bfad0a951f15daf420716d1038b16363a5efa0eec154c2ef65dcc7df6ab352fa8cdd065ed74046ac4254353f1101b414dc9685fd83bccc530fbce303ee42d3055b47126634427af3667d5153574d0b905f7ce1366ce699cbe209f7f3ad37575211577207e86d22348f53d220222e6231c8e073caeb92b487f37db0bf61a6e1f3722be798aeb9d197a776340ee1ff37832e7b8b9413ac145e33cefb44e52a799d2b3528ec5657bab7cde5a8670627933a64ab18e1ec37f00d019c26f4e1be6e12a5d8bc4833ef4efb32e1b4562f94b424f2340fade8b204f2e8e88d51e10d8f36c98219622fdd676892b2248365c70a5895d88c54d176b815631e9815cf913982e26cc06d695a46ac41c4032e6f1c6cce93e9312cf54efdb668ae8a0e258b38c3c5f0325c641ed66aeadf6d254eca7c1fb313f58d046a890849bd709f785701f97f9126fb8f673ed7d04c3aee077ef4c251767f3552f03a6596893b0446f96d1febb48c08fd1343de291eb813f332f4bcad00828bbea13265b6bd072a6341fd1a9a54516e5976abb424771ec423686a12f682475ec8600f08f46bc5002761c36308a2ab5ab43da7cba56e688bec072bdd493366f9aa2ed4d321ac0ebe192366511aafa6b01dd45cb5e9ef2529b6854cb92189c61d9d9060de319d3925981d83468c00cb7aaaab9ad999cdf307668d98235d89e052eff38a5fc8b24e89ff8c4f0dae2d86d6b5acf6777ba964350c18e0a04aa12682a88f71cd472856d9d27c50abc532db87fd31bc094040435ac0fe32d4911f53683a389838619acd364036927dd91e707d4b580d4e96d9bc6d979b0083206396cf9eedb9553f0109087c4be91f760c55d9d9ffd133f5252aadc8084af5eb03832c6d0b4853c60c5b14975409be1869d11ccb8bbf18c882bfbb3649b97b20fee0e5ed8da99ff4ad2450e18fb27081582d87ea07aa90e31e761cc90be9243c83d60415e4cb6c3e50eb1d0f437fa375401371c92c3504c27f6f7bcb69cb29bdf738f280d48c6dc2b49e30ac82c0c4a69948cf0fb70fc9594fbd01f485d3d998ce06e7e64a0b4b42806bf18d7514d3bea304d4823bcdfacdb28574244ca223c0d94dac8d225849c82907449e1bf6be183db36f0e85d2103a32c1d840f4a3a983060ea5cd7c35fe75babff350be4c074fed9727aa664ca0aa59f7a4bf11157edf4ed3ea756d496a0635e64d21205bba586231dd73be46e68ad82364d79096869c09fe9e871af2aafa7c91bd9aa6a81b3b7e58d187148293da26fd497a3eeca55381052d7a4f020922a3bdc9ae8d9e7a902599ef5a39aa8035db5a8dc4a837e5c33e1b27cb80ba79a7647e31e4c40e1f0da5eb9cd2dba8b978b09dc959eeef16993e5e3417a5cbd728322841d3dd3c8b0a8ec8e1328e60018d98ac30ae3259f790f625a73a1c22795251540d06e1c4c704b9dfdfc7d130468df235228fae765ffb7c54f30154b2977fff915aab1074f7248cee8e5703413390df47abed9f1e6595d95ad5e82845bf415027505fea42866f2bfe6d271012ebfe7f7076d81d373bf4635c6c45c0b957633e51fdec213fc55b8dd9bd55f2b8f7437537d70cdf134b1df99ff6579c6117218f654b4730c614eab101bfe2c14f2aaac04b38695114ef6e0b702e4554756f8d95f365b59b11f237a15ad6353b70aead665da1f29a732c38cfa75e4b9cd3a007115e8baa0a6ce9eab766c12f686900282de745c0f46f7e6192c44ab89069d3b4bc6e612402536e28d181158a2a1e8d224f853a78d317eb95868351e077a12adc57df198af8760d5370caff4d040a2346215511ac45a370d7a8dd0c50a44e9fc3142a027a2edce9cf6e68453f1b38da76f67f67766e1b963246bd3af244d178a56bb843955632af721935a913b87b61eed5aaafeff615f5ecce45b19567a4d2522e3a68390e6207ae6945c2874faa70f29de0f23f59fc90e37b684c3565843fb368a3bee85fb604e0f4745aed88909bc78b382dac60a9a43170bb93eb15a1f62d26514b3f750b238c601ee64116c80d1997a8aaa56d0cc4612decd2f728ebc90c6b717479a2e9d5f81e30aff1de53b9d3c30970119c4b56ae835ea79e129521adad3e204d7a057bd07659c4d3428e2e26b92f1ae10f8cdb5c3c9517449180a008703d20d6e26cfdd1b141d5691bbfbe5f57f6768b6c277ace957e5604cf21868994ab08ded1453e35522769a693c23b7b414a05f35a2566945d2077cb1dbbfd72d7346a6128c733be9f5c044e5033995f5810a225173d3c2471f66d909eae455df8ea73a7047144e8d320982570f9895b7b079de5c7a08421292dcf60489a87cb8b8c06df5694f428c6e117010fbf42f1bfc0af86ec0e10c46232bc728b612666aa41e78eb90c9e077f7c4e4bd522d099ad1cbb375b5efdd772ea33192094c892695b73043281bfca14228a4d4bdfb749e7a88a13a74b1bf846228ba1323c837d411ecfefd3f71eb400b889b65cf9719fdaea79101452c057e0e3b86a2f5557fd59f12356fe3c375b5972f286ec3dbe4efe8074645bebc4550d2419003a0fd1d8f3ca5e6bcf9604b8345d3da747ce26ad05f9e60bce990e1147ea5c22803cee711c1ebb7ed386afd03076daccad11b8976541cf2410375d6729c391f8d28c602509e49db16cabca2caee946f856a0eb6cac11c545bed85e956a4a86372acd69d8614b108918b2329aa78cd9a7f479b89c39a9a8f508f2ccd8fe814fe276d50dd95e41e100011a7f0533de3511bb16d569021edba207928a3634250c391d574b0a524f37c03b09eb8d026434f2a4624baf995d95c7ee133c1818d7cc4232750ee45a'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Protected Shell Script - Devicely
|
|
3
|
-
# This script is encrypted for code protection
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
NODE_BIN="node"
|
|
7
|
-
|
|
8
|
-
# Check if node is available
|
|
9
|
-
if ! command -v node &> /dev/null; then
|
|
10
|
-
echo "Error: Node.js is required to run Devicely"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Decrypt and execute
|
|
15
|
-
$NODE_BIN -e "
|
|
16
|
-
const crypto = require('crypto');
|
|
17
|
-
const pkg = require('$SCRIPT_DIR/../../package.json');
|
|
18
|
-
|
|
19
|
-
function generateKey() {
|
|
20
|
-
return crypto.createHash('sha256').update(pkg.name + pkg.version).digest();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function decrypt(iv, content) {
|
|
24
|
-
const key = generateKey();
|
|
25
|
-
const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'hex'));
|
|
26
|
-
let decrypted = decipher.update(content, 'hex', 'utf8');
|
|
27
|
-
decrypted += decipher.final('utf8');
|
|
28
|
-
return decrypted;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const encrypted = {
|
|
32
|
-
iv: '1cfdad418b88ce4c9562bba7a0f96bc4',
|
|
33
|
-
content: '71ccf8dfcab371a79f7556aa5108a36b241b83e7e56dedcf544d5569f20c8afd93d4edada2edf715ad3b06e4838a1af94f4f35d7e15fbbb1cbfc4dcdff1011d5e2d2d28ed6f563915978712c6a03df6a1813a591dd40714935f6a2f9fc24ed60dedbbc80d86f5b10a5c6889f6dbecb54328ac2152303034951ef8b6d13f91e772d7e27d313821ec9d7b53474355cff7588dcb79d5eb576b150fc61f0e5fe856225d5dd2da0e38246c4a8df5179212b8be114c46de1f79e4e0f67ee3028379d4f250fa61813d1b3462d02e57df316bbba973ef172afcaf61d6801cbf01f44af8ca67b31dfa5cdbf843dc64c9670d69b97798c48d47b06fd346ea041fe137b5fa62ba7be4eb681e248489473569a2feb3e8913afa25be714e85e3a4214f4df4bd970d989be2bc24025b7fa746286f21fd66127aed5e6db717084f4f3ec5f02746ddb49d6136d3ac4a5394518a1fed9ebc3f0822ae0f0b6155e7a416cecad70fda2e99a818d86fecd7de38d58bcfdfe1bcd3b643aa9f2d728b27d3487e5346d767b5d76dbaa938c03660691be313b1fefb7b2c9b10ce91251be981a798d4e398d72bfaaee7f9ad7b7bc5edab0c892dc528c911e163a5d493485a6584783cc2577759134643003009ff1bf1513d49c3811eb2d5c60c2f0b028c1775dfd67356e1d8fc5744efa80e06e96673d509be8f7253b97119ab69cf682d6dfd0a766247760736d8f8b60d606a09763ec625a0c92f9d9113f791ed58576bc075781f554af7208945f27055f65839c1b2d5542af37c9d9ff3598199229724b20586a4b0c8440b045cdef877a4440b3eda9d4a44a3ad943d9be58dee72c1e69fc3ab7d834a8af851d3542ac59028e409fcea2f9dfdefc4985b349d160c730f28104ef8923ac80eddca137602cf9a79bd499ba7acfa524b04bfbb455dec241152b8bbd5446fa12afc0ac5e99e6f9524d5974cceccb2bad4e4879cfd2c88938f972f564fa7dee26d2891f5aafea9abbf295914727533aff3990cc777527a41302b853e048b513ad4f2f5ed4d01c4ed6bda59cf13a02a21f4320f06a6656558a1e143202b5ab973a19cb62eee7582b51cb83b8e8a790625a7252ff7e6a7a0a60273e694f2af4418ea35bd4b0e6d5a18e0f48a1ead96b8180a5f373679bf093aefc592234c3558f10fc9b73d6c37cbf16fc903b3baa64315389845904f2dc39b754fe8e3b6af07e407c332358ceb99c99e27d2c98a17fd6495cd4a9faf56b282982cc95d05d829a19273a0612ef0047875ffdfcadca0c4b2800d8fbb67bb182eb2d031a22ece1a1215e099892f05d89d0a8fe49805d680f25b20af4f7c0c0dd4d5a68111e15719711fc1d36e403beffa6ec0e773db828b6f2e4e0d63507870b4d428dd9d8ad78718379e082039b835212d98500ae3c3b5454259e667a357a881390bfb24050605f665cef1bbe1c259a443cb6e670c54674f7538331573fd764ce421ceb09a00fe05484f63e1b8b2946fb8514f0f0717a902a48d1a51d463649101435e4a892067f8cea971315841c1674cafa23a48a28bb2e387c3b1fcad909f127668293695d035e363cf7b67d3713b49ffca673a6a65a3420da190f1b23f46ee40ed4803b4c88dcadf187f0cdadad9fe7fa82a445af5cb3595c792a90330f46ec0c26a8c900b30e1dbc63470543c6cd15186528faded08273d039430caa0a2d0b3eb93e98e1182cfdad595c4a3efb12e26322030c6f25d191847ac2ef02c30f59af5c9b44f9854537c8fc5f671fb9196a87f3db3ec91e9b3ae1d899f6e6fe4d0d56bff87c161615ff4f1b5a2c02c337926170a70902e96993687406610801e2c6604a81972bb7c57428e8d94d9cca5af08a4480996d4ec8cb9e39de0c3e0f434ec966c5c1023e3676473faf0a8405514501965e30478cbe24d59588db4894cdb66caeb8bf62048355b4ac3def87c2f57a396c1c3b328c76a331c5d9d5b3c7905082898eb378ae708858c85a299d4b28f89c23feca5b8e0e2ffa00ab524ba16b3512d0ddc4926846a68eadda97e4d5337f57ea4aac083a6be9833fe50b79c4057303207a94c1f564fce7dcffa0d4f1db7203774f441705021caf909eba890b54b7e835f74c938be1317e0b468d9689596521dc1af4bceab45fdfa93aca25e048e05cf256d53d470e6c4110aee5d4b54d1d83e9a962752789fc23b3bf1a2a0ef88e82ac5771052c6a841678c8abdbf7f2a0895056253c84f86b94b0ac52acafe0532e8559f41ec1668f93431c2a56629c02d5687c8b12cc6642ad2475d0a6524f624cbabcab4a73f6214e2d9006d6b25172e05b08c85e36133cdb9bd145931abdb0ac901a5376be3fe2c6085b72a0c0ce632a0a19e079fd4ec49dea6028720e109e80c8e22c38bc869ab9fdeab50f2e9f762572ec3a51f78ca80bb7fc8f46867e481c2653be18930cbbda3dd9199b03ecefee18ef0e8cd3cfb88707a64ef58cc2eace12b0560cde4baebd552a18bdd342da4c8e2a1f2279e88d139cfcfd1e2917ee17a189d0b3e3777e4c7acfb02c0f51e19d21c53054ed1bc9009b94148ed6935026c94486b70e0ad3b019f3c30d6d1126e5509672257e518906f45bebd7a3a27f9a39b818c8fdc6e9b96bd2b994f46347b71d5860b141ba439b5137ff702bd2ae02cad966f6336794eeae7e6b1b4794ee7d38262b8dbf59485ab0ee75904bb4c6a96d393a2879681222bc5633edf90762f6ed4126bf09c4df925102e06ccbe8bb9112e402430a59898c0fe7d473a7dc7f60c9bc34932cd539e58959a39d8e93f2699f9bcb96a1e44f9758cddf98b87f7f973ce9ad96823713c0ce5782433d2bd1dc0d477424c62f78a63ec6690593b529255b1cd6489e7b66c0ebda10153d65b077dc62f9c9684f67c376337dc06e2a9135549250a142edba9c199a7452a7f686d8d68339814a5182af6524b324f52f609e515c9217648dc0f0ae9c2994971b4b125b291d8e2d2bc0afd4341817c261c92da6d6c8ca7f79f64046835f8bb21fe1c53cfcdf381670a87f79dd50905d5aca0930bd4ca719fd7dae87513a1c68cf284afc19dd5228b183ae49dd61bb8eb6076d070240c1cca7922ba3347d9c9712591ce94903098954003e34044d80a0e57311c398bed112c3c1421abbc74acb479951b221d71001b7324797db3343fd700e667d7adf65e88e14d6e7a14d0447b39589d1f2afcea51abc94b56941661456f00a54f50c1027c634296b9a23e6e2fae5cbdb36be6e3429b1e3702c9fc303a559b073829ad402d32fcc85332618d2fd4f40e21cfbf4bdacaeca0e697fee02d1da696313ba38aa67162318e769b5ee78c56375514e7271e86dda08f0a53ee44e8e18f89d751c001b54ab153190007616f22fa9a3f452f70baafbb7d1743958f5d4b8dc9ff9aaccf36bad989769c843f6c619deec60e25e0c919610a0815e97a17166270708329cf957602bb2ab11ffea97b966f73c7b1f076d6b60d9da6b3184211c73ac9073160135c3d8cad14081ec231ddcf7d8a5a13b0e'
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const script = decrypt(encrypted.iv, encrypted.content);
|
|
37
|
-
const { spawn } = require('child_process');
|
|
38
|
-
|
|
39
|
-
// Get arguments passed to this wrapper
|
|
40
|
-
const args = process.argv.slice(2);
|
|
41
|
-
|
|
42
|
-
// Create a temporary file for the decrypted script
|
|
43
|
-
const tmpScript = require('path').join(require('os').tmpdir(), 'devicely_' + Date.now() + '.sh');
|
|
44
|
-
require('fs').writeFileSync(tmpScript, script, { mode: 0o755 });
|
|
45
|
-
|
|
46
|
-
// Execute the decrypted script with arguments using spawn
|
|
47
|
-
const child = spawn(tmpScript, args, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
env: process.env
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
child.on('exit', (code) => {
|
|
53
|
-
// Clean up temp file
|
|
54
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
55
|
-
process.exit(code || 0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
child.on('error', (error) => {
|
|
59
|
-
// Clean up temp file on error
|
|
60
|
-
try { require('fs').unlinkSync(tmpScript); } catch(e) {}
|
|
61
|
-
console.error('Error executing script:', error);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
});
|
|
64
|
-
"
|