diff --git a/ChangeLog b/ChangeLog index c1c14bd..4cf6bfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -222,7 +222,7 @@ 2009-04-28 Markus Gutschke * Fixed variable expansion in service descriptions. - + 2009-04-27 Markus Gutschke * Released version 2.7 @@ -268,7 +268,7 @@ cursor if the line ends in spaces. * Work-around for an IE6 bug when doing HTTPS through proxies. - + 2009-03-21 Markus Gutschke * Released version 2.5 @@ -374,11 +374,11 @@ * Added CGI mode for demand-loading the shellinaboxd daemon from a web server. This also allows for the web server to perform authentication, instead of having shellinaboxd do so. - + * Tightened setuid-root operation to no longer allow switching to arbitrary users/groups. As before, setuid-root remains a non-standard configuration that is not currently recommended. - + * Fixed session management to deal better with torn down connections. Closed one bug that could have resulted in permanently orphaned connections, when the browser navigated @@ -389,4 +389,3 @@ * First public release of the version 2.0 rewrite. This is the first release of ShellInABox that supports an AJAX interface instead of the original Java applet. - diff --git a/INSTALL b/INSTALL index d3c5b40..200806c 100644 --- a/INSTALL +++ b/INSTALL @@ -234,4 +234,3 @@ an Autoconf bug. Until the bug is fixed you can use this workaround: `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/README.Fedora b/README.Fedora index 018bfc2..21dba69 100644 --- a/README.Fedora +++ b/README.Fedora @@ -29,4 +29,3 @@ some tips on getting things working: Make sure you assign the correct SELinux labels to this file when copying it into "/etc/pam.d": cp -Z system_u:object_r:etc_t:s0 etc-pam.d-shellinabox-example /etc/pam.d/ - diff --git a/TODO b/TODO index 3720980..69819ed 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,3 @@ - Check if there is any way that we could fall back on gnutls if openssl is unavailable - Package for distributions other than Debian - diff --git a/debian/shellinabox.init b/debian/shellinabox.init index 721b480..87d5a2e 100755 --- a/debian/shellinabox.init +++ b/debian/shellinabox.init @@ -8,7 +8,7 @@ # Short-Description: Shell In A Box Daemon # Description: Daemon for publishing a login shell at # http://localhost:SHELLINABOX_PORT -# where default port number is 4200. +# where default port number is 4200. ### END INIT INFO # Authors: Markus Gutschke , Marc Singer diff --git a/debian/source/options b/debian/source/options index 8b13789..e69de29 100644 --- a/debian/source/options +++ b/debian/source/options @@ -1 +0,0 @@ - diff --git a/demo/demo.html b/demo/demo.html index 4ffed56..a6769b6 100644 --- a/demo/demo.html +++ b/demo/demo.html @@ -6,23 +6,23 @@ diff --git a/demo/demo.jspp b/demo/demo.jspp index bc2b1a4..c5f3661 100644 --- a/demo/demo.jspp +++ b/demo/demo.jspp @@ -880,7 +880,7 @@ Demo.prototype.intrinsic = function() { } v = arg1.val().substr(arg1.val().length - v); value = new this.Value(TYPE_STRING, v, v); - break; + break; case 'STR$': value = new this.Value(TYPE_STRING, arg1.toString(), arg1.toString()); @@ -909,7 +909,7 @@ Demo.prototype.intrinsic = function() { v = String.fromCharCode(arg1.val()); value = new this.Value(TYPE_STRING, v, v); break; - case 'SPC': + case 'SPC': if (arg1.val() < 0) { return this.error('Range error'); } @@ -1183,4 +1183,3 @@ Demo.prototype.Value.prototype.val = function() { Demo.prototype.Value.prototype.toString = function() { return this.s; }; - diff --git a/demo/demo.xml b/demo/demo.xml index d8467d9..f17c6d1 100644 --- a/demo/demo.xml +++ b/demo/demo.xml @@ -1,4 +1,4 @@ - + diff --git a/demo/print-styles.css b/demo/print-styles.css index 187dc3f..0b948d2 100644 --- a/demo/print-styles.css +++ b/demo/print-styles.css @@ -28,7 +28,7 @@ margin: 0px; } - #print { + #print { margin: 0px; } diff --git a/demo/styles.css b/demo/styles.css index 37f1135..9beaeb4 100644 --- a/demo/styles.css +++ b/demo/styles.css @@ -1,9 +1,9 @@ -#vt100 a { +#vt100 a { text-decoration: none; color: inherit; } -#vt100 a:hover { +#vt100 a:hover { text-decoration: underline; } @@ -12,7 +12,7 @@ z-index: 2; } -#vt100 #reconnect input { +#vt100 #reconnect input { padding: 1ex; font-weight: bold; font-size: x-large; @@ -29,7 +29,7 @@ z-index: 2; } -#vt100 pre { +#vt100 pre { margin: 0px; } @@ -44,11 +44,11 @@ padding: 1px; } -#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre { +#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre { font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", monospace; } -#vt100 #lineheight { +#vt100 #lineheight { position: absolute; visibility: hidden; } @@ -75,7 +75,7 @@ margin: -1px; } -#vt100 #padding { +#vt100 #padding { visibility: hidden; width: 1px; height: 0px; @@ -90,7 +90,7 @@ height: 0px; } -#vt100 #menu { +#vt100 #menu { overflow: visible; position: absolute; z-index: 3; @@ -103,14 +103,14 @@ position: absolute; } -#vt100 #menu .popup ul { +#vt100 #menu .popup ul { list-style-type: none; padding: 0px; margin: 0px; min-width: 10em; } -#vt100 #menu .popup li { +#vt100 #menu .popup li { padding: 3px 0.5ex 3px 0.5ex; } @@ -123,11 +123,11 @@ color: #AAAAAA; } -#vt100 #menu .popup hr { +#vt100 #menu .popup hr { margin: 0.5ex 0px 0.5ex 0px; } -#vt100 #menu img { +#vt100 #menu img { margin-right: 0.5ex; width: 1ex; height: 1ex; @@ -136,7 +136,7 @@ #vt100 #scrollable.inverted { color: #ffffff; background-color: #000000; } -#vt100 #kbd_button { +#vt100 #kbd_button { float: left; position: fixed; z-index: 0; @@ -198,7 +198,7 @@ visibility: hidden; } -#vt100 #keyboard .shifted { +#vt100 #keyboard .shifted { display: none; } @@ -218,15 +218,15 @@ display: none; } - #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard { + #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard { visibility: hidden; } - #vt100 #scrollable { + #vt100 #scrollable { overflow: hidden; } - #vt100 #console, #vt100 #alt_console { + #vt100 #console, #vt100 #alt_console { overflow: hidden; width: 1000000ex; } diff --git a/libhttp/httpconnection.c b/libhttp/httpconnection.c index cd9601a..1bdc376 100644 --- a/libhttp/httpconnection.c +++ b/libhttp/httpconnection.c @@ -1637,7 +1637,7 @@ int httpHandleConnection(struct ServerConnection *connection, void *http_, } } } - + // If the callback only provided partial data, refill the outgoing // buffer whenever it runs low. if (http->isPartialReply && (!http->msg || http->msgLength <= 0)) { @@ -1664,7 +1664,7 @@ int httpHandleConnection(struct ServerConnection *connection, void *http_, http->msg = NULL; http->msgLength = 0; } - + if ((!(*events || http->isSuspended) || timedOut) && http->sslHndl) { *events = 0; serverSetTimeout(connection, 1); diff --git a/libhttp/httpconnection.h b/libhttp/httpconnection.h index d0207c4..eb503aa 100644 --- a/libhttp/httpconnection.h +++ b/libhttp/httpconnection.h @@ -115,7 +115,7 @@ struct HttpHandler { int (*websocketHandler)(struct HttpConnection *, void *, int, const char *, int); void *arg, *streamingArg; - + }; struct HttpConnection *newHttpConnection(struct Server *server, int fd, diff --git a/libhttp/server.c b/libhttp/server.c index 51c0e60..d7f575b 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -181,7 +181,7 @@ static int serverCollectFullPayload(struct HttpConnection *http, free(payload); } return rc; - + } static int serverCollectHandler(struct HttpConnection *http, void *handler_) { diff --git a/logging/logging.c b/logging/logging.c index 532b8fa..0b81e7b 100644 --- a/logging/logging.c +++ b/logging/logging.c @@ -191,4 +191,3 @@ char *stringPrintfUnchecked(char *buf, const char *fmt, ...) return s; } #endif - diff --git a/shellinabox/cgi_root.html b/shellinabox/cgi_root.html index 0816065..ea487a7 100644 --- a/shellinabox/cgi_root.html +++ b/shellinabox/cgi_root.html @@ -6,23 +6,23 @@ @@ -70,7 +70,7 @@ '\n' + - ''); + ''); })(); --> diff --git a/shellinabox/externalfile.c b/shellinabox/externalfile.c index 332cb4f..fd34e64 100644 --- a/shellinabox/externalfile.c +++ b/shellinabox/externalfile.c @@ -75,7 +75,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, while (*pathInfo == '/') { pathInfo++; } - + // Compute file name of external file char *fn; int s_size = strlen((char *)arg) + @@ -91,7 +91,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, ptr++; } strncat(fn, ptr, s_size); - + // Any files/directories starting with a dot are inaccessible to us do { if (*ptr == '.') { @@ -103,7 +103,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, ptr = strchr(ptr + 1, '/'); } while (ptr); } - + // Open file for reading #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -147,7 +147,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, httpSendReply(http, 404, "File not found", NO_MSG); return HTTP_DONE; } - + // We only serve regular files, and restrict the file size to 100MB. // As a special-case, we also allow access to /dev/null. struct stat sb = { 0 }; @@ -161,7 +161,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, return HTTP_DONE; } free(fn); - + // Set up response header char *response = stringPrintf(NULL, "HTTP/1.1 200 OK\r\n" @@ -180,7 +180,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, } check(response = realloc(response, respLen + dataLen + 1)); bytes = NOINTR(read(fd, response + respLen, dataLen)); - + if (bytes < 0) { free(response); NOINTR(close(fd)); @@ -188,7 +188,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, return HTTP_DONE; } } - + if (bytes < 0 || bytes == sb.st_size) { // Read entire file. Transmit it in one go. httpTransfer(http, response, @@ -199,7 +199,7 @@ static int externalFileHttpHandler(HttpConnection *http, void *arg, // Transmit partial reply and store state for future calls into the // handler. httpTransferPartialReply(http, response, respLen + bytes); - + check(state = malloc(sizeof(struct ExternalFileState))); state->fd = fd; state->totalSize = sb.st_size; diff --git a/shellinabox/launcher.c b/shellinabox/launcher.c index 835969e..9bc5541 100644 --- a/shellinabox/launcher.c +++ b/shellinabox/launcher.c @@ -676,7 +676,7 @@ void destroyUtmp(struct Utmp *utmp) { updwtmpx("/var/log/wtmp", &utmp->utmpx); } #endif - + // Switch back to the lower privileges check(!setresgid(r_gid, e_gid, s_gid)); check(!setresuid(r_uid, e_uid, s_uid)); @@ -1576,7 +1576,7 @@ static void childProcess(struct Service *service, int width, int height, // Change user and group ids check(!setresgid(service->gid, service->gid, service->gid)); check(!setresuid(service->uid, service->uid, service->uid)); - + // Change working directory if (service->useHomeDir) { check(!service->useLogin); diff --git a/shellinabox/print-styles.css b/shellinabox/print-styles.css index 187dc3f..0b948d2 100644 --- a/shellinabox/print-styles.css +++ b/shellinabox/print-styles.css @@ -28,7 +28,7 @@ margin: 0px; } - #print { + #print { margin: 0px; } diff --git a/shellinabox/root_page.html b/shellinabox/root_page.html index 931a205..c9614c2 100644 --- a/shellinabox/root_page.html +++ b/shellinabox/root_page.html @@ -6,23 +6,23 @@ diff --git a/shellinabox/shell_in_a_box.jspp b/shellinabox/shell_in_a_box.jspp index 5b3825a..8de5220 100644 --- a/shellinabox/shell_in_a_box.jspp +++ b/shellinabox/shell_in_a_box.jspp @@ -357,7 +357,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) { } } } - + }; ShellInABox.prototype.about = function() { @@ -373,4 +373,3 @@ ShellInABox.prototype.about = function() { "Eric Young\n(eay@cryptsoft.com)" : "")); }; - diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index ba734e1..eb4f8f7 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -243,7 +243,7 @@ static int completePendingRequest(struct Session *session, data = jsonEscape(buf, len); } } - + char *json = stringPrintf(NULL, "{" "\"session\":\"%s\"," "\"data\":\"%s\"" diff --git a/shellinabox/shellinaboxd.man.in b/shellinabox/shellinaboxd.man.in index c617bbf..b0fca5e 100644 --- a/shellinabox/shellinaboxd.man.in +++ b/shellinabox/shellinaboxd.man.in @@ -199,7 +199,7 @@ In order to be useful as a CGI script, the .B shellinaboxd binary probably will have to be made .BR setuid-root . -This is currently a discouraged configuration. Use with care. +This is currently a discouraged configuration. Use with care. .TP \fB-d\fP\ |\ \fB--debug\fP Enables debugging mode, resulting in lots of log messages on @@ -292,7 +292,7 @@ mode, anything that looks like a hostname, URL or e-mail address is recognized, even if not preceded by a protocol. .TP \fB--localhost-only\fP -Normally, +Normally, .B shellinaboxd listens on all available network interfaces. When operating behind a reverse-proxy that is not always desirable. This command line option @@ -756,7 +756,7 @@ the daemon with \fBsudo service shellinabox restart\fP. .TP .I /etc/shellinabox This directory contains style sheets that will be used for the -.B --user-css +.B --user-css command line option, when running .B shellinaboxd as a system-wide service. diff --git a/shellinabox/styles.css b/shellinabox/styles.css index 3097cb4..5cbb31e 100755 --- a/shellinabox/styles.css +++ b/shellinabox/styles.css @@ -1,9 +1,9 @@ -#vt100 a { +#vt100 a { text-decoration: none; color: inherit; } -#vt100 a:hover { +#vt100 a:hover { text-decoration: underline; } @@ -12,7 +12,7 @@ z-index: 2; } -#vt100 #reconnect input { +#vt100 #reconnect input { padding: 1ex; font-weight: bold; font-size: x-large; @@ -29,7 +29,7 @@ z-index: 2; } -#vt100 pre { +#vt100 pre { margin: 0px; } @@ -44,11 +44,11 @@ padding: 1px; } -#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre { +#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre { font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", monospace; } -#vt100 #lineheight { +#vt100 #lineheight { position: absolute; visibility: hidden; } @@ -75,7 +75,7 @@ margin: -1px; } -#vt100 #padding { +#vt100 #padding { visibility: hidden; width: 1px; height: 0px; @@ -90,7 +90,7 @@ height: 0px; } -#vt100 #menu { +#vt100 #menu { overflow: visible; position: absolute; z-index: 3; @@ -103,14 +103,14 @@ position: absolute; } -#vt100 #menu .popup ul { +#vt100 #menu .popup ul { list-style-type: none; padding: 0px; margin: 0px; min-width: 10em; } -#vt100 #menu .popup li { +#vt100 #menu .popup li { padding: 3px 0.5ex 3px 0.5ex; } @@ -123,11 +123,11 @@ color: #AAAAAA; } -#vt100 #menu .popup hr { +#vt100 #menu .popup hr { margin: 0.5ex 0px 0.5ex 0px; } -#vt100 #menu img { +#vt100 #menu img { margin-right: 0.5ex; width: 1ex; height: 1ex; @@ -136,7 +136,7 @@ #vt100 #scrollable.inverted { color: #ffffff; background-color: #000000; } -#vt100 #kbd_button { +#vt100 #kbd_button { float: left; position: fixed; z-index: 0; @@ -198,7 +198,7 @@ visibility: hidden; } -#vt100 #keyboard .shifted { +#vt100 #keyboard .shifted { display: none; } @@ -257,15 +257,15 @@ display: none; } - #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard { + #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard { visibility: hidden; } - #vt100 #scrollable { + #vt100 #scrollable { overflow: hidden; } - #vt100 #console, #vt100 #alt_console { + #vt100 #console, #vt100 #alt_console { overflow: hidden; width: 1000000ex; } diff --git a/shellinabox/vt100.jspp b/shellinabox/vt100.jspp index f02b3be..6d5a837 100755 --- a/shellinabox/vt100.jspp +++ b/shellinabox/vt100.jspp @@ -363,7 +363,7 @@ VT100.prototype.initializeUserCSSStyles = function() { var label = userCSSList[i][0]; var newGroup = userCSSList[i][1]; var enabled = userCSSList[i][2]; - + // Add user style sheet to document var style = document.createElement('link'); var id = document.createAttribute('id'); @@ -381,7 +381,7 @@ VT100.prototype.initializeUserCSSStyles = function() { document.getElementsByTagName('head')[0].appendChild(style); style.disabled = !enabled; } - + // Add entry to menu if (newGroup || i == userCSSList.length) { if (beginOfGroup != 0 && (i - beginOfGroup > 1 || !wasSingleSel)) { @@ -588,7 +588,7 @@ VT100.prototype.addKeyBinding = function(elem, ch, key, CH, KEY) { this.addListener(elem, 'mousedown', function(vt100, elem, key) { return function(e) { if ((e.which || e.button) == 1) { - if (vt100.lastSelectedKey) { + if (vt100.lastSelectedKey) { vt100.lastSelectedKey.className= ''; } // Highlight the key while the mouse button is held down. @@ -989,7 +989,7 @@ VT100.prototype.initializeElements = function(container) { vt100.indicateSize = true; }; }(this), 100); - this.addListener(window, 'resize', + this.addListener(window, 'resize', function(vt100) { return function() { vt100.hideContextMenu(); @@ -997,7 +997,7 @@ VT100.prototype.initializeElements = function(container) { vt100.showCurrentSize(); } }(this)); - + // Hide extra scrollbars attached to window document.body.style.margin = '0px'; try { document.body.style.overflow ='hidden'; } catch (e) { } @@ -1684,7 +1684,7 @@ VT100.prototype.putString = function(x, y, text, color, style) { this.insertBlankLine(yIdx); } line = console.childNodes[yIdx]; - + // If necessary, promote blank '\n' line to a
tag if (line.tagName != 'DIV') { var div = document.createElement('div'); @@ -1728,7 +1728,7 @@ VT100.prototype.putString = function(x, y, text, color, style) { s += ' '; } while (xPos + s.length < x); } - + // If styles do not match, create a new var del = text.length - s.length + x - xPos; if (oldColor != color || @@ -1787,7 +1787,7 @@ VT100.prototype.putString = function(x, y, text, color, style) { } this.setTextContent(span, s); - + // Delete all subsequent 's that have just been overwritten sibling = span.nextSibling; while (del > 0 && sibling) { @@ -1802,7 +1802,7 @@ VT100.prototype.putString = function(x, y, text, color, style) { break; } } - + // Merge with next sibling, if styles are identical if (sibling && span.className == sibling.className && span.style.cssText == sibling.style.cssText) { @@ -1883,7 +1883,7 @@ VT100.prototype.putString = function(x, y, text, color, style) { this.getTextContent(span)); line.removeChild(sibling); } - + // Prune white space from the end of the current line span = line.lastChild; while (span && @@ -1964,7 +1964,7 @@ VT100.prototype.enableAlternateScreen = function(state) { this.resizer(); return; } - + // We save the full state of the normal screen, when we switch away from it. // But for the alternate screen, no saving is necessary. We always reset // it when we switch to it. @@ -2210,7 +2210,7 @@ VT100.prototype.scrollRegion = function(x, y, w, h, incX, incY, while (console.childNodes.length < this.terminalHeight) { this.insertBlankLine(this.terminalHeight); } - + // Add new lines at bottom in order to force scrolling for (var i = 0; i < y; i++) { this.insertBlankLine(console.childNodes.length, color, style); @@ -2577,7 +2577,7 @@ VT100.prototype.showContextMenu = function(x, y) { this.menu.style.height = this.container.offsetHeight + 'px'; popup.style.left = '0px'; popup.style.top = '0px'; - + var margin = 2; if (x + popup.clientWidth >= this.container.offsetWidth - margin) { x = this.container.offsetWidth-popup.clientWidth - margin - 1; @@ -2665,7 +2665,7 @@ VT100.prototype.handleKey = function(event) { ch = this.applyModifiers(ch, event); // By this point, "ch" is either defined and contains the character code, or - // it is undefined and "key" defines the code of a function key + // it is undefined and "key" defines the code of a function key if (ch != undefined) { this.scrollable.scrollTop = this.numScrollbackLines * this.cursorHeight + 1; @@ -2889,7 +2889,7 @@ VT100.prototype.fixEvent = function(event) { case 61: /* = -> + */ u = 61; s = 43; break; case 91: /* [ -> { */ u = 91; s = 123; break; case 92: /* \ -> | */ u = 92; s = 124; break; - case 93: /* ] -> } */ u = 93; s = 125; break; + case 93: /* ] -> } */ u = 93; s = 125; break; case 96: /* ` -> ~ */ u = 96; s = 126; break; case 109: /* - -> _ */ u = 45; s = 95; break; @@ -2904,7 +2904,7 @@ VT100.prototype.fixEvent = function(event) { case 192: /* ` -> ~ */ u = 96; s = 126; break; case 219: /* [ -> { */ u = 91; s = 123; break; case 220: /* \ -> | */ u = 92; s = 124; break; - case 221: /* ] -> } */ u = 93; s = 125; break; + case 221: /* ] -> } */ u = 93; s = 125; break; case 222: /* ' -> " */ u = 39; s = 34; break; default: break; } @@ -3623,7 +3623,7 @@ VT100.prototype.sendControlToPrinter = function(ch) { break; } // Fall through - case ESgetpars: + case ESgetpars: if (ch == 0x3B /*;*/) { this.npar++; break; @@ -3985,7 +3985,7 @@ VT100.prototype.doControl = function(ch) { } // Fall through case ESdeviceattr: - case ESgetpars: + case ESgetpars: /*;*/ if (ch == 0x3B) { this.npar++; break; @@ -4260,7 +4260,7 @@ VT100.prototype.vt100 = function(s) { this.utfEnabled && ch >= 128 || !(this.dispCtrl ? this.ctrlAlways : this.ctrlAction)[ch & 0x1F]) && (ch != 0x7F || this.dispCtrl); - + if (isNormalCharacter && this.isEsc == ESnormal) { if (ch < 256) { ch = this.translate[this.toggleMeta ? (ch | 0x80) : ch]; @@ -4465,4 +4465,3 @@ VT100.prototype.ctrlAlways = [ false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false ]; -