blob: 66e094f97e7a0ec2e1a20476dff72a14e43e7c3a [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.8">
<title>Overview</title>
<style>
@import url("backtotop.css");
/* ========================================================================== HTML5 display definitions ========================================================================== */
/** Correct `block` display not defined in IE 8/9. */
@import url(https://fast.fonts.net/cssapi/20974f8a-0939-4574-aef9-681eda2faca8.css);
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
/** Correct `inline-block` display not defined in IE 8/9. */
audio, canvas, video { display: inline-block; }
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
audio:not([controls]) { display: none; height: 0; }
/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */
[hidden], template { display: none; }
script { display: none !important; }
/* ========================================================================== Base ========================================================================== */
/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
html { /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ background-color: #D5DFEA; }
/** Remove default margin. */
body { margin: 0; background-color: #D5DFEA; font-family:sans-serif; font-weight: 400} /* add margin-right 0 here for mobile*/
/* ========================================================================== Links ========================================================================== */
/** Remove the gray background color from active links in IE 10. */
a { background: transparent; }
/** Address `outline` inconsistency between Chrome and other browsers. */
a:focus { outline: thin dotted; }
/** Improve readability when focused and also mouse hovered in all browsers. */
a:active, a:hover { outline: 0; }
/* ========================================================================== Typography ========================================================================== */
/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */
h1 { font-size: 2em; margin: 0.67em 0; }
/** Address styling not present in IE 8/9, Safari 5, and Chrome. */
abbr[title] { border-bottom: 1px dotted; }
/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */
b, strong { font-weight: 600; }
/** Address styling not present in Safari 5 and Chrome. */
dfn { font-style: italic; }
/** Address differences between Firefox and other browsers. */
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
/** Address styling not present in IE 8/9. */
mark { background: #ff0; color: #000; }
/** Correct font family set oddly in Safari 5 and Chrome. */
code, kbd, pre, samp { font-family: Fira Mono, monospace, serif; font-size: 1em; }
/** Improve readability of pre-formatted text in all browsers. */
pre { white-space: pre-wrap; }
/** Set consistent quote types. */
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
/** Address inconsistent and variable font size in all browsers. */
small { font-size: 80%; }
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
/* ========================================================================== Embedded content ========================================================================== */
/** Remove border when inside `a` element in IE 8/9. */
img { border: 0; }
/** Correct overflow displayed oddly in IE 9. */
svg:not(:root) { overflow: hidden; }
/* ========================================================================== Figures ========================================================================== */
/** Address margin not present in IE 8/9 and Safari 5. */
figure { margin: 0; }
/* ========================================================================== Forms ========================================================================== */
/** Define consistent border, margin, and padding. */
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */
button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }
/**
#tocbutton {
top: 0;
left: 13rem;
position:fixed;
z-index: 1000;
}
*/
/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
button, input { line-height: normal; }
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */
button, select { text-transform: none; }
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
/** Re-set default cursor for disabled elements. */
button[disabled], html input[disabled] { cursor: default; }
/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
/** Remove inner padding and border in Firefox 4+. */
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */
textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }
/* ========================================================================== Tables ========================================================================== */
/** Remove most spacing between table cells. */
table { border-collapse: collapse; border-spacing: 0; }
meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; }
meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; }
meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; }
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
html, body { background-color:#527AA3; }
body { background: white; color: #222222; padding: ; margin: 0; font-family:sans-serif, Helvetica, Arial, sans-serif; font-weight: 400; font-style: normal; position: relative; cursor: auto; padding-left: 2rem; padding-right: 2rem;}
a:hover { cursor: pointer; }
img, object, embed { height: auto; max-width: 90%; }
object, embed { height: 100%; }
img { -ms-interpolation-mode: bicubic; }
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.antialiased, body { -webkit-font-smoothing: antialiased; }
img { display: inline-block; vertical-align: baseline; }
textarea { height: auto; min-height: 50px; }
select { width: 100%; }
object, svg { display: inline-block; vertical-align: middle; }
.center { margin-left: auto; margin-right: auto; }
.spread { width: 100%; margin-right: 2rem; }
p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1em; line-height: 1.6; }
/* Typography padding etc */
.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 2.4; color: #132445; font-weight: 400; margin-top: 0em; margin-bottom: 0.5em; }
/* Typography resets */
div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }
div.openblock.partintro, div.sectionbody.paragraph {font-weight: 500; line-height: 1.4; margin-bottom: 1em; }
div.sect1 {padding-top: 1rem;}
div.paragraph.faq-intro {max-width: 66%;}
/* Default Link Styles */
a { color: #6999d6; text-decoration: none; line-height: inherit; }
a:hover, a:focus { color: #132445; }
a img { border: none; }
/* Grey links with black transition
a { color: #2ba6cb; text-decoration: none; line-height: inherit; color: rgba(0,0,0,.3); transition: .2s; }
a:active, a:hover, a:focus { color: #212121; }
a img { border: none; }
*/
/* Default paragraph styles */
p { font-family:sans-serif; font-weight: 400; font-size: 1.2rem; line-height: 1.4; padding-bottom: 0.5em; }
p aside { font-size: 0.575em; line-height: 1.35; font-style: italic; }
div.p, { width: 100% }
/* Default header styles */
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: sans-serif; font-weight: 600; font-style: normal; color: #244d82; text-rendering: optimizeLegibility; margin-bottom: 0em; line-height: 1.2125em; margin-top:; 2rem; }
h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #6999d6; line-height: 0; }
h1 { font-size: 2.125em; max-width:66.66%;}
h2 { font-size: 1.6875em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }
h4 { font-size: 1.125em; }
h5 { font-size: 1.125em; }
h6 { font-size: 1em; }
hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }
/* Helpful Typography Defaults */
em, i { font-style: italic; line-height: inherit; }
strong, b { font-weight: 600; line-height: inherit; }
small { font-size: 60%; line-height: inherit; }
code { font-family: Fira Mono, Consolas, "Liberation Mono", Courier, monospace; }
/* Lists */
ul, ol, dl { list-style-position: outside; font-family:sans-serif; padding-left: 0rem; list-style-type: none}
ul, ol { margin-left: 0em; }
ul.no-bullet, ol.no-bullet { margin-left: 1.5em; margin-bottom: 0;}
/* Unordered Lists */
ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }
ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }
ul.square { list-style-type: square; }
ul.circle { list-style-type: circle; }
ul.disc { list-style-type: none; }
ul.no-bullet { list-style: none; }
/* Ordered Lists */
ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
/* Definition Lists */
dl dt { margin-bottom: 0.3125em; font-weight: bold; font-size: 1.2em; font-style: italic}
dl dd { margin-bottom: 1.25em; }
/* Abbreviations */
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #222222; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
/* Blockquotes */
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; }
blockquote cite { display: block; font-size: inherit; color: color: #132445; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #417dcb; }
blockquote, blockquote p { line-height: 1.6; color: #132445; }
/* Microformats */
.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; }
.vcard li { margin: 0; display: block; }
.vcard .fn { font-weight: bold; font-size: 0.9375em; }
.vevent .summary { font-weight: bold; }
.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }
@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; margin-top: 1rem; margin-bottom: 0.2rem;}
h1 { font-size: 2.75em; }
h2 { font-size: 2.3125em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
h4 { font-size: 1.4375em; } }
/* Tables */
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
table thead, table tfoot { background: whitesmoke; font-weight: 600; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #222222; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #222222; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.4; }
/* FEATURE TABLE */
table.done, tr.done.alt, table.done tr:nth-of-type(even) {
background: #efe;
padding-top: 0;
padding-bottom: 0;
border: none;
margin-bottom: -1px;
}
table.most, tr.most.alt, table.most tr:nth-of-type(even) {
background: #ffd;
padding-top: 0;
padding-bottom: 0;
border: none;
margin-bottom: -1px;
}
table.tbc, tr.tbc.alt, table.tbc tr:nth-of-type(even) {
background: #fff6de;
padding-top: 0;
padding-bottom: 0;
border: none;
margin-bottom: -1px;
}
table.tbd, tr.tbd.alt, table.tbd tr:nth-of-type(even) {
background: #fee;
padding-top: 0;
padding-bottom: 0;
border: none;
margin-bottom: -1px;
}
table.done thead tr th, table.done tfoot tr th, table.done tfoot tr td, table.done.sect2, table.most thead tr th, table.most tfoot tr th, table.most tfoot tr td, table.most.sect2, table.tbc thead tr th, table.tbc tfoot tr th, table.tbc tfoot tr td, table.tbc.sect2, table.tbd thead tr th, table.tbd tfoot tr th, table.tbd tfoot tr td, table.tbd.sect2 {background: white; font-size: 1.9rem; color: #417dcb; }
/*
green "done" = #efe
yellow "most" = #ffd
orange "tbc" = #fff6de
red "tbd" = #fee
*/
body { tab-size: 4; max-width: 1050px; margin-right: auto; margin-left: auto; position: relative; margin-top: 0rem; margin-bottom: 0rem; padding-top: 0rem; /* Fixes tables, breaks headers */}
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; margin-top: 0rem;}
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; font-style: normal !important; letter-spacing: 0; padding: 0; line-height: inherit; }
pre, pre > code { line-height: 1.4; color: black; font-family: monospace, serif; font-weight: normal; }
.keyseq { color: #555555; }
kbd { font-family: Consolas, "Liberation Mono", Courier, monospace; display: inline-block; color: #222222; font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menu { color: #090909; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
#header, #content, #footnotes, #footer { max-width: 1050px; margin-right: auto; margin-left: auto; position: relative; margin-top: 0rem; margin-bottom: 0rem; padding-top: 0rem; padding-right: 0rem;}
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content:before { content: none; }
#content {padding-left: 0.5rem;}
#header > h1:first-child { color: black; font-weight: bold; margin-top: 2.25rem; margin-bottom: 0; }
#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #dddddd; }
#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #dddddd; padding-bottom: 8px; }
#header .details { border-bottom: 1px solid #dddddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #417dcb; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; }
#header .details span:first-child { margin-left: -0.125em; }
#header .details span.email a { color: #6999d6; }
#header .details br { display: none; }
#header .details br + span:before { content: "\00a0\2013\00a0"; }
#header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #6999d6; }
#header .details br + span#revremark:before { content: "\00a0|\00a0"; }
#header #revnumber { text-transform: capitalize; }
#header #revnumber:after { content: "\00a0"; }
#content > h1:first-child:not([class]) { color: black; font-weight: bold; border-bottom: 1px solid #dddddd; max-width: 1050px; margin-right: auto; margin-left: auto; position: relative; margin-top: 4rem; margin-bottom: 4rem; padding-top: 0rem; }
/* ========================================================================== Table of Contents ======================================================================= */
#toc { border-bottom: 1px solid #dddddd; padding-bottom: 0.5em; position: relative; left: 0;}
#toc > ul { margin-left: 0.125em; padding-left: 1em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; }
#toc ul { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; list-style-type: none; }
#toc li { line-height: 1.3334; margin-top: 0.3334em; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toc ul li:before {
content: "›";
margin-left: -.75em;
margin-right: .4em;
color: #244d82
}
div.ulist li:before {
content: "›";
position: absolute;
margin-top: .2rem;
font-size: x-large;
margin-left: -.75em;
margin-bottom: -.75em;
margin-right: 0;
line-height: 1rem;
color: #244d82
}
#toctitle { color: #244d82; font-size: 1.2em; padding-left: 1em; }
#faq {
position: relative;
right: 9.3rem;
top: 9rem;
margin-bottom: 20px;
left: 45rem;
z-index:1;padding-left:2rem;border-left:1px solid #d3d3d3
}
@media only screen and (max-width: 945px) {
div#faq { display: none; }
}
#faq h2 {
font-size: 25px;
font-weight: 600;
margin-top: -8rem;
}
div#faq li:before {
content: "›";
position: absolute;
font-size: x-large;
margin-left: -.75em;
margin-bottom: -.75em;
margin-right: 0;
line-height: 1rem;
color: #244d82
}
#features-nav {
position: absolute;
right: 1rem;
top: 2rem;
margin-bottom: 20px;
position:absolute;z-index:1;padding-left:2rem;border-left:1px solid #d3d3d3
}
@media only screen and (max-width: 993px) {
#features-nav { display: none; }
}
#features-nav h2 {
font-size: 25px;
font-weight: 600;
margin-top: -1rem;
}
#features-nav li {
margin-top: .3rem;
}
div#features-nav li:before {
content: "›";
position: absolute;
font-size: x-large;
margin-left: -.75em;
margin-bottom: -.75em;
margin-right: 0;
line-height: 1rem;
color: #244d82
}
@media only screen and (min-width: 1434px) { body.toc2.toc-right #toc.toc2 { border-right-width: 0; border: none; left: 0px; } }
@media only screen and (min-width: 1434px) { #toctitle { padding-top: 1.5rem; font-size: 1.375em; }
body.toc2 { padding-left: 2em; padding-right: 1em; }
#toc.toc2 { margin-top: 0 !important; background-color: #f2f2f2; position: fixed; width: 12em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 0.25em 0em 0.25em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; padding-left: 1em;}
#toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 1em; padding-left: .3em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 2em; padding-right: 2em; }
body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: -13rem; } }
@media only screen and (min-width: 1535px) {
body.toc2 { padding-left: 2em; padding-right: 2em; }
#toctitle { padding-top: 0rem; font-size: 1.375em; }
#toc.toc2 { width: 13em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 0; }
body.toc2.toc-right { padding-left: 2em; padding-right: 2em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 0; border-radius: 0; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#footer { width: 1050px;background-color: #132445; padding: 1.25em; padding-bottom: 0rem; margin-right: -2rem; margin-left: -2rem; margin-top: 2rem; color: white}
div.social { line-height: 1.4; color: #FFFFFF;font-size: 1.2rem; font-weight: 400; font-style: bold; background-color: #132445; margin-right: -2rem; margin-left: -2rem; text-align: left; padding-bottom: 4px; padding-left: 25px; }
div.social li a { margin-bottom: 2em; color: #d5dfea;font-size: 1.2rem; font-weight: 800; font-style: bold; list-style: none; list-style-type: none; text-decoration-color: rgb(213, 223, 234); }
/* div.social a:visited { color: #244D82; }*/
div.social a:hover { color: #F7D425; }
div.social :first-child { margin-top: 0; }
div.social h2 { margin-bottom: 20px;font-weight: 600;font-size: 1.3em;margin-top: 4rem;color: #244d82;font-family: sans-serif;}
div.social li:before {content: "› "; color: #244d82;font-size: large;font-weight: 800;}
div.social ul {margin-top: -10px;line-height: 30px;}
div.social li {/* nothing */}
#bottomright {float: right;}
@media only screen and (max-width: 1050px) {
body {width: 100%;}
}
#footer-text { color: #dddddd; line-height: 1.44; }
.sect1 { padding-bottom: 0.625em; }
.sectionbody.paragraph {max-width: 66.666%}
.sectionbody ul {padding-left: 1rem;}
@media only screen and (min-width: 768px) { .sect1 { padding-bottom: 0em; } }
.sect1 + .sect1 { border-top: 0px solid #dddddd; }
#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: 400; max-width: 1050px; }
#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\2771"; font-size: 0.85em; display: block; padding-top: 0.1em; vertical-align: bas }
#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }
#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #244d82; text-decoration: none; font-family: sans-serif}
#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #1e416e; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: black; max-width: 66%}
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border-collapse: separate; border: 0; background: none; max-width: 80%;}
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: none; }
.admonitionblock > table td.icon .title { font-weight: bold; font-family: sans-serif, Georgia, Verdana, "Helvetica", Helvetica, Arial, sans-serif; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #417dcb; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background-color: #fffef7; -webkit-border-radius: 0; border-radius: 0; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.sidebarblock { position: absolute; border-style: solid; border-width: 1px; border-color: #d9d9d9; margin: -2rem -7.5rem 0rem 63.65rem; padding: .2rem; background: #f2f2f2; -webkit-border-radius: 0; border-radius: 0; text-align: left; width: 5.5rem;}
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock > .content > .title { color: #6999d6; margin-top: 0; }
@media only screen and (max-width: 1203px) {
.sidebarblock { position: absolute; right: 12%; }
}
@media only screen and (max-width: 817px) {
.sidebarblock { position: absolute; right: 18%; }
}
@media only screen and (max-width: 562px) {
.sidebarblock { position: absolute; right: 25%; }
}
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eeeeee; }
.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px solid #cccccc; -webkit-border-radius: 0; border-radius: 0; word-wrap: break-word; padding: 0.8em 0.8em 0.65em 0.8em; font-size: 0.8125em; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } }
@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } }
.literalblock.output pre { color: #eeeeee; background-color: black; }
.listingblock pre.highlightjs { padding: 0; margin-right: 0em; }
.listingblock pre.highlightjs > code { padding: 0.8em 2rem 0.65em 0.8em; -webkit-border-radius: 0; border-radius: 0; padding-right: 2rem;}
.listingblock > .content { position: relative; }
.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; padding-right: 2rem; }
.listingblock:hover code[data-lang]:before { display: none; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; }
table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.4; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; }
pre.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; }
.quoteblock { margin: 0 1em 1.25em 1.5em; display: table; }
.quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; }
.quoteblock blockquote, .quoteblock blockquote p { color: #132445; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; }
.quoteblock blockquote { margin: 0; padding: 1rem; border: 0; }
.quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #6999d6; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: 1em; margin-right: 0.5ex; text-align: right; }
.quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #417dcb; }
.quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; }
.quoteblock .quoteblock blockquote:before { display: none; }
.verseblock { margin: 0 1em 1.25em 1em; }
.verseblock pre { font-family: sans-serif, "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #6999d6; font-weight: 300; text-rendering: optimizeLegibility; }
.verseblock pre strong { font-weight: 400; }
.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; text-align: right;}
.quoteblock .attribution, .verseblock .attribution { font-size: inherit; line-height: 1.45; font-style: italic; }
.quoteblock .attribution br, .verseblock .attribution br { display: none; }
.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #417dcb; }
.quoteblock.abstract { margin: 0 0 1.25em 0; display: block; }
.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; }
.quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; }
table.tableblock { max-width: 100%; border-collapse: separate; }
table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #dddddd; margin-right: 2rem;}
table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; padding: 0.5rem;}
table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; }
table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; }
table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; }
table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0;}
table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: 600; }
tbody tr th { display: table-cell; line-height: 1.4; background: whitesmoke; }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #222222; font-weight: 600; }
p.tableblock > code:only-child { background: none; padding: 0; max-width: 100%}
p.tableblock { font-size: 1em; max-width: 100% }
td > div.verse { white-space: pre; }
ol { margin-left: 1.75em; }
ul li ol { margin-left: 1.5em; }
dl dd { margin-left: 1.125em; }
dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }
ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: -0.2em; }
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; }
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
ul.inline > li > * { display: block; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1, td.hdlist2 { vertical-align: baseline; padding: 0 0.625em; }
td.hdlist1 { font-weight: bold; padding-bottom: 1.25em; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; display: inline-block; }
a.image object { pointer-events: none; }
sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; }
sup.footnote a, sup.footnoteref a { text-decoration: none; }
sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.05em; margin-bottom: 0.2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.github-block { text-align: right; margin-right: -1rem; }
div.gist {padding-right: 2rem;}
div.unbreakable { page-break-inside: avoid; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #207c98; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; }
.conum[data-value] { display: inline-block; color: #fff !important; background-color: #222222; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family:sans-serif, "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; }
.conum[data-value] * { color: #fff !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -0.125em; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
.literalblock pre, .listingblock pre { background: #eeeeee; }
div#remarks.ulist {
max-width: 70%;
}
div.title:first-of-type {
display: none;
}
/* Mobile */
@media only screen and (max-width: 800px) {
a#bottomright {visibility: hidden;}
.sectionbody.paragraph {max-width: 100%}
.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { max-width: 100% }
}
#div.paragraph.faq-intro {
max-width: 66.66%
}
/* ========================================================================== Mobile Menu ======================================================================= */
#menu {
display: none;
}
div.slicknav_menu {
padding-top: 5px;
padding-right: 15px;
background-color: #132445;
margin-left: -2rem;
margin-right: -2rem;
text-align: right;
display: none;
right: 10px;
font-size: 1rem;
color: white;
padding-bottom: 2rem;
background: url("n4js-logo.png");
background-position: 10px 10px;
background-size: 344.48px 40px;
background-repeat: no-repeat;
background-color: #132445;
}
span.slicknav_menutxt {
margin-right: -20px;
color: white;
}
div.slicknav_menu a.scroll:first-of-type {
color: #F7D425;
font-size: 120%;
font-weight: 600;
}
div.slicknav_menu ul li a {
color: white;
}
div.slicknav_menu ul li a:hover {
color: #F7D425;
}
div.slicknav_menu a:hover {color: #F7D425; }
div.slicknav_menu a:visited {color: white; }
div.slicknav_menu a {color: white;}
a.slicknav_btn {
padding: 1rem;
}
li.slicknav_parent.slicknav_open {
color: white;
}
li.slicknav_parent.slicknav_open {
color: white;
}
@media screen and (max-width: 890px) {
div.slicknav_menu {
display: block;
color: white
}
#mobile-banner {
display: block;
}
}
@media screen and (max-width: 470px) {
div.slicknav_menu ul:first-of-type {
margin-top: 1.5rem;
}
div.slicknav_menu ul li {
color: white;
}
div.slicknav_menu ul li:hover {
color: #F7D425;
}
}
div.slicknav_menu li:last-of-type
{
padding-bottom: 0.7rem;
}
/* ========================================================================== NavMenu ======================================================================= */
.banner {
height: 1rem;
padding-right: 2rem;
max-height: 1rem;
max-width: 50%;
vertical-align: middle;
@media (max-width: 800px) {
flex-basis: 66.666%%;
max-width: 25%;
margin: 1rem;
}
}
div.box p {
text-indent: 0px;
position: absolute;
display: none;
}
#menubar ul { margin: 0; padding: 0; white-space:nowrap; padding-left: 10px; padding-right: 10px; line-height: 2rem;}
#menubar li { margin: 0; padding: 0; }
#menubar a { margin: 0; padding: 0;}
#menubar ul {list-style: none; text-align: right;}
#menubar a {text-decoration: none;}
#menubar li {margin-left: 0;}
#menubar {height: 70px; background-color: #132445; /* box-shadow: 0px 2px 3px rgba(0,0,0,.4); */ position: relative; padding-right: 2rem; margin-left: -2rem; margin-right: -2rem; color: white; font-size: 1.9rem;}
#menubar > ul > li {
display:inline-block;
margin: 0.2rem;
position: relative;
z-index: 10000;
flex-basis: 66.666%%;
font-weight: 700;
}
@media only screen and (max-width: 890px) {
#n4js-mobile-logo {
position: absolute;
top: 0;
left: 0;
width: 178px;
height: 60px;
background-color: transparent;
}
div.box p {
text-indent: -999px;
position: absolute;
}
#menubar > ul > li, #menubar {
visibility: hidden;
display: none;
}
}
@media only screen and (max-width: 500px) {
#menubar {
display: none;
}
#logo {
margin-top: -55px;
}
}
#logo {
height: 40px;
margin-left: 40px;
margin-top: 17px;
position: relative;
overflow: hidden;
}
#menubar > ul > li::after {
content: " · ";
position: relative;
top: 3px;
padding-left: 3px;
font-weight: 400;
}
#menubar > ul > li:last-of-type::after {
content: none;
}
#menubar > ul > li:last-of-type {
padding-right: -1rem;
}
#menubar > ul > li > a {
color: #FFFFFF;
font-size: 1.2rem;
line-height: 50px;
font-weight: 400;
/* padding-top: 2rem; */
webkit-transition: color .15s;
-moz-transition: color .15s;
-o-transition: color .15s;
transition: color .15s;
white-space:nowrap;
-webkit-font-smoothing: auto;
letter-spacing: -.01em;
padding-top: 0.2em;
padding-left: 0rem;
padding-right: 0.1rem;
}
#menubar > ul {
margin-right: 12px;
margin-top: 0px;
}
#menubar > ul > li > a:hover {color: #F7D425; }
body.home li.home, body.tech li.tech {font-weight:bold; }
#menubar > ul > li > ul {
opacity: 0;
visibility: hidden;
padding: 18px 0 20px 0;
background-color: #FFFFFF; /* rgb(15,26,54); top menu color */
text-align: left;
position: absolute;
top: 55px;
left: 50%;
margin-left: -200px;
-webkit-transition: all .3s .1s;
-moz-transition: all .3s .1s;
-o-transition: all .3s .1s;
transition: all .3s .1s;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.4);
-moz-box-shadow: 0px 1px 3px rgba(0,0,0,.4);
box-shadow: 0px 1px 3px rgba(0,0,0,.4);
}
#menubar > li li {
width:100%;
}
#menubar > ul > li:hover > ul {
opacity: 1;
top: 65px;
visibility: visible;
}
#menubar > ul > li > ul:before{
content: '';
display: block;
border-color: transparent transparent #FFFFFF transparent;
border-style: solid;
border-width: 10px;
position: absolute;
top: -20px;
left: 10%;
margin-left: -10px;
}
#menubar > ul ul > li { position: relative;}
#menubar ul ul a{
color: rgb(50,50,50);
font-family: sans-serif, Verdana, 'Lucida Grande';
font-size: 17px;
background-color: #FFFFFF; /* rgb(15,26,54); top menu color */
padding: 5px 8px 7px 16px;
display: block;
-webkit-transition: background-color .1s;
-moz-transition: background-color .1s;
-o-transition: background-color .1s;
transition: background-color .1s;
}
#menubar ul ul a:hover {background-color: #244D82; color: #F7D425;}
#menubar ul ul ul {
visibility: hidden;
opacity: 0;
position: absolute;
top: -16px;
left: 206px;
padding: 16px 0 20px 0;
background-color: #527AA3;
text-align: left;
width: 160px;
-webkit-transition: all .3s;
-moz-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.4);
-moz-box-shadow: 0px 1px 3px rgba(0,0,0,.4);
box-shadow: 0px 1px 3px rgba(0,0,0,.4);
}
#menubar ul ul > li:hover > ul { opacity: 1; left: 196px; visibility: visible;}
#menubar ul ul a:hover{
background-color: #244D82;
color: #F7D425;
}
.Cell--12-12 {
-webkit-flex-basis: 100%;
-ms-flex-preferred-size: 100%;
flex-basis: 100%;
max-width: 100%
}
.Grid {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row
}
.Cell,
.Comparison .Comparison-left,
.Comparison .Comparison-right,
.ExampleExplanation .ExampleExplanation-code,
.ExampleExplanation .ExampleExplanation-text,
.FeatureTabs .FeatureTabs-stage,
.Intro .Intro-Slogan {
padding-left: 1rem;
padding-right: 1rem;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto
}
#_index, #_feature_table {display: none;}
#_documentation {margin-top: -2rem;}
h3 {padding-top: 1rem}
/* ========================================================================== AsciiSpec ======================================================================= */
.requirement {
border: 1px solid #aaaaaa;
padding: 0.5em;
margin-bottom: 1rem;
}
.bibliography .content .paragraph p :first-child::before {
color:#777777;
content: "[" attr(id) "] "; }
.bibliography .content .paragraph {
padding-left: 6em;
text-indent: -6em;
</style>
</head>
<body class="article">
<div id="header">
</div>
<div id="content">
<div class="sect1">
<h2 id="_overview">Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In part 1, we have discussed how to develop a chess game app with React and JSX in N4JS. There, we have stored the application state in the React component Game&#8217;s state. As applications become larger, however, the mix of application state and UI makes the application hard to comprehend and more difficult to test.</p>
</div>
<div class="paragraph">
<p>As a result, in large applications, <a href="https://redux.js.org/">Redux</a> - an implementation of <a href="https://facebook.github.io/flux/">Flux architecture</a> also created by Facebook - is often used to organize the application code. Redux strictly allows the data to flow in only one direction as shown in the following diagram. Also, Redux is UI agnostic and can be used in conjunction with any UI library. In this tutorial, we will extract the entire game state out of React components and store it in a Redux store.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_source_code">Source code</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Redux-based version of the chess app in hosted on the branch <a href="https://github.com/NumberFour/n4js-tutorial-chess/tree/chess-app-react-redux"><code>chess-app-react-redux</code></a> of the corresponding repository.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_redux_architecture_with_react">Redux Architecture with React</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this section, we will review several key concepts of Redux when used with React. You should consult official Redux documentation for more details. When using React with Redux, we normally store the application state in Redux store instead of React components' state. As a result, React components become stateless UI elements and they simply render the UI using the data retrieved from the Redux store. In a Redux architecture, data flows strictly in one direction. The following diagram graphically depicts the action/data flow in a React + Redux app.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/redux-architecture.svg" alt="Redux architecture"></span></p>
</div>
<div class="paragraph">
<p>The action/data flow in the diagram can be roughly understood as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When a user interaction is triggered on the React component (e.g. button clicked, text field edited etc.), an action is created. The action describes the changes needed to be updated in the application state. For instance, when a text field is edited, the action created may contain the new string of the text field.</p>
</li>
<li>
<p>Then the action is dispatched to the Redux store whereby the Redux store stores the application state, usually as a hierarchical tree of state.</p>
</li>
<li>
<p>The reducers take the action and the current application state and create an updated application state.</p>
</li>
<li>
<p>If the changes in the application state are to a certain React component, they are forwarded into the component in form of props. The change in props causes the component to re-render.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_connect_react_to_redux">Connect React to Redux</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In a React + Redux app, we have stateless React components rendering UI elements on the one side. On the other side, we have a Redux store that stores our application state. We need to establish a connection between them.</p>
</div>
<div class="paragraph">
<p>In particular, when the user interaction is triggered on a React component, we need to turn this user interaction into actions that are then processed by reducers to create a new application state in the Redux store. Conversely, when the application state in the Redux store is changed, we need to inform the React components that are interested in the change so that they can re-render.
Fortunately, the npm library react-redux can establish exactly this connection for us.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="images/react-redux-connection.svg" alt="Redux architecture"></span></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_store_chess_game_state_in_redux_store">Store Chess Game State in Redux Store</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Recall that in the previous implementation, the game state is stored as <em>state</em> in the React component Game. We move state out of Game component and store it in a Redux instead. In this section, we will provide some hints on the implementation. The reader should study the source code for the detailed implementation.</p>
</div>
<div class="paragraph">
<p>In Game component, we define two mapping functions needed by <code>react-redux</code> to connect Game component with the Redux store.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-typescript" data-lang="typescript">/**
* Map Redux state to Game's props
*/
function mapStateToProps(state: StoreState): GameProps {
return {
history: state.history,
stepNumber: state.stepNumber,
whiteIsNext: state.whiteIsNext,
pickedSquare: state.pickedSquare,
validDestinations: state.validDestinations
}
}
/**
* Map Game's events to Redux actions
*/
function mapDispatchToProps(dispatch: {function(ReduxAction): any} ) {
return {
createPickSquareAction: (pos: Coordinate) =&gt; {
dispatch(createPickSquareAction(pos))
},
jumpToStep: (step: number) =&gt; {
dispatch(createJumpToStepAction(step))
}
}
}
export public const ConnectedGame = connect(mapStateToProps, mapDispatchToProps)(Game);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Whenever a square is clicked, an instance of <code>PickSquareAction</code> is created. A redux action has be a subclass of <code>ReduxAction</code>. Note that, react-redux requires that every action has a <code>type</code>. In N4JS, we can use the fully qualified name of the class for this purpose. Hence, we define a base class <code>ActionBase</code> for all actions.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-typescript" data-lang="typescript">/**
* Base Redux action. Its type is the FQN of the class
*/
export public class ~ActionBase implements ReduxAction {
@Override
public type: string = this.constructor.n4type.fqn;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>PickSquareAction</code> class and function creating an instance of that class are very simple</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-typescript" data-lang="typescript">/**
* Pick square action
*/
export public class PickSquareAction extends ActionBase {
/**
* The coordinate of the picked square
*/
public coord: Coordinate;
public constructor(@Spec spec:~i~this) {}
}
/**
* Create a PickSquareAction
*/
export public function createPickSquareAction(pos: Coordinate): PickSquareAction {
return new PickSquareAction({ coord: pos });
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A reducer modifies the state in the Redux store based on an action. For the purpose of this application, we define a single reducer that is interested in all actions. An implementation of the reducer chooses the actions it is interested and returns a new state from the old one based on the action.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-typescript" data-lang="typescript">/**
* For this demo application, this reducer is interested in all actions.
*/
export public function reducer(state: StoreState, action: ReduxAction): StoreState {
if (!state) {
state = initialState;
}
const { history, stepNumber, whiteIsNext } = state;
switch (action.type) {
case PickSquareAction.n4type.fqn: // This reducer is interested in this action
...
case JumpToStepAction.n4type.fqn: // This reducer is interested in this action
...
default:
// Irrelevant action, return the old state
return state;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the reducer returns a new state, that state is passed through the function <code>mapStateToProps</code> which selects the props that are relevant to Game component. The Game component then re-renders with the updated props.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_test_game_rules_with_mangelhaft">Test Game Rules with Mangelhaft</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Since the focus of the tutorials is on N4JS, we have not discussed test yet. In a real world project, however, it is extremely important to have tests, especially unit tests, to assure the correctness of the application. The good news is, unit tests for N4JS applications can be written very conveniently in our xUnit-based test framework Mangelhaft that provides assertion methods resembling JUnit&#8217;s familiar to Java developers.</p>
</div>
<div class="paragraph">
<p>For instance, we will write a Mangelhaft test that tests the implementation of the reducer. In particular, we test that given the initial arrangement of the chess board, if an action <code>PickSquareAction</code> is created for the coordinate <code>(0,1)</code> (i.e. the left white knight is picked), the valid destinations are updated correctly in the new state. One possible way of expressing this test in Mangelhaft is as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-typescript" data-lang="typescript">export public class ReducePickSquareActionTest {
private state: StoreState;
@Before
public init() {
this.state = initialState;
}
@Test
public knightValidDestinationsTest() {
const pickSquare = new Coordinate({row: 0, col: 1});
const pickLeftWhiteKnight = createPickSquareAction(pickSquare);
const newState = reducer(this.state, pickLeftWhiteKnight);
Assert.equal(newState.validDestinations.length, 2, 'Must have 2 valid destinations');
for (const validDest of newState.validDestinations) {
Assert.equal(validDest.row - pickSquare.row, 2, 'Wrong row');
Assert.equal(Math.abs(validDest.col - pickSquare.col), 1, 'Wrong column');
}
}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the way we are testing the game logics is completely UI-agnostic and no React components are involved at all! This is thanks to the decoupling of game logics from UI with the help of Redux.</p>
</div>
<div class="paragraph">
<p>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/themes/prism.min.css"></link>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/prism.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/components/prism-typescript.min.js"></script>
</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2019-05-15 16:11:28 +0200
</div>
</div>
</body>
</html>