...
 
Commits (588)
<p>&copy; <?xjs write(system.name + ", " + strftime("%Y")); ?></p>
<div class="modal" id="popUpModal" tabindex="-1" role="dialog" style="display:none;">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="popUpModalTitle">Pop-Up Thingie</h4>
</div>
<div class="modal-body" id="popUpModalBody"></div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="popUpModalCloseButton"><? write(locale.strings.main.button_close); ?></button>
<button type="button" class="btn btn-primary" id="popUpModalActionButton" hidden><? write(locale.strings.main.button_submit); ?></button>
</div>
</div>
</div>
</div>
\ No newline at end of file
<?xjs function subMenu(obj, title, path) { ?>
<li class="dropdown<?xjs if (path.match(/\//g).length > 1) write('-submenu'); ?>">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<? write(title.replace(/^.*\-/, '')); ?>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<?xjs menu(obj.list, path); ?>
</ul>
</li>
<?xjs } ?>
<?xjs
function menu(obj, path) {
Object.keys(obj).forEach(function (e) {
if (obj[e].type == 'list') {
subMenu(obj[e], e, (path || '') + e + '/');
} else {
?>
<li>
<?xjs if (obj[e].type == 'link') { ?>
<a class="dropdown-item" href="./?page=<?xjs write(obj[e].page); ?>" target="_blank">
<?xjs } else { ?>
<a class="dropdown-item" href="./?page=<?xjs write((path || '') + obj[e].page); ?>">
<?xjs } ?>
<? write(e); ?>
</a>
</li>
<?xjs
}
});
}
?>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container<?xjs if (settings.layout_full_width) write('-fluid'); ?>">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only"><? write(locale.strings.main.label_sidebar); ?></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="./"><? write(settings.brand || system.name); ?></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<?xjs menu(getPageList(settings.web_pages)); ?>
</ul>
<ul class="nav navbar-nav navbar-right">
<?xjs if (user.alias === settings.guest || user.number < 1) { ?>
<?xjs if (settings.user_registration) { ?>
<li>
<a href="./?page=000-register.xjs"><? write(locale.strings.main.menu_item_register); ?></a>
</li>
<?xjs } ?>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<? write(locale.strings.main.menu_item_login); ?>
<span class="caret"></span>
</a>
<div id="login-form" class="dropdown-menu" style="padding:15px; padding-bottom:0px;">
<form id="form-login">
<label for="input-username" class="sr-only"><? write(locale.strings.main.input_username); ?></label>
<input id="input-username" title="<? write(locale.strings.main.input_username); ?>" type="text" class="dropdown form-control" placeholder="<? write(locale.strings.main.input_username); ?>">
<label for="input-password" class="sr-only"><? write(locale.strings.main.input_password); ?></label>
<input id="input-password" title="<? write(locale.strings.main.input_password); ?>" type="password" class="dropdown form-control" placeholder="<? write(locale.strings.main.input_password); ?>">
<input id="button-login" class="dropdown btn btn-primary" type="submit" value="<? write(locale.strings.main.button_login); ?>">
</form>
</div>
</li>
<?xjs } else { ?>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<? write(user.alias); ?>
<span class="badge scanned" title="Unread mail" id="badge-unread-mail"></span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>
<a href="./?page=000-mail.xjs">
<? write(locale.strings.main.menu_item_mail); ?>
<span class="badge scanned" title="<?xjs write(locale.strings.main.label_unread_mail); ?>" id="badge-unread-mail-inner"></span>
</a>
</li>
<li>
<a id="button-logout" href="#"><? write(locale.strings.main.menu_item_logout); ?></a>
</li>
</ul>
</li>
<?xjs } ?>
</ul>
</div>
</div>
</nav>
\ No newline at end of file
require('sbbsdefs.js', 'SYS_CLOSED');
function randomString(length) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split("");
var str = '';
for (var i = 0; i < length; i++) {
str += chars[Math.floor(Math.random() * chars.length)];
}
return str;
}
function getSession(un) {
var fn = format('%suser/%04d.web', system.data_dir, un);
if (!file_exists(fn)) return false;
var f = new File(fn);
if (!f.open('r')) return false;
var session = f.iniGetObject();
f.close();
return session;
}
function getSessionValue(un, key) {
var session = getSession(un);
if (!session || typeof session[key] === 'undefined') return null;
return session[key];
}
function setSessionValue(un, key, value) {
var fn = format('%suser/%04d.web', system.data_dir, un);
var f = new File(fn);
f.open(f.exists ? 'r+' : 'w+');
f.iniSetValue(null, key, value);
f.close();
}
function setCookie(usr, sessionKey) {
if (usr instanceof User && usr.number > 0) {
set_cookie(
'synchronet',
usr.number + ',' + sessionKey,
(time() + settings.timeout),
http_request.host.replace(/\:\d*/g, ''),
'/'
);
setSessionValue(usr.number, 'key', sessionKey);
}
}
function validateSession(cookies) {
var usr = new User(0);
for (var c in cookies) {
if (cookies[c].search(/^\d+,\w+$/) < 0) continue;
var cookie = cookies[c].split(',');
try {
usr.number = cookie[0];
if (usr.number < 1) {
throw 'Invalid user number ' + cookie[0] + ' in cookie.';
}
} catch (err) {
log(LOG_DEBUG, err);
continue;
}
var session = getSession(usr.number);
if (typeof session !== 'object') continue;
if (typeof session.key != 'string' || session.key != cookie[1]) {
continue;
}
var _usr = authenticate(usr.alias, usr.security.password, false);
_usr = undefined;
setCookie(usr, session.key);
setSessionValue(usr.number, 'ip_address', client.ip_address);
if (session.session_start === undefined || time() - parseInt(session.session_start, 10) > settings.timeout) {
setSessionValue(usr.number, 'session_start', time());
if(!usr.is_sysop || (system.settings&SYS_SYSSTAT)) {
const logonlist_lib = load({}, 'logonlist_lib.js');
logonlist_lib.add({ node: 'Web' });
}
}
break;
}
usr = undefined;
}
function destroySession(cookies) {
var usr = new User(0);
for (var c in cookies) {
if (cookies[c].search(/^\d+,\w+$/) < 0) continue;
var cookie = cookies[c].split(',');
try {
usr.number = cookie[0];
if(usr.number < 1) {
throw 'Invalid user number ' + cookie[0] + ' in cookie.';
}
var session = getSession(usr.number);
if (typeof session !== 'object') {
throw 'Invalid session for user #' + usr.number;
}
if (session.key !== cookie[1]) {
throw 'Invalid session key for user #' + user.number;
}
set_cookie(
'synchronet',
usr.number + ',' + session.key,
(time() - settings.timeout),
http_request.host.replace(/\:\d*/g, ''),
'/'
);
var fn = format('%suser/%04d.web', system.data_dir, usr.number);
file_remove(fn);
break;
} catch (err) {
log(LOG_DEBUG,
'Error destroying session: ' + err + ', cookie: ' + cookies[c]
);
}
}
usr = undefined;
}
function authenticate(alias, password, inc_logons) {
var un = system.matchuser(alias);
if (un < 1) return false;
var usr = new User(un);
if (usr.settings&USER_DELETED) return false;
if (!login(usr.alias, password, inc_logons)) return false;
return usr;
}
function is_user() {
return user.number > 0 && user.alias != settings.guest;
}
(function () {
// If someone is trying to log in
if (http_request.query.username !== undefined &&
http_request.query.username[0].length <= LEN_ALIAS &&
http_request.query.password !== undefined &&
http_request.query.password[0].length <= LEN_PASS
) {
var usr = authenticate(
http_request.query.username[0],
http_request.query.password[0],
true
);
if (usr instanceof User) {
destroySession(http_request.cookie.synchronet || {});
setCookie(usr, randomString(512));
}
usr = undefined;
// If they have a cookie
} else if (
http_request.cookie.synchronet !== undefined &&
http_request.cookie.synchronet.some(function (e) {
return(e.search(/^\d+,\w+$/) != -1);
})
) {
// Verify & update their session, or log them out if requested
if (typeof http_request.query.logout === 'undefined') {
validateSession(http_request.cookie.synchronet);
} else {
destroySession(http_request.cookie.synchronet);
}
}
// If they haven't authenticated as an actual user yet
if (user.number === 0) {
// Try to log them in as the guest user
var gn = system.matchuser(settings.guest);
if (gn > 0) {
var gu = new User(gn);
login(gu.alias, gu.security.password);
gu = undefined;
} else {
// Otherwise just kill the script, for security's sake
exit();
}
}
})();
var avatar_lib = load({}, 'avatar_lib.js');
function Avatars() {
const cache = { local : {}, network : {} };
this.__defineGetter__('cache', function () { return cache; });
this.get_localuser = function (usernumber) {
if (typeof cache.local[usernumber] == 'undefined') {
var data = avatar_lib.read_localuser(usernumber);
if (!data || data.disabled) {
cache.local[usernumber] = false;
} else {
cache.local[usernumber] = data.data;
}
} else {
return cache.local[usernumber];
}
}
this.get_netuser = function (username, netaddr) {
if (typeof cache.network[netaddr] == 'undefined') {
cache.network[netaddr] = {};
}
if (typeof cache.network[netaddr][username] == 'undefined') {
var data = avatar_lib.read_netuser(username, netaddr);
if (!data || data.disabled) {
cache.network[netaddr][username] = false;
} else {
cache.network[netaddr][username] = data.data;
}
} else {
return cache.network[netaddr][username];
}
}
}
load(settings.web_lib + 'forum.js');
var last_subs;
var last_groups;
var last_threads;
var last_run = 0;
const frequency = (settings.refresh_interval || 60000) / 1000;
// Where 'a' is the previous data and 'b' is new
function shallow_diff(a, b) {
const ret = {};
Object.keys(a).forEach(function (e) {
if (typeof b[e] == 'undefined') {
ret[e] = b[e];
} else if (a[e].scanned != b[e].scanned || a[e].total != b[e].total) {
ret[e] = b[e];
}
});
return Object.keys(ret).length ? ret : undefined;
}
function forum_emit(evt, data) {
emit({ event: 'forum', data: JSON.stringify({ type: evt, data: data }) });
}
function scan_groups() {
const scan = getGroupUnreadCounts();
if (!last_groups) {
forum_emit('groups_unread', scan);
} else {
const diff = shallow_diff(last_groups, scan);
if (diff) forum_emit('groups_unread', scan);
}
last_groups = scan;
}
function scan_subs(group) {
const scan = getSubUnreadCounts(group);
if (!last_subs) {
forum_emit('subs_unread', scan);
} else {
const diff = shallow_diff(last_subs, scan);
if (diff) forum_emit('subs_unread', scan);
}
last_subs = scan;
}
function scan_threads(sub, offset, page_size) {
const scan = getThreadStats(sub, offset, page_size);
if (!last_threads) {
forum_emit('threads', scan);
} else {
const ret = Object.keys(scan).reduce(function (a, c) {
if (typeof last_threads[c] == 'undefined') {
a[c] = scan[c];
} else if (scan[c].total != last_threads[c].total) {
a[c] = scan[c];
} else if (scan[c].votes.total != last_threads[c].votes.total) {
a[c] = scan[c];
}
return a;
}, {});
if (Object.keys(ret).length) forum_emit('threads', ret);
}
last_threads = scan;
}
function cycle() {
if (!is_user()) return;
if (time() - last_run <= frequency) return;
last_run = time();
if (Request.has_param('groups_unread')) scan_groups();
if (Request.has_param('subs_unread')) scan_subs(Request.get_param('subs_unread'));
if (Request.has_param('threads')) scan_threads(Request.get_param('threads'), Request.get_param('offset'), Request.get_param('page_size'));
}
this;
var last_run = 0;
var frequency = 30;
var last_count = 0;
function cycle() {
if (user.number < 1 || user.alias == settings.guest) return;
if (time() - last_run <= frequency) return;
last_run = time();
const count = user.stats.mail_waiting;
if (count > 0 || (count == 0 && last_count > 0)) {
emit({ event: 'mail', data: JSON.stringify({ count: count })});
}
last_count = count;
}
this;
var last_run = 0;
var frequency = 15;
const node_state = system.node_list.map(function (e, i) {
return {
status: -1,
action: -1,
aux: -1,
extaux: -1,
useron: -1,
connection : -1
};
});
const web_state = {};
function scan_nodes() {
var change = false;
system.node_list.forEach(function (e, i) {
const n = system.node_list[i];
if (n.status != node_state[i].status
|| n.action != node_state[i].action
|| n.useron != node_state[i].useron
) {
change = true;
const obj = {
status: n.status,
action: n.action,
aux: n.aux,
extaux: n.extaux,
useron: n.useron,
connection: n.connection
};
node_state[i] = obj;
}
});
return change;
}
function scan_web() {
var change = false;
const sessions = directory(system.data_dir + 'user/*.web');
sessions.forEach(function (e) {
const base = file_getname(e).replace(file_getext(e), '');
const un = parseInt(base, 10);
if (isNaN(un) || un < 1 || un > system.lastuser) return;
if (time() - file_date(e) >= settings.inactivity) {
if (web_state[base]) {
delete web_state[base];
change = true;
}
} else {
const action = getSessionValue(un, 'action');
if (web_state[base] != action) {
web_state[base] = action;
change = true;
}
}
});
return change;
}
function scan() {
var out = [];
var usr = new User(1);
const node_change = scan_nodes();
const web_change = scan_web();
if (node_change) {
out = node_state.map(function (e, i) {
if (e.status != 3) {
return {
node: i + 1,
status: null,
action: null,
user: null,
connection: ''
};
} else {
usr.number = e.useron;
return {
node: i + 1,
status: format(NodeStatus[e.status], e.aux, e.extaux),
action: format(NodeAction[e.action], e.aux, e.extaux),
user: usr.alias,
connection : NodeConnectionProper[e.connection] ? NodeConnectionProper[e.connection] : (e.connection + ' bps')
};
}
});
}
if (node_change || web_change) {
out = out.concat(Object.keys(web_state).map(function (e) {
usr.number = parseInt(e, 10);
return {
node: 'W',
action: locale.strings.sidebar_node_list.label_status_web + ' ' + web_state[e],
user: usr.alias,
connection: 'Web'
};
}));
}
usr = undefined;
return out;
}
function cycle() {
if (time() - last_run <= frequency) return;
last_run = time();
const data = scan();
if (data.length) emit({ event: 'nodelist', data: JSON.stringify(data) });
}
this;
const sbbsimsg = load({}, "sbbsimsg_lib.js");
var last_run = 0;
const frequency = 60;
const timeout = 2500;
function list() {
const state = {};
sbbsimsg.read_sys_list();
var sent = sbbsimsg.request_active_users();
sbbsimsg.poll_systems(sent, 0.25, timeout, function () { });
for (var i in sbbsimsg.sys_list) {
var sys = sbbsimsg.sys_list[i];
if (sys.users.length) {
state[sys.name] = { host: sys.host, users: sys.users };
}
}
emit({ event: 'sbbsimsg', data: JSON.stringify(state) });
}
function cycle() {
if (time() - last_run <= frequency) return;
last_run = time();
// list();
}
this;
var last_run = 0;
var frequency = 15;
function cycle() {
if (user.alias === settings.guest) return;
if (time() - last_run <= frequency) return;
last_run = time();
const tg = system.get_telegram(user.number);
if (tg !== null) emit({ event: 'telegram'
, data: JSON.stringify(html_encode(tg.replace('\7', '').replace(/\1./g, '')
, /* ex-ascii */true
, /* white-space */false
, /* ansi */false
, /* ctrl_a */false))
});
}
this;
require('filebase.js', 'FileBase');
require('file_size.js', 'file_size_str');
function count_files(dir) {
var n = 0;
const fn = format("%s%s.ixb", file_area.dir[dir].data_dir, dir);
if (!file_exists(fn)) return n;
return Math.floor(file_size(fn) / 22); // ixb record length is 22 bytes
}
function listLibraries() {
return file_area.lib_list.filter(function (library) {
return library.dir_list.length >= 1;
});
}
function listDirectories(library) {
var dirs = [];
file_area.lib_list[library].dir_list.forEach(function (dir) {
const fc = count_files(dir.code);
if (fc < 1) return;
dirs.push({ dir: dir, fileCount: fc });
});
return dirs;
}
function listFiles(dir) {
return (new FileBase(file_area.dir[dir].code)).map(function (df) {
df.size = df.path ? file_size_str(file_size(df.path)) : 'Unknown';
df._size = df.path ? file_size(df.path) : 0;
return df;
});
}
This diff is collapsed.
require('http.js', 'HTTPRequest');
function get_splash() {
var DefaultSplash = 'G1swbQ0KG1syOEMbWzE7MzBtICAgG1swbRtbMTlDG1szNG3cG1sxbdwbWzBtICAgG1szNG3cDQobWzM3bRtbMTNDG1sxbSAbWzMzbSAbWzBtG1sxM0MbWzM0bdwbWzM3bSAgG1szNG3c3LAbWzQ0OzMwbbIbWzQwOzM3bRtbMTFDG1szNG0gIBtbMW3c3xtbMG0bWzlDG1sxOzMwbWdqL9rkDQobWzBtG1s2QxtbMW1zeW5jaHJvbmV0G1swbSAgIBtbMTszMG3c3BtbMG0gG1sxOzMwbd8bWzBtICAgG1szNG3+G1szN20bWzVDG1szNG0gIN+y29zcG1szN20gICAbWzM0bdzcICAgG1sxbd4bWzA7MzRt3Q0KG1szN20bWzdDG1szNG3cG1szN20gG1szNG3+G1szN20gICAg3NzcG1sxbbGxsBtbMG0gICAgG1szNG3c3Nzc2xtbMTs0NG3cICD+G1swOzM0bdvc3tsbWzQ0OzMwbbAbWzQwOzM0bbLfIN4bWzE7NDRtsLAbWzA7MzRtsbDcG1sxbdwbWzQ2bbIbWzA7MzRtIBtbMzdt3xtbMTszMG3fG1swbdsbWzE7NDdt3Nzc3NwbWzBtsiAgIBtbMzRt3xtbMzdtICAbWzM0bd/f3NwNChtbMzdtICAgIBtbMTszNG3cG1swOzM0bd8bWzM3bSAgINwbWzFt3BtbNDdt3BtbNDBt29sbWzQ3bdvb27EbWzQwbbAbWzBtICAbWzM0bdwbWzE7NDRt3NwbWzQwbdvf3xtbMDszNG3fG1szN20g3NzcIBtbMzRt3BtbMTs0NG2wG1swOzM0bdvfG1szN20g3NzcIBtbMzRt3htbMTs0NG2yG1swOzM0bdwbWzQ0OzMybbAbWzQ2OzM0bbIbWzE7NDBt398bWzA7MzRt3xtbMzZtIBtbMzdtICAbWzE7NDc7MzBt3BtbMzdtstvb2xtbNDBtsRtbMG0gINzc3Nzc3CAbWzE7MzRtsN0NChtbMG0gIBtbMTszNG0g3htbMDszNG3dG1szN20gICAbWzFtsBtbNDdtstvb29/f29uyG1swbd0gG1sxOzM0bbEbWzQ2bbIbWzQ3bbIbWzQ2bbIbWzQwbbIbWzBtIBtbMTs0N23e29vbG1s0MG2xG1swbSAbWzE7MzRt3BtbNDRtshtbMDszNG3fG1szN23cG1sxOzQ3bbCx29uyG1swbd0gG1s0NjszNG3cG1sxOzQwbd8bWzBtIBtbMTszMG3cG1swbdwbWzE7NDdtsLCwsLAbWzBt3NsbWzE7NDdtstvbshtbNDBtsBtbMG0g2xtbMTs0N23b27AbWzBtIBtbMzRt3N8bWzFt39zcG1swOzM0bdwNChtbMzdtICAgIBtbNDY7MzBtshtbNDA7MzRtICAbWzE7MzBt3htbNDc7MzdtsbLb29wbWzBt3CDfG1sxOzQ3bd/fG1swbdvcIBtbMTszNG3f3xtbMDszNG0gG1sxbbEbWzBtIBtbMTs0N23e29sbWzQwbbIbWzBt3RtbMTszNG3eG1s0Nm2yG1swbSAbWzE7MzBt3BtbMG2y3xtbMTs0N22xstvbG1s0MG2xG1swbSAg3BtbMTs0N22wsbKysrKysrEbWzBtIBtbMTs0NzszMG2wG1szN23b29sbWzQwbbEbWzBtIN4bWzE7NDdt3tuyG1swbd0bWzM0bd8bWzE7NDRtsBtbNDBt2xtbNDdtsrIbWzQwbbEbWzA7MzRtsrEbWzM3bSAbWzM0bbANCiAgG1sxbSAbWzA7MzRt3NwbWzE7NDRtsBtbMDszNG3cG1szN20gG1sxOzMwbd8bWzBt3xtbMTs0N23f39vb3BtbMG3cICAbWzE7MzBt3BtbMG3c3NwbWzFtsBtbMzBt3RtbMzRtsBtbMG0gG1sxOzQ3bd7b2xtbNDBtsbAbWzBt3BtbMzZt3xtbMzdtICAbWzM0bdwbWzM3bSCwG1sxOzQ3bbLbsrAbWzBtIBtbMW2wG1s0N22xstvb39vb2xtbNDBtshtbMG3dIBtbMTszMG3eG1s0NzszN22x29uxG1swbdzc2xtbMTs0N23b2xtbNDBtstzcG1swbdwbWzFt3BtbMG3c3CDcIBtbMTszNG2wG1swOzQ0OzMwbbIbWzBtDQobWzM0bSAg2xtbMTs0NG2wshtbMDszNG0gG1sxOzQ0bbEbWzQwbbEbWzA7NDY7MzRtshtbNDBt3NwbWzM3bSDf3xtbMTs0N23f39wbWzBt3CAbWzE7NDdtsdvb2xtbMG3dIBtbMTszMG3eG1s0NzszN23e29sbWzQwbbCyG1s0N23b29wbWzQwbdwbWzBt3BtbMzRtIBtbMTszN20gG1s0N22ysrEgG1s0MDszMG3eG1s0NzszN22xstvbG1swbd8gG1sxbbAbWzQ3bdvb3RtbMG0gG1szNG3+IBtbMTszN22wG1s0N22y29vb29vb27KxG1swbSAbWzM0bdwbWzFt3BtbMDszNm3cG1sxOzM0bdwbWzA7MzRt3NwbWzFt3BtbMDszNG3fDQog3htbNDQ7MzZtsBtbNDY7MzRtshtbMTs0MG3d3t/fG1swbSDc3NwgG1szNG3cG1szN20g3tsbWzE7NDdt3BtbMG3bG1sxbbEbWzQ3bbLb29wbWzBt3N4bWzE7NDdt29uyG1swbd0bWzE7NDdtsbLb29vb3BtbMG3cG1sxOzQ3bbKxsBtbMG3bG1sxOzMwbd4bWzQ3OzM3bbCy27EbWzBtIBtbMzRtINwbWzE7MzBt3xtbMG3fG1sxbd/fG1szMG0gG1swbSDeG1sxOzQ3bbCysRtbMG3dICDbG1sxOzQ3bbKyshtbMG3dIBtbMzRt3xtbMW3f3BtbNDZtshtbMG0NChtbMzRtICDfG1sxbdsbWzQ2bd+yG1s0MG3dG1swbbAbWzQ3OzMwbbAbWzQwOzM3bdsbWzFtsRtbMG3c3NzcG1sxOzQ3bSAbWzQwbbGxG1s0N20gG1swbdwbWzE7NDc7MzBt3BtbNDA7Mzdt3xtbNDdt39/b29vbsRtbMG0gG1sxOzQ3bbCxsbAbWzBtIBtbMW3f2xtbNDdt29uysBtbMG3bIBtbMTs0NzszMG3cG1szN22wsbAbWzBt29wgG1szNG3f3xtbMzdtINyxG1sxOzMwbd0bWzBtINsbWzE7NDdtsbEbWzBt3RtbMzRt3twbWzM3bd4bWzE7NDdtsbGxG1swbdsgG1sxOzQ0OzM2bbAbWzQwOzM0bd/fDQobWzBtG1s1QxtbMTszNG0gG1swOzM0bSAbWzM3bbAbWzQ3OzMwbbAbWzQwOzM3bdvb2xtbMTs0N23bsrGwsCAbWzBt29vbG1sxOzQ3OzMwbd8bWzQwbdwbWzBtIN4bWzE7NDdtsrKyG1swbd3e2xtbMTs0N22wsBtbMG3b3SAgG1sxbd/bG1s0N23bsbAbWzBt3SDfG1sxOzQ3bSAbWzQwbbGxG1s0N20g3BtbMG3bG1sxOzQ3bf4bWzBt29uyG1sxbd0bWzA7MzRt3BtbMzdt3htbMTs0N22wG1swbdsbWzFt3RtbMzRt3htbMDs0NDszNm2wG1s0MDszN23eG1sxOzQ3bbCwsBtbMG3bG1sxbd0bWzA7MzZt3t0NChtbMzdtICAgIBtbMzZtsBtbNDY7MzBtshtbNDA7MzdtICAbWzFt3xtbNDdt3NzcG1s0MG2yG1swbd3f39/fIBtbMTszNG3c3BtbMDszNG3c3BtbMzdtINsbWzE7NDdtsLCwG1swbSAbWzFt39/fG1s0N23c3NwbWzQwbd0bWzA7MzRt3xtbMW3cG1swbSAbWzFt3xtbNDdtsrEbWzQwbbEbWzBt3CAbWzM0bdwbWzM3bSDf39vbG1s0NzszMG2wG1s0MDszN22yG1sxbd/fG1swbSAg3tsbWzFt3xtbMDszNG0gG1s0NDszNm2yG1s0MDszN20gG1sxbbAbWzBt29sbWzQ3OzMwbbAbWzE7NDA7MzdtsRtbMG0gG1sxOzM2bd8NChtbMG0bWzZDG1szNm3fG1szN20gIBtbMzZt3BtbMzdtICAbWzM2bdzcG1sxbdwbWzA7MzZt39/bG1sxbbEbWzQ0bbAbWzA7NDQ7MzZtsBtbNDA7MzRtst8bWzM3bd4bWzE7NDc7MzNtIBtbMG3bG1sxOzQ3OzMzbbAbWzQwbd0bWzMwbbAbWzBtsBtbNDc7MzBtshtbNDA7MzdtICAbWzM0bdwbWzM3bSAbWzFt3xtbMG0gG1sxOzM2bbAbWzQ2OzM0bd8bWzQwbdzcG1swbSAbWzFt39/f3NwbWzBtIBtbMzRt3yDc3NwgG1szN20gG1szNG0gG1sxOzM3bdwbWzBt3xtbMW3fG1swbSAbWzE7MzRt3htbMG0g39/fG1sxbd/fDQobWzBtG1sxM0MbWzM0bSAbWzM3bSAgG1szNG2wG1szN20gG1szNG2wG1s0NDszMG2yG1s0MDszN20gIBtbMW3cG1s0N23cG1szM23c27LbG1s0MDszN23b29sbWzMzbd8bWzBtIBtbMzRtICDf3xtbNDQ7MzZtIN/fsBtbNDA7MzRt2xtbMW3f3BtbMG0bWzVD/iAgICDfG1s1QxtbMzRtIP4NChtbMzdtG1syNkMbWzE7MzNt3Nvb3xtbMG0bWzEyQxtbMzRtIN4bWzFt3bAbWzA7NDQ7MzBtshtbNDA7MzdtIBtbMTszMG0gIBtbMzNtYmJzG1swbSBzb2Z0d2FyZQ0KG1syNUMbWzE7MzNt3NsbWzM3bd8bWzBtG1sxMkMbWzM0bdwbWzM3bSAgG1szNG3fDQobWzM3bRtbMjRDG1sxOzM2bdwbWzM3bdsbWzMzbdzcDQobWzBtG1syNUMbWzE7MzNt3N8NChtbMG0bWzI1QxtbMTszM23dDQo=';
if (settings && settings.ftelnet_splash) {
var f = new File(settings.ftelnet_splash);
f.open('rb');
var splash = base64_encode(f.read());
f.close();
return splash || DefaultSplash;
} else {
return DefaultSplash;
}
}
function get_variant() {
if (!settings) return 'norip.noxfer';
return (settings.ftelnet_rip ? 'rip' : 'norip') + '.' + (settings.ftelnet_xfer ? 'xfer' : 'noxfer');
}
function get_cached_url(f) {
if (f.open('r')) {
const ret = f.read();
f.close();
return ret;
}
return 'http://embed-v2.ftelnet.ca/js/ftelnet-loader.' + get_variant() + '.js?v=2018-09-14';
}
function get_url() {
const f = new File(system.temp_dir + 'ftelnet.url');
if (!f.exists || time() - f.date > 86400) {
try {
var str = (new HTTPRequest()).Get('http://embed-v2.ftelnet.ca/js/ftelnet-loader.' + get_variant() + '.js?v=' + (new Date()).getTime());
} catch (err) {
log(LOG_ERR, 'Failed to fetch fTelnet URL');
str = '';
}
const match = str.match(/^.+\ssrc="(.*)"\s.+/);
if (match !== null) {
if (f.open('w')) {
f.write(match[1]);
f.close();
}
return match[1];
}
}
return get_cached_url(f);
}
require('sbbsdefs.js', 'SYS_CLOSED');
// Paths
settings.web_directory = fullpath(
backslash(
typeof settings.web_directory === 'undefined'
? '../web'
: settings.web_directory
)
);
settings.web_root = fullpath(
backslash(
typeof settings.web_root === 'undefined'
? settings.web_directory + 'root'
: settings.web_root
)
);
settings.web_lib = backslash(settings.web_directory + 'lib/');
settings.web_components = backslash(settings.web_directory + 'components/');
settings.web_pages = backslash(fullpath(settings.web_root + '../pages'));
settings.web_sidebar = backslash(fullpath(settings.web_root + '../sidebar'));
var defaults = {
guest : {
default : 'Guest',
test : function () {
return system.matchuser(settings.guest) ? null : 'Guest account unavailable';
}
},
timeout : { default : 43200 },
user_registration : { default : false },
minimum_password_length : { default : 4 },
email_validation : { default : true },
email_validation_level : { default : 50 },
max_messages : {
default : 0,
test : function () {
return settings.max_messages >= 0 ? null : 'max_messages must be >= 0';
}
},
page_size : {
default : 25,
test : function () {
return settings.page_size >= 1 ? null : 'page_size must be >= 1';
}
},
forum_extended_ascii : { default : true },
active_node_list : { default : true },
hide_empty_stats : { default : true }
};
Object.keys(defaults).forEach(function (e) {
if (typeof settings[e] == 'undefined') {
settings[e] = defaults[e].default;
} else if (typeof settings[e] != typeof defaults[e].default) {
log(LOG_ERROR, 'Invalid ' + e + ' setting: ' + settings[e]);
exit();
} else if (typeof defaults[e].test == 'function') {
const t = defaults[e].test();
if (t !== null) {
log(LOG_ERROR, t);
exit();
}
}
});
defaults = undefined;
require(settings.web_lib + 'locale.js', 'locale');
if (!settings.locale) {
require(backslash(settings.web_lib + 'locale/') + 'en_us.js', 'Locale');
} else {
require(backslash(settings.web_lib + 'locale/') + settings.locale + '.js', 'Locale');
}
var locale = new Locale();
[page_register]
input_zipcode = Postal code
input_location = Location (City, Province)
placeholder_zipcode = H0H0H0
placeholder_location = City, Province
require(backslash(settings.web_lib + 'locale/') + 'en_us.js', 'EN_US');
function EN_CA() {
EN_US.call(this, 'en_ca');
}
EN_CA.prototype = Object.create(EN_US.prototype);
EN_CA.prototype.constructor = EN_US;
var Locale = EN_CA;
[main]
button_close = Close
button_submit = Submit
button_login = Log in
input_username = Username
input_password = Password
label_sidebar = Sidebar
label_unread_mail = Unread mail
menu_item_login = Log in
menu_item_logout = Log out
menu_item_mail = Mail
menu_item_register = Register
[page_home]
button_ftelnet = Connect via Telnet
[page_mail]
button_post_new = Post a new message
button_select_all = Select all messages
button_delete_selected = Delete selected messages
label_message_from = From
label_message_to = To
label_message_date = on
label_message_subject = Subject
label_tab_inbox = Inbox
label_tab_sent = Sent
[page_register]
title = Register
button_register = Register
label_field_required = Required
input_alias = Username
input_password = Password
input_password_confirm = Confirm password
input_email = Email address
input_name = Real name
input_street_address = Street address
input_zipcode = Zip Code
input_location = Location (City, State)
input_phone = Telephone number
input_birthdate = Birthdate
input_gender = Gender
input_gender_withheld = Withheld
input_gender_male = Male
input_gender_female = Female
input_gender_other = Other
input_registration_password = Registration password
stat_suffix_field_required = required
help_text_required = Fields marked with an asterisk are required. All others can be left blank if you wish.
help_text_minimum_characters = Minimum of %d characters
help_text_maximum_characters = Maximum of %d characters
message_account_created = Your account has been created
placeholder_netmail = pat@m.f
placeholder_name = Pat Androgyne
placeholder_street_address = 123 Any Street
placeholder_zipcode = 92860
placeholder_location = City, State
placeholder_phone = 800-555-5555
[page_files]
title = Files
stat_suffix_file = file
stat_suffix_files = files
stat_suffix_directory = directory
stat_suffix_directories = directories
[page_forum]
title = XJS Test Forum
sub_boards = sub-boards
label_thread_from = By
label_message_from = From
label_message_to = To
label_message_date = on
label_message_subject = Subject
label_thread_latest_reply = Latest reply from
suffix_reply_count = reply
suffix_replies_count = replies
badge_poll = POLL
badge_downvotes = Downvotes - Parent / Thread Total
badge_upvotes = Upvotes - Parent / Thread Total
badge_unread_messages = Unread messages
button_post_message = Post a new message
button_post_poll = Post a new poll
button_scan_new = Include in new message scan
button_scan_you = Include in new message scan (messages to you only)
button_scan_off = Exclude from new message scan
button_thread_first_page = First page
button_thread_back_pages = Jump %s page(s) backward
button_thread_previous_page = Previous page
button_thread_next_page = Next page
button_thread_forward_pages = Jump %s page(s) forward
button_thread_last_page = Last page
[sidebar_node_list]
label_title = Who's Online
label_connection_column = Via
label_node_column = Node
label_send_telegram = Send a telegram
label_status_column = Status
label_status_web = browsing
[sidebar_recent_visitors]
label_title = Recent Visitors
label_location = from
label_connection = via
[sidebar_system_info]
label_title = System Info
label_sysop = Sysop:
label_location = Location:
label_users = Users:
label_nodes = Nodes:
label_uptime = Uptime:
label_calls_total = Calls:
label_calls_today = Calls today:
label_files_total = Files:
label_files_uploaded_today = U/L today:
label_files_downloaded_today = D/L today:
label_messages_total = Messages:
label_messages_posted_today = Posted today:
stat_suffix_files = files
stat_suffix_bytes = bytes
[api_system]
nodelist_action_prefix = viewing
telegram_header_format = Telegram from %s via WWW on %s
[api_register]
log_success = User #%d registered via HTTP
log_bot_attempt = Hidden registration form field filled. Likely a bot. Cancelling registration.
error_failed = Failed to create user record.
error_bad_syspass = Incorrect registration password.
error_invalid_alias = Valid username is required.
error_alias_taken = Username already taken.
error_password_mismatch = Password and confirmation are required, and must match.
error_password_length = Password must be %d to %d characters in length.
error_email_required = Valid email address is required.
error_invalid_email = Invalid email address
error_invalid_name = Valid real name is required.
error_invalid_location = Valid location is required.
error_invalid_street_address = Valid street address and postal code are required
error_invalid_phone = Valid phone number is required.
error_invalid_gender = Sex is required. Heh heh heh.
error_invalid_birthdate = Valid birthdate is required.
function EN_US(name) {
const ini_path = backslash(settings.web_lib + 'locale/') + 'en_us.ini';
if (typeof name == 'string') {
const mod_path = backslash(settings.web_lib + 'locale/') + name + '.ini';
}
var f = new File(ini_path);
f.open('r');
var sections = f.iniGetSections();
f.close();
f = undefined;
const _strings = {};
const strings = {};
sections.forEach(function (e) {
Object.defineProperty(strings, e, {
enumerable: true,
get: function () {
if (_strings[e]) return _strings[e];
var f = new File(ini_path);
f.open('r');
const o = f.iniGetObject(e);
f.close();
if (mod_path) {
f = new File(mod_path);
f.open('r');
const oo = f.iniGetObject(e);
f.close();
if (oo !== null) {
Object.keys(oo).forEach(function (ee) {
o[ee] = oo[ee];
});
}
}
f = undefined;
_strings[e] = o;
return o;
}
});
});
Object.defineProperty(this, 'strings', { value: strings });
var active_section = 'page_main';
Object.defineProperty(this, 'section', {
get: function () {
return active_section;
},
set: function (s) {
active_section = s;
}
});
}
EN_US.prototype.group_numbers = function (n) {
n = n + '';
const d = n.indexOf('.');
return n.substring(0, d > -1 ? d : n.length).split('').reverse().reduce(
function (a, c, i) {
return a + (i > 0 && !(i % 3) ? ',' + c : c);
}, ''
).split('').reverse().join('') + (d > -1 ? n.substring(d) : '');
}
EN_US.prototype.write = function (str, sec) {
write(this.strings[sec || this.section][str]);
}
EN_US.prototype.writef = function (str) {
const args = Array.concat(this.strings[this.section][str], Array.apply(null, arguments).slice(1));
write(format.apply(null, args));
}
var Locale = EN_US;
[main]
button_close = Cerrar
button_submit = Enviar
button_login = Iniciar sesión
input_username = Usuario
input_password = Clave
label_sidebar = Sidebar
label_unread_mail = Ne leídos
menu_item_login = Ingresar
menu_item_logout = Salir
menu_item_mail = Correo
menu_item_register = Registrar
[page_home]
button_ftelnet = Conectar via Telnet
[page_mail]
button_post_new = Escribir un mensaje
button_select_all = Seleccionar todos
button_delete_selected = Eliminar seleccionados
label_message_from = De
label_message_to = Para
label_message_date = el
label_message_subject = Asunto
label_tab_inbox = Entrada
label_tab_sent = Enviados
[page_register]
title = Registrar
button_register = Registrar
label_field_required = Requerido
input_alias = Usuario
input_password = Clave
input_password_confirm = Confirmar clave
input_email = Dirección de Email
input_name = Nombre real
input_street_address = Dirección
input_zipcode = Cod. Postal
input_location = Lugar (Ciudad, Estado)
input_phone = Teléfono
input_birthdate = Nacimiento
input_gender = Genero
input_gender_withheld = Retenido
input_gender_male = Masculino
input_gender_female = Femenino
input_gender_other = Otro
input_registration_password = Clave de registro
stat_suffix_field_required = obligatorio
help_text_required = Campos marcados con asterisco son obligatorios. Todo los demas pueden quedar en blanco si lo desea.
help_text_minimum_characters = Mínimo de %d caracteres
help_text_maximum_characters = Máximo de %d caracteres
message_account_created = Su cuenta ha sido creada
placeholder_netmail = jp@m.f
placeholder_name = Juan Perez
placeholder_street_address = Calle 123
placeholder_zipcode = 92860
placeholder_location = Ciudad, Estado
placeholder_phone = 800-555-5555
[page_files]
title = Archivos
stat_suffix_file = archivo
stat_suffix_files = archivos
stat_suffix_directory = directorio
stat_suffix_directories = directorios
[page_forum]
title = XJS Foros de prueba
sub_boards = sub-boards
label_thread_from = Por
label_message_from = De
label_message_to = Para
label_message_date = el
label_message_subject = Asunto
label_thread_latest_reply = última respuesta de
suffix_reply_count = respuesta
suffix_replies_count = respuestas
badge_poll = ENCUESTA
badge_downvotes = Downvotes - Parent / Thread Total
badge_upvotes = Upvotes - Parent / Thread Total
badge_unread_messages = No leidos
button_post_message = Nuevo mensaje
button_post_poll = Nueva encuesta
button_scan_new = Incluir en escaneo de nuevos mensajes
button_scan_you = Incluir en escaneo de nuevos mensajes (mensajes solo para ud.)
button_scan_off = Excluir del escaneo de nuevos mensajes
button_thread_first_page = First page
button_thread_back_pages = Saltar %s página(s) atras
button_thread_previous_page = Página anterior
button_thread_next_page = Página siguiente
button_thread_forward_pages = Salta %s página(s) adelante
button_thread_last_page = Última página
[sidebar_node_list]
label_title = Quien está en Línea
label_connection_column = Vía
label_node_column = Nodo
label_send_telegram = Enviar Telegram
label_status_column = Estado
label_status_web = navegando
[sidebar_recent_visitors]
label_title = Visitas Recientes
label_location = desde
label_connection = vía
[sidebar_system_info]
label_title = Información el Systema
label_sysop = Sysop:
label_location = Lugar:
label_users = Usuarios:
label_nodes = Nodos:
label_uptime = Uptime:
label_calls_total = Llamadas:
label_calls_today = Llamadas de hoy:
label_files_total = Archivoss:
label_files_uploaded_today = U/L hoy:
label_files_downloaded_today = D/L hoy:
label_messages_total = Mensajes:
label_messages_posted_today = Mensajes hoy:
stat_suffix_files = archivos
stat_suffix_bytes = bytes
[api_system]
nodelist_action_prefix = viendo
telegram_header_format = Telegram de %s vía WWW el %s
[api_register]
log_success = Usuario #%d registrado vía HTTP
log_bot_attempt = Hidden registration form field filled. Likely a bot. Cancelling registration.
error_failed = Error al crear el registro de usuario.
error_bad_syspass = Clave incorrecta.
error_invalid_alias = Usuario es obligatorio.
error_alias_taken = Usuario ya existente.
error_password_mismatch = La clave y confirmación son obligatorios y deben concidir.
error_password_length = La clave debe ser de %d a %d caracteres de longitud.
error_email_required = Dirección de E-mail es obligatoria.
error_invalid_email = Direccion de E-mail inválida.
error_invalid_name = Nombre real es obligatorio.
error_invalid_location = Lugar es obligatorio.
error_invalid_street_address = Direccion y Cod. postal son obligatorios.
error_invalid_phone = Telefono es obligatorio.
error_invalid_gender = Sexo es obligatorio. Heh heh heh.
error_invalid_birthdate = Nacimiento es obligatorio.
/* $Id: mime_decode.ssjs,v 1.22 2009/05/06 21:54:05 deuce Exp $ */
function regex_escape(str)
{
str=str.replace(/([\\\^\$\*\+\?\.\(\)\{\}\[\]])/g,"\\$1");
return(str);
}
function count_attachments(hdr, body)
{
var Message=new Array;
var CT;
var TE;
var attach=0;
if(hdr==undefined || body==undefined || hdr.field_list==undefined)
return(0);
for(head in hdr.field_list) {
if(hdr.field_list[head].data.search(/content-type:/i)!=-1) {
CT=hdr.field_list[head].data;
}
else if(hdr.field_list[head].data.search(/content-transfer-encoding:/i)!=-1) {
TE=hdr.field_list[head].data;
}
}
if(CT==undefined)
return(0);
if(CT.search(/multipart\/[^\s;]*/i)!=-1) {
var bound=CT.match(/;[\s\r\n]*boundary="{0,1}([^";\r\n]*)"{0,1}/i);
if(bound==undefined)
return(attach);
bound[1]=regex_escape(bound[1]);
re=new RegExp ("--"+bound[1]+"-{0,2}","");
msgbits=body.split(re);
/* Search for attachments/inlined */
for(bit in msgbits) {
var pieces=msgbits[bit].split(/\r?\n\r?\n/);
var disp=pieces[0].match(/content-disposition:\s+(?:attachment|inline)[;\s]*filename="?([^";\r\n]*)"?/i);
if(disp!=undefined) {
attach++;
}
}
}
return(attach);
}
function mime_decode(hdr, body, sub)
{
var Message=new Array;
var CT;
var TE;
var undef;
if(hdr==undefined || body==undefined || hdr.field_list==undefined) {
Message.type="plain";
Message.body=decode_body(TE,undef,body);
return(Message);
}
for(head in hdr.field_list) {
if(hdr.field_list[head].data.search(/content-type:/i)!=-1) {
CT=hdr.field_list[head].data;
}
else if(hdr.field_list[head].data.search(/content-transfer-encoding:/i)!=-1) {
TE=hdr.field_list[head].data;
}
}
if(CT==undefined) {
Message.type="plain";
Message.body=decode_body(TE,undef,body);
return(Message);
}
if(CT.search(/multipart\/[^\s;]*/i)!=-1) {
var bound=CT.match(/;[\s\r\n]*boundary="{0,1}([^";\r\n]*)"{0,1}/i);
if(bound!=undefined) {
bound[1]=regex_escape(bound[1]);
re=new RegExp ("--"+bound[1]+"-{0,2}");
msgbits=body.split(re);
/* Search for attachments/inlined */
for(bit in msgbits) {
var pieces=msgbits[bit].split(/\r?\n\r?\n/);
var disp=pieces[0].match(/content-disposition:\s+(?:attachment|inline)[;\s]*filename="?([^";\r\n]*)"?/i);
if(disp!=undefined) {
/* Attachment */
if(Message.attachments==undefined)
Message.attachments=new Array;
Message.attachments.push(disp[1]);
}
disp=pieces[0].match(/content-id:\s+\<?([^\<\>;\r\n]*)\>?/i);
if(disp!=undefined) {
/* Inline Attachment */
if(Message.inlines==undefined)
Message.inlines=new Array;
Message.inlines.push(disp[1]);
}
}
/* Search for HTML encoded bit */
for(bit in msgbits) {
var pieces=msgbits[bit].split(/\r?\n\r?\n/);
var pheads=pieces[0];
if(pheads==undefined)
continue;
var content=pieces.slice(1).join('');
if(content==undefined)
continue;
if(pheads.search(/content-type: text\/html/i)!=-1) {
Message.body=decode_body(TE,pheads,content);
if(Message.inlines!=undefined) {
for(il in Message.inlines) {
var path=http_request.virtual_path;
var basepath=path.match(/^(.*\/)[^\/]*$/);
re=new RegExp("cid:("+regex_escape(Message.inlines[il])+")","ig");
Message.body=Message.body.replace(re,basepath[1]+"api/attachments.ssjs?sub="+sub+"&amp;msg="+hdr.number+"&amp;cid=$1");
}
}
Message.type="html";
return(Message);
}
}
/* Search for plaintext bit */
for(bit in msgbits) {
var pieces=msgbits[bit].split(/\r?\n\r?\n/);
var pheads=pieces[0];
var content=pieces.slice(1).join('');
if(content==undefined)
continue;
if(pheads.search(/content-type: text\/plain/i)!=-1) {
Message.body=decode_body(TE,pheads,content);
Message.type="plain";
return(Message);
}
}
}
}
if(CT.search(/text\/html/i)!=-1) {
Message.type="html";
Message.body=decode_body(TE,undef,body);
return(Message);
}
Message.type="plain";
Message.body=body;
return(Message);
}
function decode_body(TE, heads, body)
{
var tmp;
if(heads!=undefined && heads != "") {
tmp=heads.match(/content-transfer-encoding: ([^;\r\n]*)/i);
if(tmp!=undefined)
tmp=tmp[1];
else {
if(TE!=undefined) {
tmp=TE.match(/content-transfer-encoding: ([^;\r\n]*)/i);
if(tmp!=undefined)
tmp=tmp[1];
}
}
}
else {
if(TE!=undefined) {
tmp=TE.match(/content-transfer-encoding: ([^;\r\n]*)/i);
if(tmp!=undefined)
tmp=tmp[1];
}
else
tmp="";
}
if(tmp==undefined)
tmp="";
if(tmp.search(/quoted-printable/i)!=-1) {
body=body.replace(/\=(\r{0,1}\n)/g,"$1");
body=body.replace(/\=([A-F0-9]{2})/ig,function (str,p1,offset,s)
{
var i=parseInt(p1,16);
if(i==NaN || i==undefined)
return('='+p1);
return ascii(i);
}
);
return body;
}
if(tmp.search(/base64/i)!=-1) {
body=body.replace(/[^A-Za-z0-9\+\/\=]/g,'');
return base64_decode(body);
}
return