'use strict'; var _ = require('underscore'); var ora = require('ora'); var file = require('./file'); const UNITS_SIZE = [ {unit: 'B', name: 'Bytes', count: 1024}, {unit: 'K', name: 'KBytes', count: 1024}, {unit: 'M', name: 'MBytes', count: 1024}, {unit: 'G', name: 'GBytes', count: -1} ]; const UNITS_TIME = [ {unit: 's', name: 'seconds', count: 60}, {unit: 'm', name: 'minutes', count: 60}, {unit: 'h', name: 'hours', count: 24}, {unit: 'd', name: 'days', count: 7}, {unit: 'w', name: 'weeks', count: 4}, {unit: 'm', name: 'months', count: 12}, {unit: 'y', name: 'years', count: -1} ]; function getUnit(units, v) { for (let i = 0; i < units.length; ++i) { if (units[i].count <= 0 || v < units[i].count) return [v, units[i]]; v /= units[i].count; } } const LANGS = [ {lang: 'bash', ext: '.sh', style: '#'}, {lang: 'c', ext: '.c', style: 'c'}, {lang: 'cpp', ext: '.cpp', style: 'c'}, {lang: 'csharp', ext: '.cs', style: 'c'}, {lang: 'golang', ext: '.go', style: 'c'}, {lang: 'java', ext: '.java', style: 'c'}, {lang: 'javascript', ext: '.js', style: 'c'}, {lang: 'kotlin', ext: '.kt', style: 'c'}, {lang: 'mysql', ext: '.sql', style: '--'}, {lang: 'python', ext: '.py', style: '#'}, {lang: 'python3', ext: '.py', style: '#'}, {lang: 'ruby', ext: '.rb', style: '#'}, {lang: 'scala', ext: '.scala', style: 'c'}, {lang: 'swift', ext: '.swift', style: 'c'} ]; const h = {}; h.KEYS = { user: '../user', stat: '../stat', plugins: '../../plugins', problems: 'problems', problem: p => p.fid + '.' + p.slug + '.' + p.category }; h.prettyState = function(state) { switch (state) { case 'ac': return this.prettyText('', true); case 'notac': return this.prettyText('', false); default: return ' '; } }; h.prettyText = function(text, yesNo) { const chalk = require('./chalk'); const icon = require('./icon'); switch (yesNo) { case true: return chalk.green(icon.yes + text); case false: return chalk.red(icon.no + text); default: return text; } }; h.prettySize = function(n) { const res = getUnit(UNITS_SIZE, n); return res[0].toFixed(2) + res[1].unit; }; h.prettyTime = function(n) { const res = getUnit(UNITS_TIME, n); return res[0].toFixed(0) + ' ' + res[1].name; }; h.prettyLevel = function(level) { const chalk = require('./chalk'); switch (level.toLowerCase().trim()) { case 'easy': return chalk.green(level); case 'medium': return chalk.yellow(level); case 'hard': return chalk.red(level); default: return level; } }; h.levelToName = function(level) { switch (level) { case 1: return 'Easy'; case 2: return 'Medium'; case 3: return 'Hard'; default: return ' '; } }; h.statusToName = function(sc) { switch (sc) { case 10: return 'Accepted'; case 11: return 'Wrong Answer'; case 12: return 'Memory Limit Exceeded'; case 13: return 'Output Limit Exceeded'; case 14: return 'Time Limit Exceeded'; case 15: return 'Runtime Error'; case 16: return 'Internal Error'; case 20: return 'Compile Error'; case 21: return 'Unknown Error'; default: return 'Unknown'; } }; h.langToExt = function(lang) { const res = LANGS.find(x => x.lang === lang); return res ? res.ext : '.raw'; }; h.extToLang = function(fullpath) { const res = LANGS.find(x => fullpath.endsWith(x.ext)); return res ? res.lang : 'unknown'; }; h.langToCommentStyle = function(lang) { const res = LANGS.find(x => x.lang === lang); return (res && res.style === 'c') ? {start: '/*', line: ' *', end: ' */'} : {start: res.style, line: res.style, end: res.style}; }; h.readStdin = function(cb) { const stdin = process.stdin; const bufs = []; console.log('NOTE: to finish the input, press ' + (file.isWindows() ? ' and ' : '')); stdin.on('readable', function() { const data = stdin.read(); if (data) { // windows doesn't treat ctrl-D as EOF if (file.isWindows() && data.toString() === '\x04\r\n') { stdin.emit('end'); } else { bufs.push(data); } } }); stdin.on('end', function() { cb(null, Buffer.concat(bufs).toString()); }); stdin.on('error', cb); }; h.getSetCookieValue = function(resp, key) { const cookies = resp.headers['set-cookie']; if (!cookies) return null; for (let i = 0; i < cookies.length; ++i) { const sections = cookies[i].split(';'); for (let j = 0; j < sections.length; ++j) { const kv = sections[j].trim().split('='); if (kv[0] === key) return kv[1]; } } return null; }; h.printSafeHTTP = function(msg) { return msg.replace(/(Cookie\s*:\s*)'.*?'/, '$1') .replace(/('X-CSRFToken'\s*:\s*)'.*?'/, '$1') .replace(/('set-cookie'\s*:\s*)\[.*?\]/, '$1'); }; h.spin = function(s) { return ora(require('./chalk').gray(s)).start(); }; const COLORS = { blue: {fg: 'white', bg: 'bgBlue'}, cyan: {fg: 'white', bg: 'bgCyan'}, gray: {fg: 'white', bg: 'bgGray'}, green: {fg: 'black', bg: 'bgGreen'}, magenta: {fg: 'white', bg: 'bgMagenta'}, red: {fg: 'white', bg: 'bgRed'}, yellow: {fg: 'black', bg: 'bgYellow'}, white: {fg: 'black', bg: 'bgWhite'} }; h.badge = function(s, color) { s = ' ' + s + ' '; if (color === 'random') color = _.chain(COLORS).keys().sample().value(); const c = COLORS[color || 'blue']; const chalk = require('./chalk'); return chalk[c.fg][c.bg](s); }; module.exports = h;