Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

util.js 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. 'use strict';
  2. // @ts-check
  3. // ==================================================================================
  4. // utils.js
  5. // ----------------------------------------------------------------------------------
  6. // Description: System Information - library
  7. // for Node.js
  8. // Copyright: (c) 2014 - 2020
  9. // Author: Sebastian Hildebrandt
  10. // ----------------------------------------------------------------------------------
  11. // License: MIT
  12. // ==================================================================================
  13. // 0. helper functions
  14. // ----------------------------------------------------------------------------------
  15. const os = require('os');
  16. const fs = require('fs');
  17. const spawn = require('child_process').spawn;
  18. const exec = require('child_process').exec;
  19. const execSync = require('child_process').execSync;
  20. const util = require('util');
  21. let _platform = process.platform;
  22. const _linux = (_platform === 'linux');
  23. const _darwin = (_platform === 'darwin');
  24. const _windows = (_platform === 'win32');
  25. const _freebsd = (_platform === 'freebsd');
  26. const _openbsd = (_platform === 'openbsd');
  27. const _netbsd = (_platform === 'netbsd');
  28. // const _sunos = (_platform === 'sunos');
  29. let _cores = 0;
  30. let wmicPath = '';
  31. let codepage = '';
  32. const WINDIR = process.env.WINDIR || 'C:\\Windows';
  33. const execOptsWin = {
  34. windowsHide: true,
  35. maxBuffer: 1024 * 20000,
  36. encoding: 'UTF-8',
  37. env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
  38. };
  39. function toInt(value) {
  40. let result = parseInt(value, 10);
  41. if (isNaN(result)) {
  42. result = 0;
  43. }
  44. return result;
  45. }
  46. const stringReplace = new String().replace;
  47. const stringToLower = new String().toLowerCase;
  48. const stringToString = new String().toString;
  49. const stringSubstr = new String().substr;
  50. const stringTrim = new String().trim;
  51. function isFunction(functionToCheck) {
  52. let getType = {};
  53. return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
  54. }
  55. function unique(obj) {
  56. let uniques = [];
  57. let stringify = {};
  58. for (let i = 0; i < obj.length; i++) {
  59. let keys = Object.keys(obj[i]);
  60. keys.sort(function (a, b) { return a - b; });
  61. let str = '';
  62. for (let j = 0; j < keys.length; j++) {
  63. str += JSON.stringify(keys[j]);
  64. str += JSON.stringify(obj[i][keys[j]]);
  65. }
  66. if (!{}.hasOwnProperty.call(stringify, str)) {
  67. uniques.push(obj[i]);
  68. stringify[str] = true;
  69. }
  70. }
  71. return uniques;
  72. }
  73. function sortByKey(array, keys) {
  74. return array.sort(function (a, b) {
  75. let x = '';
  76. let y = '';
  77. keys.forEach(function (key) {
  78. x = x + a[key]; y = y + b[key];
  79. });
  80. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  81. });
  82. }
  83. function cores() {
  84. if (_cores === 0) {
  85. _cores = os.cpus().length;
  86. }
  87. return _cores;
  88. }
  89. function getValue(lines, property, separator, trimmed) {
  90. separator = separator || ':';
  91. property = property.toLowerCase();
  92. trimmed = trimmed || false;
  93. for (let i = 0; i < lines.length; i++) {
  94. let line = lines[i].toLowerCase().replace(/\t/g, '');
  95. if (trimmed) {
  96. line = line.trim();
  97. }
  98. if (line.startsWith(property)) {
  99. const parts = lines[i].split(separator);
  100. if (parts.length >= 2) {
  101. parts.shift();
  102. return parts.join(separator).trim();
  103. } else {
  104. return '';
  105. }
  106. }
  107. }
  108. return '';
  109. }
  110. function decodeEscapeSequence(str, base) {
  111. base = base || 16;
  112. return str.replace(/\\x([0-9A-Fa-f]{2})/g, function () {
  113. return String.fromCharCode(parseInt(arguments[1], base));
  114. });
  115. }
  116. function detectSplit(str) {
  117. let seperator = '';
  118. let part = 0;
  119. str.split('').forEach(element => {
  120. if (element >= '0' && element <= '9') {
  121. if (part === 1) { part++; }
  122. } else {
  123. if (part === 0) { part++; }
  124. if (part === 1) {
  125. seperator += element;
  126. }
  127. }
  128. });
  129. return seperator;
  130. }
  131. function parseTime(t, pmDesignator) {
  132. pmDesignator = pmDesignator || '';
  133. t = t.toUpperCase();
  134. let hour = 0;
  135. let min = 0;
  136. let splitter = detectSplit(t);
  137. let parts = t.split(splitter);
  138. if (parts.length >= 2) {
  139. if (parts[2]) {
  140. parts[1] += parts[2];
  141. }
  142. let isPM = (parts[1] && (parts[1].toLowerCase().indexOf('pm') > -1) || (parts[1].toLowerCase().indexOf('p.m.') > -1) || (parts[1].toLowerCase().indexOf('p. m.') > -1) || (parts[1].toLowerCase().indexOf('n') > -1) || (parts[1].toLowerCase().indexOf('ch') > -1) || (parts[1].toLowerCase().indexOf('ös') > -1) || (pmDesignator && parts[1].toLowerCase().indexOf(pmDesignator) > -1));
  143. hour = parseInt(parts[0], 10);
  144. min = parseInt(parts[1], 10);
  145. hour = isPM && hour < 12 ? hour + 12 : hour;
  146. return ('0' + hour).substr(-2) + ':' + ('0' + min).substr(-2);
  147. }
  148. }
  149. function parseDateTime(dt, culture) {
  150. const result = {
  151. date: '',
  152. time: ''
  153. };
  154. culture = culture || {};
  155. let dateFormat = (culture.dateFormat || '').toLowerCase();
  156. let pmDesignator = (culture.pmDesignator || '');
  157. const parts = dt.split(' ');
  158. if (parts[0]) {
  159. if (parts[0].indexOf('/') >= 0) {
  160. // Dateformat: mm/dd/yyyy or dd/mm/yyyy or dd/mm/yy or yyyy/mm/dd
  161. const dtparts = parts[0].split('/');
  162. if (dtparts.length === 3) {
  163. if (dtparts[0].length === 4) {
  164. // Dateformat: yyyy/mm/dd
  165. result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2);
  166. } else if (dtparts[2].length === 2) {
  167. if ((dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1)) {
  168. // Dateformat: mm/dd/yy
  169. result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  170. } else {
  171. // Dateformat: dd/mm/yy
  172. result.date = '20' + dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  173. }
  174. } else {
  175. // Dateformat: mm/dd/yyyy or dd/mm/yyyy
  176. const isEN = ((dt.toLowerCase().indexOf('pm') > -1) || (dt.toLowerCase().indexOf('p.m.') > -1) || (dt.toLowerCase().indexOf('p. m.') > -1) || (dt.toLowerCase().indexOf('am') > -1) || (dt.toLowerCase().indexOf('a.m.') > -1) || (dt.toLowerCase().indexOf('a. m.') > -1));
  177. if ((isEN || dateFormat.indexOf('/d/') > -1 || dateFormat.indexOf('/dd/') > -1) && dateFormat.indexOf('dd/') !== 0) {
  178. // Dateformat: mm/dd/yyyy
  179. result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2);
  180. } else {
  181. // Dateformat: dd/mm/yyyy
  182. result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  183. }
  184. }
  185. }
  186. }
  187. if (parts[0].indexOf('.') >= 0) {
  188. const dtparts = parts[0].split('.');
  189. if (dtparts.length === 3) {
  190. if (dateFormat.indexOf('.d.') > -1 || dateFormat.indexOf('.dd.') > -1) {
  191. // Dateformat: mm.dd.yyyy
  192. result.date = dtparts[2] + '-' + ('0' + dtparts[0]).substr(-2) + '-' + ('0' + dtparts[1]).substr(-2);
  193. } else {
  194. // Dateformat: dd.mm.yyyy
  195. result.date = dtparts[2] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[0]).substr(-2);
  196. }
  197. }
  198. }
  199. if (parts[0].indexOf('-') >= 0) {
  200. // Dateformat: yyyy-mm-dd
  201. const dtparts = parts[0].split('-');
  202. if (dtparts.length === 3) {
  203. result.date = dtparts[0] + '-' + ('0' + dtparts[1]).substr(-2) + '-' + ('0' + dtparts[2]).substr(-2);
  204. }
  205. }
  206. }
  207. if (parts[1]) {
  208. parts.shift();
  209. let time = parts.join(' ');
  210. result.time = parseTime(time, pmDesignator);
  211. }
  212. return result;
  213. }
  214. function parseHead(head, rights) {
  215. let space = (rights > 0);
  216. let count = 1;
  217. let from = 0;
  218. let to = 0;
  219. let result = [];
  220. for (let i = 0; i < head.length; i++) {
  221. if (count <= rights) {
  222. // if (head[i] === ' ' && !space) {
  223. if (/\s/.test(head[i]) && !space) {
  224. to = i - 1;
  225. result.push({
  226. from: from,
  227. to: to + 1,
  228. cap: head.substring(from, to + 1)
  229. });
  230. from = to + 2;
  231. count++;
  232. }
  233. space = head[i] === ' ';
  234. } else {
  235. if (!/\s/.test(head[i]) && space) {
  236. to = i - 1;
  237. if (from < to) {
  238. result.push({
  239. from: from,
  240. to: to,
  241. cap: head.substring(from, to)
  242. });
  243. }
  244. from = to + 1;
  245. count++;
  246. }
  247. space = head[i] === ' ';
  248. }
  249. }
  250. to = 1000;
  251. result.push({
  252. from: from,
  253. to: to,
  254. cap: head.substring(from, to)
  255. });
  256. let len = result.length;
  257. for (var i = 0; i < len; i++) {
  258. if (result[i].cap.replace(/\s/g, '').length === 0) {
  259. if (i + 1 < len) {
  260. result[i].to = result[i + 1].to;
  261. result[i].cap = result[i].cap + result[i + 1].cap;
  262. result.splice(i + 1, 1);
  263. len = len - 1;
  264. }
  265. }
  266. }
  267. return result;
  268. }
  269. function findObjectByKey(array, key, value) {
  270. for (let i = 0; i < array.length; i++) {
  271. if (array[i][key] === value) {
  272. return i;
  273. }
  274. }
  275. return -1;
  276. }
  277. function getWmic() {
  278. if (os.type() === 'Windows_NT' && !wmicPath) {
  279. wmicPath = WINDIR + '\\system32\\wbem\\wmic.exe';
  280. if (!fs.existsSync(wmicPath)) {
  281. try {
  282. const wmicPathArray = execSync('WHERE WMIC').toString().split('\r\n');
  283. if (wmicPathArray && wmicPathArray.length) {
  284. wmicPath = wmicPathArray[0];
  285. } else {
  286. wmicPath = 'wmic';
  287. }
  288. } catch (e) {
  289. wmicPath = 'wmic';
  290. }
  291. }
  292. }
  293. return wmicPath;
  294. }
  295. function wmic(command, options) {
  296. options = options || execOptsWin;
  297. return new Promise((resolve) => {
  298. process.nextTick(() => {
  299. try {
  300. exec(WINDIR + '\\system32\\chcp.com 65001 | ' + getWmic() + ' ' + command, options, function (error, stdout) {
  301. resolve(stdout, error);
  302. }).stdin.end();
  303. } catch (e) {
  304. resolve('', e);
  305. }
  306. });
  307. });
  308. }
  309. function getVboxmanage() {
  310. return _windows ? process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH + '\\VBoxManage.exe' + '" ' : 'vboxmanage';
  311. }
  312. function powerShell(cmd) {
  313. let result = '';
  314. return new Promise((resolve) => {
  315. process.nextTick(() => {
  316. try {
  317. const child = spawn('powershell.exe', ['-NoLogo', '-InputFormat', 'Text', '-NoExit', '-ExecutionPolicy', 'Unrestricted', '-Command', '-'], {
  318. stdio: 'pipe',
  319. windowsHide: true,
  320. maxBuffer: 1024 * 20000,
  321. encoding: 'UTF-8',
  322. env: util._extend({}, process.env, { LANG: 'en_US.UTF-8' })
  323. });
  324. if (child && !child.pid) {
  325. child.on('error', function () {
  326. resolve(result);
  327. });
  328. }
  329. if (child && child.pid) {
  330. child.stdout.on('data', function (data) {
  331. result = result + data.toString('utf8');
  332. });
  333. child.stderr.on('data', function () {
  334. child.kill();
  335. resolve(result);
  336. });
  337. child.on('close', function () {
  338. child.kill();
  339. resolve(result);
  340. });
  341. child.on('error', function () {
  342. child.kill();
  343. resolve(result);
  344. });
  345. try {
  346. child.stdin.write(cmd + os.EOL);
  347. child.stdin.write('exit' + os.EOL);
  348. child.stdin.end();
  349. } catch (e) {
  350. child.kill();
  351. resolve(result);
  352. }
  353. } else {
  354. resolve(result);
  355. }
  356. } catch (e) {
  357. resolve(result);
  358. }
  359. });
  360. });
  361. }
  362. function getCodepage() {
  363. if (_windows) {
  364. if (!codepage) {
  365. try {
  366. const stdout = execSync('chcp');
  367. const lines = stdout.toString().split('\r\n');
  368. const parts = lines[0].split(':');
  369. codepage = parts.length > 1 ? parts[1].replace('.', '') : '';
  370. } catch (err) {
  371. codepage = '437';
  372. }
  373. }
  374. return codepage;
  375. }
  376. if (_linux || _darwin || _freebsd || _openbsd || _netbsd) {
  377. if (!codepage) {
  378. try {
  379. const stdout = execSync('echo $LANG');
  380. const lines = stdout.toString().split('\r\n');
  381. const parts = lines[0].split('.');
  382. codepage = parts.length > 1 ? parts[1].trim() : '';
  383. if (!codepage) {
  384. codepage = 'UTF-8';
  385. }
  386. } catch (err) {
  387. codepage = 'UTF-8';
  388. }
  389. }
  390. return codepage;
  391. }
  392. }
  393. function isRaspberry() {
  394. const PI_MODEL_NO = [
  395. 'BCM2708',
  396. 'BCM2709',
  397. 'BCM2710',
  398. 'BCM2835',
  399. 'BCM2837B0'
  400. ];
  401. let cpuinfo = [];
  402. try {
  403. cpuinfo = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).split('\n');
  404. } catch (e) {
  405. return false;
  406. }
  407. const hardware = getValue(cpuinfo, 'hardware');
  408. return (hardware && PI_MODEL_NO.indexOf(hardware) > -1);
  409. }
  410. function isRaspbian() {
  411. let osrelease = [];
  412. try {
  413. osrelease = fs.readFileSync('/etc/os-release', { encoding: 'utf8' }).split('\n');
  414. } catch (e) {
  415. return false;
  416. }
  417. const id = getValue(osrelease, 'id');
  418. return (id && id.indexOf('raspbian') > -1);
  419. }
  420. function execWin(cmd, opts, callback) {
  421. if (!callback) {
  422. callback = opts;
  423. opts = execOptsWin;
  424. }
  425. let newCmd = 'chcp 65001 > nul && cmd /C ' + cmd + ' && chcp ' + codepage + ' > nul';
  426. exec(newCmd, opts, function (error, stdout) {
  427. callback(error, stdout);
  428. });
  429. }
  430. function darwinXcodeExists() {
  431. const cmdLineToolsExists = fs.existsSync('/Library/Developer/CommandLineTools/usr/bin/');
  432. const xcodeAppExists = fs.existsSync('/Applications/Xcode.app/Contents/Developer/Tools');
  433. const xcodeExists = fs.existsSync('/Library/Developer/Xcode/');
  434. return (cmdLineToolsExists || xcodeExists || xcodeAppExists);
  435. }
  436. function nanoSeconds() {
  437. const time = process.hrtime();
  438. if (!Array.isArray(time) || time.length !== 2) {
  439. return 0;
  440. }
  441. return +time[0] * 1e9 + +time[1];
  442. }
  443. function countUniqueLines(lines, startingWith) {
  444. startingWith = startingWith || '';
  445. const uniqueLines = [];
  446. lines.forEach(line => {
  447. if (line.startsWith(startingWith)) {
  448. if (uniqueLines.indexOf(line) === -1) {
  449. uniqueLines.push(line);
  450. }
  451. }
  452. });
  453. return uniqueLines.length;
  454. }
  455. function countLines(lines, startingWith) {
  456. startingWith = startingWith || '';
  457. const uniqueLines = [];
  458. lines.forEach(line => {
  459. if (line.startsWith(startingWith)) {
  460. uniqueLines.push(line);
  461. }
  462. });
  463. return uniqueLines.length;
  464. }
  465. function sanitizeShellString(str) {
  466. const s = str || '';
  467. let result = '';
  468. for (let i = 0; i <= 2000; i++) {
  469. if (!(s[i] === undefined ||
  470. s[i] === '>' ||
  471. s[i] === '<' ||
  472. s[i] === '*' ||
  473. s[i] === '?' ||
  474. s[i] === '[' ||
  475. s[i] === ']' ||
  476. s[i] === '|' ||
  477. s[i] === '˚' ||
  478. s[i] === '$' ||
  479. s[i] === ';' ||
  480. s[i] === '&' ||
  481. s[i] === '(' ||
  482. s[i] === ')' ||
  483. s[i] === ']' ||
  484. s[i] === '#' ||
  485. s[i] === '\\' ||
  486. s[i] === '\t' ||
  487. s[i] === '\n' ||
  488. s[i] === '"')) {
  489. result = result + s[i];
  490. }
  491. }
  492. return result;
  493. }
  494. function isPrototypePolluted() {
  495. const s = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  496. let notPolluted = true;
  497. let st = '';
  498. st.__proto__.replace = stringReplace;
  499. st.__proto__.toLowerCase = stringToLower;
  500. st.__proto__.toString = stringToString;
  501. st.__proto__.substr = stringSubstr;
  502. notPolluted = notPolluted || !(s.length === 62)
  503. const ms = Date.now();
  504. if (typeof ms === 'number' && ms > 1600000000000) {
  505. const l = ms % 100 + 15;
  506. for (let i = 0; i < l; i++) {
  507. const r = Math.random() * 61.99999999 + 1;
  508. const rs = parseInt(Math.floor(r).toString(), 10)
  509. const rs2 = parseInt(r.toString().split('.')[0], 10);
  510. const q = Math.random() * 61.99999999 + 1;
  511. const qs = parseInt(Math.floor(q).toString(), 10)
  512. const qs2 = parseInt(q.toString().split('.')[0], 10);
  513. notPolluted = notPolluted && !(r === q);
  514. notPolluted = notPolluted && rs === rs2 && qs === qs2;
  515. st += s[rs - 1];
  516. }
  517. notPolluted = notPolluted && st.length === l;
  518. // string manipulation
  519. let p = Math.random() * l * 0.9999999999;
  520. let stm = st.substr(0, p) + ' ' + st.substr(p, 2000);
  521. stm.__proto__.replace = stringReplace;
  522. let sto = stm.replace(/ /g, '');
  523. notPolluted = notPolluted && st === sto;
  524. p = Math.random() * l * 0.9999999999;
  525. stm = st.substr(0, p) + '{' + st.substr(p, 2000);
  526. sto = stm.replace(/{/g, '');
  527. notPolluted = notPolluted && st === sto;
  528. p = Math.random() * l * 0.9999999999;
  529. stm = st.substr(0, p) + '*' + st.substr(p, 2000);
  530. sto = stm.replace(/\*/g, '');
  531. notPolluted = notPolluted && st === sto;
  532. p = Math.random() * l * 0.9999999999;
  533. stm = st.substr(0, p) + '$' + st.substr(p, 2000);
  534. sto = stm.replace(/\$/g, '');
  535. notPolluted = notPolluted && st === sto;
  536. // lower
  537. const stl = st.toLowerCase();
  538. notPolluted = notPolluted && (stl.length === l) && stl[l - 1] && !(stl[l])
  539. for (let i = 0; i < l; i++) {
  540. const s1 = st[i];
  541. s1.__proto__.toLowerCase = stringToLower;
  542. const s2 = stl ? stl[i] : '';
  543. const s1l = s1.toLowerCase();
  544. notPolluted = notPolluted && s1l[0] === s2 && s1l[0] && !(s1l[1]);
  545. }
  546. }
  547. return !notPolluted;
  548. }
  549. function hex2bin(hex) {
  550. return ("00000000" + (parseInt(hex, 16)).toString(2)).substr(-8);
  551. }
  552. function decodePiCpuinfo(lines) {
  553. // https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
  554. const oldRevisionCodes = {
  555. '0002': {
  556. type: 'B',
  557. revision: '1.0',
  558. memory: 256,
  559. manufacturer: 'Egoman',
  560. processor: 'BCM2835'
  561. },
  562. '0003': {
  563. type: 'B',
  564. revision: '1.0',
  565. memory: 256,
  566. manufacturer: 'Egoman',
  567. processor: 'BCM2835'
  568. },
  569. '0004': {
  570. type: 'B',
  571. revision: '2.0',
  572. memory: 256,
  573. manufacturer: 'Sony UK',
  574. processor: 'BCM2835'
  575. },
  576. '0005': {
  577. type: 'B',
  578. revision: '2.0',
  579. memory: 256,
  580. manufacturer: 'Qisda',
  581. processor: 'BCM2835'
  582. },
  583. '0006': {
  584. type: 'B',
  585. revision: '2.0',
  586. memory: 256,
  587. manufacturer: 'Egoman',
  588. processor: 'BCM2835'
  589. },
  590. '0007': {
  591. type: 'A',
  592. revision: '2.0',
  593. memory: 256,
  594. manufacturer: 'Egoman',
  595. processor: 'BCM2835'
  596. },
  597. '0008': {
  598. type: 'A',
  599. revision: '2.0',
  600. memory: 256,
  601. manufacturer: 'Sony UK',
  602. processor: 'BCM2835'
  603. },
  604. '0009': {
  605. type: 'A',
  606. revision: '2.0',
  607. memory: 256,
  608. manufacturer: 'Qisda',
  609. processor: 'BCM2835'
  610. },
  611. '000d': {
  612. type: 'B',
  613. revision: '2.0',
  614. memory: 512,
  615. manufacturer: 'Egoman',
  616. processor: 'BCM2835'
  617. },
  618. '000e': {
  619. type: 'B',
  620. revision: '2.0',
  621. memory: 512,
  622. manufacturer: 'Sony UK',
  623. processor: 'BCM2835'
  624. },
  625. '000f': {
  626. type: 'B',
  627. revision: '2.0',
  628. memory: 512,
  629. manufacturer: 'Egoman',
  630. processor: 'BCM2835'
  631. },
  632. '0010': {
  633. type: 'B+',
  634. revision: '1.2',
  635. memory: 512,
  636. manufacturer: 'Sony UK',
  637. processor: 'BCM2835'
  638. },
  639. '0011': {
  640. type: 'CM1',
  641. revision: '1.0',
  642. memory: 512,
  643. manufacturer: 'Sony UK',
  644. processor: 'BCM2835'
  645. },
  646. '0012': {
  647. type: 'A+',
  648. revision: '1.1',
  649. memory: 256,
  650. manufacturer: 'Sony UK',
  651. processor: 'BCM2835'
  652. },
  653. '0013': {
  654. type: 'B+',
  655. revision: '1.2',
  656. memory: 512,
  657. manufacturer: 'Embest',
  658. processor: 'BCM2835'
  659. },
  660. '0014': {
  661. type: 'CM1',
  662. revision: '1.0',
  663. memory: 512,
  664. manufacturer: 'Embest',
  665. processor: 'BCM2835'
  666. },
  667. '0015': {
  668. type: 'A+',
  669. revision: '1.1',
  670. memory: 256,
  671. manufacturer: '512MB Embest',
  672. processor: 'BCM2835'
  673. }
  674. }
  675. const processorList = [
  676. 'BCM2835',
  677. 'BCM2836',
  678. 'BCM2837',
  679. 'BCM2711',
  680. ];
  681. const manufacturerList = [
  682. 'Sony UK',
  683. 'Egoman',
  684. 'Embest',
  685. 'Sony Japan',
  686. 'Embest',
  687. 'Stadium'
  688. ];
  689. const typeList = {
  690. '00': 'A',
  691. '01': 'B',
  692. '02': 'A+',
  693. '03': 'B+',
  694. '04': '2B',
  695. '05': 'Alpha (early prototype)',
  696. '06': 'CM1',
  697. '08': '3B',
  698. '09': 'Zero',
  699. '0a': 'CM3',
  700. '0c': 'Zero W',
  701. '0d': '3B+',
  702. '0e': '3A+',
  703. '0f': 'Internal use only',
  704. '10': 'CM3+',
  705. '11': '4B',
  706. '13': '400',
  707. '14': 'CM4'
  708. };
  709. const revisionCode = getValue(lines, 'revision', ':', true);
  710. const model = getValue(lines, 'model:', ':', true);
  711. const serial = getValue(lines, 'serial', ':', true);
  712. let result = {};
  713. if (oldRevisionCodes.hasOwnProperty(revisionCode)) {
  714. // old revision codes
  715. result = {
  716. model,
  717. serial,
  718. revisionCode,
  719. memory: oldRevisionCodes[revisionCode].memory,
  720. manufacturer: oldRevisionCodes[revisionCode].manufacturer,
  721. processor: oldRevisionCodes[revisionCode].processor,
  722. type: oldRevisionCodes[revisionCode].type,
  723. revision: oldRevisionCodes[revisionCode].revision,
  724. }
  725. } else {
  726. // new revision code
  727. const revision = ('00000000' + getValue(lines, 'revision', ':', true).toLowerCase()).substr(-8);
  728. // const revisionStyleNew = hex2bin(revision.substr(2, 1)).substr(4, 1) === '1';
  729. const memSizeCode = parseInt(hex2bin(revision.substr(2, 1)).substr(5, 3), 2) || 0;
  730. const manufacturer = manufacturerList[parseInt(revision.substr(3, 1), 10)];
  731. const processor = processorList[parseInt(revision.substr(4, 1), 10)];
  732. const typeCode = revision.substr(5, 2);
  733. result = {
  734. model,
  735. serial,
  736. revisionCode,
  737. memory: 256 * Math.pow(2, memSizeCode),
  738. manufacturer,
  739. processor,
  740. type: typeList.hasOwnProperty(typeCode) ? typeList[typeCode] : '',
  741. revision: '1.' + revision.substr(7, 1),
  742. }
  743. }
  744. return result;
  745. }
  746. function noop() { }
  747. exports.toInt = toInt;
  748. exports.execOptsWin = execOptsWin;
  749. exports.getCodepage = getCodepage;
  750. exports.execWin = execWin;
  751. exports.isFunction = isFunction;
  752. exports.unique = unique;
  753. exports.sortByKey = sortByKey;
  754. exports.cores = cores;
  755. exports.getValue = getValue;
  756. exports.decodeEscapeSequence = decodeEscapeSequence;
  757. exports.parseDateTime = parseDateTime;
  758. exports.parseHead = parseHead;
  759. exports.findObjectByKey = findObjectByKey;
  760. exports.getWmic = getWmic;
  761. exports.wmic = wmic;
  762. exports.darwinXcodeExists = darwinXcodeExists;
  763. exports.getVboxmanage = getVboxmanage;
  764. exports.powerShell = powerShell;
  765. exports.nanoSeconds = nanoSeconds;
  766. exports.countUniqueLines = countUniqueLines;
  767. exports.countLines = countLines;
  768. exports.noop = noop;
  769. exports.isRaspberry = isRaspberry;
  770. exports.isRaspbian = isRaspbian;
  771. exports.sanitizeShellString = sanitizeShellString;
  772. exports.isPrototypePolluted = isPrototypePolluted;
  773. exports.decodePiCpuinfo = decodePiCpuinfo;
  774. exports.stringReplace = stringReplace;
  775. exports.stringToLower = stringToLower;
  776. exports.stringToString = stringToString;
  777. exports.stringSubstr = stringSubstr;
  778. exports.stringTrim = stringTrim;