javascript-in-15-minuten-lernen.php
Quell Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JavaScript in 14 minutes by Jeremy Thomas</title>
<style>
@charset "UTF-8";
@keyframes a{
0%{
transform:rotate(0deg)
}
to{
transform:rotate(359deg)
}
}
/*! minireset.css v0.0.2 | MIT License | github.com/jgthms/minireset.css */
blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{
margin:0;
padding:0
}
h1,h2,h3,h4,h5,h6{
font-size:100%;
font-weight:400
}
ul{
list-style:none
}
button,input,select,textarea{
margin:0
}
html{
box-sizing:border-box
}
*,:after,:before{
box-sizing:inherit
}
audio,embed,img,object,video{
max-width:100%
}
iframe{
border:0
}
table{
border-collapse:collapse;
border-spacing:0
}
td,th{
padding:0;
text-align:left
}
html{
background-color:#fff;
font-size:16px;
-moz-osx-font-smoothing:grayscale;
-webkit-font-smoothing:antialiased;
min-width:300px;
overflow-x:hidden;
overflow-y:scroll;
text-rendering:optimizeLegibility;
-webkit-text-size-adjust:100%;
-ms-text-size-adjust:100%;
text-size-adjust:100%
}
article,aside,figure,footer,header,hgroup,section{
display:block
}
body,button,input,select,textarea{
font-family:BlinkMacSystemFont,-apple-system,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Helvetica,Arial,sans-serif
}
code,pre{
-moz-osx-font-smoothing:auto;
-webkit-font-smoothing:auto;
font-family:monospace
}
body{
color:#4a4a4a;
font-size:1rem;
font-weight:400;
line-height:1.5
}
a{
color:#3273dc;
cursor:pointer;
text-decoration:none
}
a strong{
color:currentColor
}
a:hover{
color:#363636
}
code{
background-color:#f5f5f5;
color:#ff3860;
font-size:.875em;
font-weight:400;
padding:.25em .5em
}
hr{
background-color:#dbdbdb;
border:none;
display:block;
height:1px;
margin:1.5rem 0
}
img{
height:auto;
max-width:100%
}
input[type=checkbox],input[type=radio]{
vertical-align:baseline
}
small{
font-size:.875em
}
span{
font-style:inherit;
font-weight:inherit
}
strong{
color:#363636;
font-weight:700
}
pre{
-webkit-overflow-scrolling:touch;
background-color:#f5f5f5;
color:#4a4a4a;
font-size:.875em;
overflow-x:auto;
padding:1.25rem 1.5rem;
white-space:pre;
word-wrap:normal
}
pre code{
background-color:transparent;
color:currentColor;
font-size:1em;
padding:0
}
table td,table th{
text-align:left;
vertical-align:top
}
table th{
color:#363636
}
.is-clearfix:after{
clear:both;
content:" ";
display:table
}
.is-pulled-left{
float:left!important
}
.is-pulled-right{
float:right!important
}
.is-clipped{
overflow:hidden!important
}
.is-overlay{
bottom:0;
left:0;
position:absolute;
right:0;
top:0
}
.is-size-1{
font-size:3rem!important
}
.is-size-2{
font-size:2.5rem!important
}
.is-size-3{
font-size:2rem!important
}
.is-size-4{
font-size:1.5rem!important
}
.is-size-5{
font-size:1.25rem!important
}
.is-size-6{
font-size:1rem!important
}
.is-size-7{
font-size:.75rem!important
}
@media screen and (max-width:768px){
.is-size-1-mobile{
font-size:3rem!important
}
.is-size-2-mobile{
font-size:2.5rem!important
}
.is-size-3-mobile{
font-size:2rem!important
}
.is-size-4-mobile{
font-size:1.5rem!important
}
.is-size-5-mobile{
font-size:1.25rem!important
}
.is-size-6-mobile{
font-size:1rem!important
}
.is-size-7-mobile{
font-size:.75rem!important
}
}
@media print,screen and (min-width:769px){
.is-size-1-tablet{
font-size:3rem!important
}
.is-size-2-tablet{
font-size:2.5rem!important
}
.is-size-3-tablet{
font-size:2rem!important
}
.is-size-4-tablet{
font-size:1.5rem!important
}
.is-size-5-tablet{
font-size:1.25rem!important
}
.is-size-6-tablet{
font-size:1rem!important
}
.is-size-7-tablet{
font-size:.75rem!important
}
}
@media screen and (max-width:1023px){
.is-size-1-touch{
font-size:3rem!important
}
.is-size-2-touch{
font-size:2.5rem!important
}
.is-size-3-touch{
font-size:2rem!important
}
.is-size-4-touch{
font-size:1.5rem!important
}
.is-size-5-touch{
font-size:1.25rem!important
}
.is-size-6-touch{
font-size:1rem!important
}
.is-size-7-touch{
font-size:.75rem!important
}
}
@media screen and (min-width:1024px){
.is-size-1-desktop{
font-size:3rem!important
}
.is-size-2-desktop{
font-size:2.5rem!important
}
.is-size-3-desktop{
font-size:2rem!important
}
.is-size-4-desktop{
font-size:1.5rem!important
}
.is-size-5-desktop{
font-size:1.25rem!important
}
.is-size-6-desktop{
font-size:1rem!important
}
.is-size-7-desktop{
font-size:.75rem!important
}
}
@media screen and (min-width:1216px){
.is-size-1-widescreen{
font-size:3rem!important
}
.is-size-2-widescreen{
font-size:2.5rem!important
}
.is-size-3-widescreen{
font-size:2rem!important
}
.is-size-4-widescreen{
font-size:1.5rem!important
}
.is-size-5-widescreen{
font-size:1.25rem!important
}
.is-size-6-widescreen{
font-size:1rem!important
}
.is-size-7-widescreen{
font-size:.75rem!important
}
}
@media screen and (min-width:1408px){
.is-size-1-fullhd{
font-size:3rem!important
}
.is-size-2-fullhd{
font-size:2.5rem!important
}
.is-size-3-fullhd{
font-size:2rem!important
}
.is-size-4-fullhd{
font-size:1.5rem!important
}
.is-size-5-fullhd{
font-size:1.25rem!important
}
.is-size-6-fullhd{
font-size:1rem!important
}
.is-size-7-fullhd{
font-size:.75rem!important
}
}
.has-text-centered{
text-align:center!important
}
@media screen and (max-width:768px){
.has-text-centered-mobile{
text-align:center!important
}
}
@media print,screen and (min-width:769px){
.has-text-centered-tablet{
text-align:center!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.has-text-centered-tablet-only{
text-align:center!important
}
}
@media screen and (max-width:1023px){
.has-text-centered-touch{
text-align:center!important
}
}
@media screen and (min-width:1024px){
.has-text-centered-desktop{
text-align:center!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.has-text-centered-desktop-only{
text-align:center!important
}
}
@media screen and (min-width:1216px){
.has-text-centered-widescreen{
text-align:center!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.has-text-centered-widescreen-only{
text-align:center!important
}
}
@media screen and (min-width:1408px){
.has-text-centered-fullhd{
text-align:center!important
}
}
.has-text-justified{
text-align:justify!important
}
@media screen and (max-width:768px){
.has-text-justified-mobile{
text-align:justify!important
}
}
@media print,screen and (min-width:769px){
.has-text-justified-tablet{
text-align:justify!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.has-text-justified-tablet-only{
text-align:justify!important
}
}
@media screen and (max-width:1023px){
.has-text-justified-touch{
text-align:justify!important
}
}
@media screen and (min-width:1024px){
.has-text-justified-desktop{
text-align:justify!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.has-text-justified-desktop-only{
text-align:justify!important
}
}
@media screen and (min-width:1216px){
.has-text-justified-widescreen{
text-align:justify!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.has-text-justified-widescreen-only{
text-align:justify!important
}
}
@media screen and (min-width:1408px){
.has-text-justified-fullhd{
text-align:justify!important
}
}
.has-text-left{
text-align:left!important
}
@media screen and (max-width:768px){
.has-text-left-mobile{
text-align:left!important
}
}
@media print,screen and (min-width:769px){
.has-text-left-tablet{
text-align:left!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.has-text-left-tablet-only{
text-align:left!important
}
}
@media screen and (max-width:1023px){
.has-text-left-touch{
text-align:left!important
}
}
@media screen and (min-width:1024px){
.has-text-left-desktop{
text-align:left!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.has-text-left-desktop-only{
text-align:left!important
}
}
@media screen and (min-width:1216px){
.has-text-left-widescreen{
text-align:left!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.has-text-left-widescreen-only{
text-align:left!important
}
}
@media screen and (min-width:1408px){
.has-text-left-fullhd{
text-align:left!important
}
}
.has-text-right{
text-align:right!important
}
@media screen and (max-width:768px){
.has-text-right-mobile{
text-align:right!important
}
}
@media print,screen and (min-width:769px){
.has-text-right-tablet{
text-align:right!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.has-text-right-tablet-only{
text-align:right!important
}
}
@media screen and (max-width:1023px){
.has-text-right-touch{
text-align:right!important
}
}
@media screen and (min-width:1024px){
.has-text-right-desktop{
text-align:right!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.has-text-right-desktop-only{
text-align:right!important
}
}
@media screen and (min-width:1216px){
.has-text-right-widescreen{
text-align:right!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.has-text-right-widescreen-only{
text-align:right!important
}
}
@media screen and (min-width:1408px){
.has-text-right-fullhd{
text-align:right!important
}
}
.is-capitalized{
text-transform:capitalize!important
}
.is-lowercase{
text-transform:lowercase!important
}
.is-uppercase{
text-transform:uppercase!important
}
.is-italic{
font-style:italic!important
}
.has-text-white{
color:#fff!important
}
a.has-text-white:focus,a.has-text-white:hover{
color:#e6e6e6!important
}
.has-text-black{
color:#0a0a0a!important
}
a.has-text-black:focus,a.has-text-black:hover{
color:#000!important
}
.has-text-light{
color:#f5f5f5!important
}
a.has-text-light:focus,a.has-text-light:hover{
color:#dbdbdb!important
}
.has-text-dark{
color:#363636!important
}
a.has-text-dark:focus,a.has-text-dark:hover{
color:#1c1c1c!important
}
.has-text-primary{
color:#00d1b2!important
}
a.has-text-primary:focus,a.has-text-primary:hover{
color:#009e86!important
}
.has-text-link{
color:#3273dc!important
}
a.has-text-link:focus,a.has-text-link:hover{
color:#205bbc!important
}
.has-text-info{
color:#209cee!important
}
a.has-text-info:focus,a.has-text-info:hover{
color:#0f81cc!important
}
.has-text-success{
color:#23d160!important
}
a.has-text-success:focus,a.has-text-success:hover{
color:#1ca64c!important
}
.has-text-warning{
color:#ffdd57!important
}
a.has-text-warning:focus,a.has-text-warning:hover{
color:#ffd324!important
}
.has-text-danger{
color:#ff3860!important
}
a.has-text-danger:focus,a.has-text-danger:hover{
color:#ff0537!important
}
.has-text-black-bis{
color:#121212!important
}
.has-text-black-ter{
color:#242424!important
}
.has-text-grey-darker{
color:#363636!important
}
.has-text-grey-dark{
color:#4a4a4a!important
}
.has-text-grey{
color:#7a7a7a!important
}
.has-text-grey-light{
color:#b5b5b5!important
}
.has-text-grey-lighter{
color:#dbdbdb!important
}
.has-text-white-ter{
color:#f5f5f5!important
}
.has-text-white-bis{
color:#fafafa!important
}
.has-text-weight-light{
font-weight:300!important
}
.has-text-weight-normal{
font-weight:400!important
}
.has-text-weight-semibold{
font-weight:600!important
}
.has-text-weight-bold{
font-weight:700!important
}
.is-block{
display:block!important
}
@media screen and (max-width:768px){
.is-block-mobile{
display:block!important
}
}
@media print,screen and (min-width:769px){
.is-block-tablet{
display:block!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-block-tablet-only{
display:block!important
}
}
@media screen and (max-width:1023px){
.is-block-touch{
display:block!important
}
}
@media screen and (min-width:1024px){
.is-block-desktop{
display:block!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-block-desktop-only{
display:block!important
}
}
@media screen and (min-width:1216px){
.is-block-widescreen{
display:block!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-block-widescreen-only{
display:block!important
}
}
@media screen and (min-width:1408px){
.is-block-fullhd{
display:block!important
}
}
.is-flex{
display:-ms-flexbox!important;
display:flex!important
}
@media screen and (max-width:768px){
.is-flex-mobile{
display:-ms-flexbox!important;
display:flex!important
}
}
@media print,screen and (min-width:769px){
.is-flex-tablet{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-flex-tablet-only{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (max-width:1023px){
.is-flex-touch{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:1024px){
.is-flex-desktop{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-flex-desktop-only{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:1216px){
.is-flex-widescreen{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-flex-widescreen-only{
display:-ms-flexbox!important;
display:flex!important
}
}
@media screen and (min-width:1408px){
.is-flex-fullhd{
display:-ms-flexbox!important;
display:flex!important
}
}
.is-inline{
display:inline!important
}
@media screen and (max-width:768px){
.is-inline-mobile{
display:inline!important
}
}
@media print,screen and (min-width:769px){
.is-inline-tablet{
display:inline!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-inline-tablet-only{
display:inline!important
}
}
@media screen and (max-width:1023px){
.is-inline-touch{
display:inline!important
}
}
@media screen and (min-width:1024px){
.is-inline-desktop{
display:inline!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-inline-desktop-only{
display:inline!important
}
}
@media screen and (min-width:1216px){
.is-inline-widescreen{
display:inline!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-inline-widescreen-only{
display:inline!important
}
}
@media screen and (min-width:1408px){
.is-inline-fullhd{
display:inline!important
}
}
.is-inline-block{
display:inline-block!important
}
@media screen and (max-width:768px){
.is-inline-block-mobile{
display:inline-block!important
}
}
@media print,screen and (min-width:769px){
.is-inline-block-tablet{
display:inline-block!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-inline-block-tablet-only{
display:inline-block!important
}
}
@media screen and (max-width:1023px){
.is-inline-block-touch{
display:inline-block!important
}
}
@media screen and (min-width:1024px){
.is-inline-block-desktop{
display:inline-block!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-inline-block-desktop-only{
display:inline-block!important
}
}
@media screen and (min-width:1216px){
.is-inline-block-widescreen{
display:inline-block!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-inline-block-widescreen-only{
display:inline-block!important
}
}
@media screen and (min-width:1408px){
.is-inline-block-fullhd{
display:inline-block!important
}
}
.is-inline-flex{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
@media screen and (max-width:768px){
.is-inline-flex-mobile{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media print,screen and (min-width:769px){
.is-inline-flex-tablet{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-inline-flex-tablet-only{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (max-width:1023px){
.is-inline-flex-touch{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:1024px){
.is-inline-flex-desktop{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-inline-flex-desktop-only{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:1216px){
.is-inline-flex-widescreen{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-inline-flex-widescreen-only{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
@media screen and (min-width:1408px){
.is-inline-flex-fullhd{
display:-ms-inline-flexbox!important;
display:inline-flex!important
}
}
.is-hidden{
display:none!important
}
@media screen and (max-width:768px){
.is-hidden-mobile{
display:none!important
}
}
@media print,screen and (min-width:769px){
.is-hidden-tablet{
display:none!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-hidden-tablet-only{
display:none!important
}
}
@media screen and (max-width:1023px){
.is-hidden-touch{
display:none!important
}
}
@media screen and (min-width:1024px){
.is-hidden-desktop{
display:none!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-hidden-desktop-only{
display:none!important
}
}
@media screen and (min-width:1216px){
.is-hidden-widescreen{
display:none!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-hidden-widescreen-only{
display:none!important
}
}
@media screen and (min-width:1408px){
.is-hidden-fullhd{
display:none!important
}
}
.is-invisible{
visibility:hidden!important
}
@media screen and (max-width:768px){
.is-invisible-mobile{
visibility:hidden!important
}
}
@media print,screen and (min-width:769px){
.is-invisible-tablet{
visibility:hidden!important
}
}
@media screen and (min-width:769px) and (max-width:1023px){
.is-invisible-tablet-only{
visibility:hidden!important
}
}
@media screen and (max-width:1023px){
.is-invisible-touch{
visibility:hidden!important
}
}
@media screen and (min-width:1024px){
.is-invisible-desktop{
visibility:hidden!important
}
}
@media screen and (min-width:1024px) and (max-width:1215px){
.is-invisible-desktop-only{
visibility:hidden!important
}
}
@media screen and (min-width:1216px){
.is-invisible-widescreen{
visibility:hidden!important
}
}
@media screen and (min-width:1216px) and (max-width:1407px){
.is-invisible-widescreen-only{
visibility:hidden!important
}
}
@media screen and (min-width:1408px){
.is-invisible-fullhd{
visibility:hidden!important
}
}
.is-marginless{
margin:0!important
}
.is-paddingless{
padding:0!important
}
.is-radiusless{
border-radius:0!important
}
.is-shadowless{
box-shadow:none!important
}
.is-unselectable{
-webkit-touch-callout:none;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none
}
.content:not(:last-child){
margin-bottom:1.5rem
}
.content li+li{
margin-top:.25em
}
.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){
margin-bottom:1em
}
.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{
color:#363636;
font-weight:400;
line-height:1.125
}
.content h1{
font-size:2em;
margin-bottom:.5em
}
.content h1:not(:first-child){
margin-top:1em
}
.content h2{
font-size:1.75em;
margin-bottom:.5714em
}
.content h2:not(:first-child){
margin-top:1.1428em
}
.content h3{
font-size:1.5em;
margin-bottom:.6666em
}
.content h3:not(:first-child){
margin-top:1.3333em
}
.content h4{
font-size:1.25em;
margin-bottom:.8em
}
.content h5{
font-size:1.125em;
margin-bottom:.8888em
}
.content h6{
font-size:1em;
margin-bottom:1em
}
.content blockquote{
background-color:#f5f5f5;
border-left:5px solid #dbdbdb;
padding:1.25em 1.5em
}
.content ol{
list-style:decimal outside
}
.content ol,.content ul{
margin-left:2em;
margin-top:1em
}
.content ul{
list-style:disc outside
}
.content ul ul{
list-style-type:circle;
margin-top:.5em
}
.content ul ul ul{
list-style-type:square
}
.content dd{
margin-left:2em
}
.content figure{
margin-left:2em;
margin-right:2em;
text-align:center
}
.content figure:not(:first-child){
margin-top:2em
}
.content figure:not(:last-child){
margin-bottom:2em
}
.content figure img{
display:inline-block
}
.content figure figcaption{
font-style:italic
}
.content pre{
-webkit-overflow-scrolling:touch;
overflow-x:auto;
padding:1.25em 1.5em;
white-space:pre;
word-wrap:normal
}
.content sub,.content sup{
font-size:75%
}
.content table{
width:100%
}
.content table td,.content table th{
border:1px solid #dbdbdb;
border-width:0 0 1px;
padding:.5em .75em;
vertical-align:top
}
.content table th{
color:#363636;
text-align:left
}
.content table tr:hover{
background-color:#f5f5f5
}
.content table thead td,.content table thead th{
border-width:0 0 2px;
color:#363636
}
.content table tfoot td,.content table tfoot th{
border-width:2px 0 0;
color:#363636
}
.content table tbody tr:last-child td,.content table tbody tr:last-child th{
border-bottom-width:0
}
.content.is-small{
font-size:.75rem
}
.content.is-medium{
font-size:1.25rem
}
.content.is-large{
font-size:1.5rem
}
.input,.textarea{
-moz-appearance:none;
-webkit-appearance:none;
-ms-flex-align:center;
align-items:center;
border:1px solid transparent;
border-radius:3px;
box-shadow:none;
display:-ms-inline-flexbox;
display:inline-flex;
font-size:1rem;
height:2.25em;
-ms-flex-pack:start;
justify-content:flex-start;
line-height:1.5;
padding:calc(.375em - 1px) calc(.625em - 1px);
position:relative;
vertical-align:top;
background-color:#fff;
border-color:#dbdbdb;
color:#363636;
box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);
max-width:100%;
width:100%
}
.input.is-active,.input.is-focused,.input:active,.input:focus,.textarea.is-active,.textarea.is-focused,.textarea:active,.textarea:focus{
outline:none
}
.input[disabled],.textarea[disabled]{
cursor:not-allowed
}
.input::-moz-placeholder,.textarea::-moz-placeholder{
color:rgba(54,54,54,.3)
}
.input::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{
color:rgba(54,54,54,.3)
}
.input:-moz-placeholder,.textarea:-moz-placeholder{
color:rgba(54,54,54,.3)
}
.input:-ms-input-placeholder,.textarea:-ms-input-placeholder{
color:rgba(54,54,54,.3)
}
.input.is-hovered,.input:hover,.textarea.is-hovered,.textarea:hover{
border-color:#b5b5b5
}
.input.is-active,.input.is-focused,.input:active,.input:focus,.textarea.is-active,.textarea.is-focused,.textarea:active,.textarea:focus{
border-color:#3273dc;
box-shadow:0 0 0 .125em rgba(50,115,220,.25)
}
.input[disabled],.textarea[disabled]{
background-color:#f5f5f5;
border-color:#f5f5f5;
box-shadow:none;
color:#7a7a7a
}
.input[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder{
color:hsla(0,0%,48%,.3)
}
.input[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder{
color:hsla(0,0%,48%,.3)
}
.input[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder{
color:hsla(0,0%,48%,.3)
}
.input[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder{
color:hsla(0,0%,48%,.3)
}
.input[readonly],.textarea[readonly]{
box-shadow:none
}
.input.is-white,.textarea.is-white{
border-color:#fff
}
.input.is-white.is-active,.input.is-white.is-focused,.input.is-white:active,.input.is-white:focus,.textarea.is-white.is-active,.textarea.is-white.is-focused,.textarea.is-white:active,.textarea.is-white:focus{
box-shadow:0 0 0 .125em hsla(0,0%,100%,.25)
}
.input.is-black,.textarea.is-black{
border-color:#0a0a0a
}
.input.is-black.is-active,.input.is-black.is-focused,.input.is-black:active,.input.is-black:focus,.textarea.is-black.is-active,.textarea.is-black.is-focused,.textarea.is-black:active,.textarea.is-black:focus{
box-shadow:0 0 0 .125em hsla(0,0%,4%,.25)
}
.input.is-light,.textarea.is-light{
border-color:#f5f5f5
}
.input.is-light.is-active,.input.is-light.is-focused,.input.is-light:active,.input.is-light:focus,.textarea.is-light.is-active,.textarea.is-light.is-focused,.textarea.is-light:active,.textarea.is-light:focus{
box-shadow:0 0 0 .125em hsla(0,0%,96%,.25)
}
.input.is-dark,.textarea.is-dark{
border-color:#363636
}
.input.is-dark.is-active,.input.is-dark.is-focused,.input.is-dark:active,.input.is-dark:focus,.textarea.is-dark.is-active,.textarea.is-dark.is-focused,.textarea.is-dark:active,.textarea.is-dark:focus{
box-shadow:0 0 0 .125em rgba(54,54,54,.25)
}
.input.is-primary,.textarea.is-primary{
border-color:#00d1b2
}
.input.is-primary.is-active,.input.is-primary.is-focused,.input.is-primary:active,.input.is-primary:focus,.textarea.is-primary.is-active,.textarea.is-primary.is-focused,.textarea.is-primary:active,.textarea.is-primary:focus{
box-shadow:0 0 0 .125em rgba(0,209,178,.25)
}
.input.is-link,.textarea.is-link{
border-color:#3273dc
}
.input.is-link.is-active,.input.is-link.is-focused,.input.is-link:active,.input.is-link:focus,.textarea.is-link.is-active,.textarea.is-link.is-focused,.textarea.is-link:active,.textarea.is-link:focus{
box-shadow:0 0 0 .125em rgba(50,115,220,.25)
}
.input.is-info,.textarea.is-info{
border-color:#209cee
}
.input.is-info.is-active,.input.is-info.is-focused,.input.is-info:active,.input.is-info:focus,.textarea.is-info.is-active,.textarea.is-info.is-focused,.textarea.is-info:active,.textarea.is-info:focus{
box-shadow:0 0 0 .125em rgba(32,156,238,.25)
}
.input.is-success,.textarea.is-success{
border-color:#23d160
}
.input.is-success.is-active,.input.is-success.is-focused,.input.is-success:active,.input.is-success:focus,.textarea.is-success.is-active,.textarea.is-success.is-focused,.textarea.is-success:active,.textarea.is-success:focus{
box-shadow:0 0 0 .125em rgba(35,209,96,.25)
}
.input.is-warning,.textarea.is-warning{
border-color:#ffdd57
}
.input.is-warning.is-active,.input.is-warning.is-focused,.input.is-warning:active,.input.is-warning:focus,.textarea.is-warning.is-active,.textarea.is-warning.is-focused,.textarea.is-warning:active,.textarea.is-warning:focus{
box-shadow:0 0 0 .125em rgba(255,221,87,.25)
}
.input.is-danger,.textarea.is-danger{
border-color:#ff3860
}
.input.is-danger.is-active,.input.is-danger.is-focused,.input.is-danger:active,.input.is-danger:focus,.textarea.is-danger.is-active,.textarea.is-danger.is-focused,.textarea.is-danger:active,.textarea.is-danger:focus{
box-shadow:0 0 0 .125em rgba(255,56,96,.25)
}
.input.is-small,.textarea.is-small{
border-radius:2px;
font-size:.75rem
}
.input.is-medium,.textarea.is-medium{
font-size:1.25rem
}
.input.is-large,.textarea.is-large{
font-size:1.5rem
}
.input.is-fullwidth,.textarea.is-fullwidth{
display:block;
width:100%
}
.input.is-inline,.textarea.is-inline{
display:inline;
width:auto
}
.input.is-rounded{
border-radius:290486px;
padding-left:1em;
padding-right:1em
}
.input.is-static{
background-color:transparent;
border-color:transparent;
box-shadow:none;
padding-left:0;
padding-right:0
}
.textarea{
display:block;
max-width:100%;
min-width:100%;
padding:.625em;
resize:vertical
}
.textarea:not([rows]){
max-height:600px;
min-height:120px
}
.textarea[rows]{
height:unset
}
.textarea.has-fixed-size{
resize:none
}
.checkbox,.radio{
cursor:pointer;
display:inline-block;
line-height:1.25;
position:relative
}
.checkbox input,.radio input{
cursor:pointer
}
.checkbox:hover,.radio:hover{
color:#363636
}
.checkbox[disabled],.radio[disabled]{
color:#7a7a7a;
cursor:not-allowed
}
.radio+.radio{
margin-left:.5em
}
.select{
display:inline-block;
max-width:100%;
position:relative;
vertical-align:top
}
.select:not(.is-multiple){
height:2.25em
}
.select:not(.is-multiple):after{
border:1px solid #3273dc;
border-right:0;
border-top:0;
content:" ";
display:block;
height:.5em;
pointer-events:none;
position:absolute;
transform:rotate(-45deg);
transform-origin:center;
width:.5em;
margin-top:-.375em;
right:1.125em;
top:50%;
z-index:3
}
.select.is-rounded select{
border-radius:290486px;
padding-left:1em
}
.select select{
-moz-appearance:none;
-webkit-appearance:none;
-ms-flex-align:center;
align-items:center;
border:1px solid transparent;
border-radius:3px;
box-shadow:none;
display:-ms-inline-flexbox;
display:inline-flex;
font-size:1rem;
height:2.25em;
-ms-flex-pack:start;
justify-content:flex-start;
line-height:1.5;
padding:calc(.375em - 1px) calc(.625em - 1px);
position:relative;
vertical-align:top;
background-color:#fff;
border-color:#dbdbdb;
color:#363636;
cursor:pointer;
display:block;
font-size:1em;
max-width:100%;
outline:none
}
.select select.is-active,.select select.is-focused,.select select:active,.select select:focus{
outline:none
}
.select select[disabled]{
cursor:not-allowed
}
.select select::-moz-placeholder{
color:rgba(54,54,54,.3)
}
.select select::-webkit-input-placeholder{
color:rgba(54,54,54,.3)
}
.select select:-moz-placeholder{
color:rgba(54,54,54,.3)
}
.select select:-ms-input-placeholder{
color:rgba(54,54,54,.3)
}
.select select.is-hovered,.select select:hover{
border-color:#b5b5b5
}
.select select.is-active,.select select.is-focused,.select select:active,.select select:focus{
border-color:#3273dc;
box-shadow:0 0 0 .125em rgba(50,115,220,.25)
}
.select select[disabled]{
background-color:#f5f5f5;
border-color:#f5f5f5;
box-shadow:none;
color:#7a7a7a
}
.select select[disabled]::-moz-placeholder{
color:hsla(0,0%,48%,.3)
}
.select select[disabled]::-webkit-input-placeholder{
color:hsla(0,0%,48%,.3)
}
.select select[disabled]:-moz-placeholder{
color:hsla(0,0%,48%,.3)
}
.select select[disabled]:-ms-input-placeholder{
color:hsla(0,0%,48%,.3)
}
.select select::-ms-expand{
display:none
}
.select select[disabled]:hover{
border-color:#f5f5f5
}
.select select:not([multiple]){
padding-right:2.5em
}
.select select[multiple]{
height:unset;
padding:0
}
.select select[multiple] option{
padding:.5em 1em
}
.select:hover:after{
border-color:#363636
}
.select.is-white select{
border-color:#fff
}
.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{
box-shadow:0 0 0 .125em hsla(0,0%,100%,.25)
}
.select.is-black select{
border-color:#0a0a0a
}
.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{
box-shadow:0 0 0 .125em hsla(0,0%,4%,.25)
}
.select.is-light select{
border-color:#f5f5f5
}
.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{
box-shadow:0 0 0 .125em hsla(0,0%,96%,.25)
}
.select.is-dark select{
border-color:#363636
}
.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{
box-shadow:0 0 0 .125em rgba(54,54,54,.25)
}
.select.is-primary select{
border-color:#00d1b2
}
.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{
box-shadow:0 0 0 .125em rgba(0,209,178,.25)
}
.select.is-link select{
border-color:#3273dc
}
.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{
box-shadow:0 0 0 .125em rgba(50,115,220,.25)
}
.select.is-info select{
border-color:#209cee
}
.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{
box-shadow:0 0 0 .125em rgba(32,156,238,.25)
}
.select.is-success select{
border-color:#23d160
}
.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{
box-shadow:0 0 0 .125em rgba(35,209,96,.25)
}
.select.is-warning select{
border-color:#ffdd57
}
.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{
box-shadow:0 0 0 .125em rgba(255,221,87,.25)
}
.select.is-danger select{
border-color:#ff3860
}
.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{
box-shadow:0 0 0 .125em rgba(255,56,96,.25)
}
.select.is-small{
border-radius:2px;
font-size:.75rem
}
.select.is-medium{
font-size:1.25rem
}
.select.is-large{
font-size:1.5rem
}
.select.is-disabled:after{
border-color:#7a7a7a
}
.select.is-fullwidth,.select.is-fullwidth select{
width:100%
}
.select.is-loading:after{
animation:a .5s infinite linear;
border:2px solid #dbdbdb;
border-radius:290486px;
border-right-color:transparent;
border-top-color:transparent;
content:"";
display:block;
height:1em;
position:relative;
width:1em;
margin-top:0;
position:absolute;
right:.625em;
top:.625em;
transform:none
}
.select.is-loading.is-small:after{
font-size:.75rem
}
.select.is-loading.is-medium:after{
font-size:1.25rem
}
.select.is-loading.is-large:after{
font-size:1.5rem
}
.file{
-webkit-touch-callout:none;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
-ms-flex-align:stretch;
align-items:stretch;
display:-ms-flexbox;
display:flex;
-ms-flex-pack:start;
justify-content:flex-start;
position:relative
}
.file.is-white .file-cta{
background-color:#fff;
border-color:transparent;
color:#0a0a0a
}
.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{
background-color:#f9f9f9;
border-color:transparent;
color:#0a0a0a
}
.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em hsla(0,0%,100%,.25);
color:#0a0a0a
}
.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{
background-color:#f2f2f2;
border-color:transparent;
color:#0a0a0a
}
.file.is-black .file-cta{
background-color:#0a0a0a;
border-color:transparent;
color:#fff
}
.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{
background-color:#040404;
border-color:transparent;
color:#fff
}
.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em hsla(0,0%,4%,.25);
color:#fff
}
.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{
background-color:#000;
border-color:transparent;
color:#fff
}
.file.is-light .file-cta{
background-color:#f5f5f5;
border-color:transparent;
color:#363636
}
.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{
background-color:#eee;
border-color:transparent;
color:#363636
}
.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em hsla(0,0%,96%,.25);
color:#363636
}
.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{
background-color:#e8e8e8;
border-color:transparent;
color:#363636
}
.file.is-dark .file-cta{
background-color:#363636;
border-color:transparent;
color:#f5f5f5
}
.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{
background-color:#2f2f2f;
border-color:transparent;
color:#f5f5f5
}
.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(54,54,54,.25);
color:#f5f5f5
}
.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{
background-color:#292929;
border-color:transparent;
color:#f5f5f5
}
.file.is-primary .file-cta{
background-color:#00d1b2;
border-color:transparent;
color:#fff
}
.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{
background-color:#00c4a7;
border-color:transparent;
color:#fff
}
.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(0,209,178,.25);
color:#fff
}
.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{
background-color:#00b89c;
border-color:transparent;
color:#fff
}
.file.is-link .file-cta{
background-color:#3273dc;
border-color:transparent;
color:#fff
}
.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{
background-color:#276cda;
border-color:transparent;
color:#fff
}
.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(50,115,220,.25);
color:#fff
}
.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{
background-color:#2366d1;
border-color:transparent;
color:#fff
}
.file.is-info .file-cta{
background-color:#209cee;
border-color:transparent;
color:#fff
}
.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{
background-color:#1496ed;
border-color:transparent;
color:#fff
}
.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(32,156,238,.25);
color:#fff
}
.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{
background-color:#118fe4;
border-color:transparent;
color:#fff
}
.file.is-success .file-cta{
background-color:#23d160;
border-color:transparent;
color:#fff
}
.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{
background-color:#22c65b;
border-color:transparent;
color:#fff
}
.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(35,209,96,.25);
color:#fff
}
.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{
background-color:#20bc56;
border-color:transparent;
color:#fff
}
.file.is-warning .file-cta{
background-color:#ffdd57;
border-color:transparent;
color:rgba(0,0,0,.7)
}
.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{
background-color:#ffdb4a;
border-color:transparent;
color:rgba(0,0,0,.7)
}
.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(255,221,87,.25);
color:rgba(0,0,0,.7)
}
.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{
background-color:#ffd83d;
border-color:transparent;
color:rgba(0,0,0,.7)
}
.file.is-danger .file-cta{
background-color:#ff3860;
border-color:transparent;
color:#fff
}
.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{
background-color:#ff2b56;
border-color:transparent;
color:#fff
}
.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{
border-color:transparent;
box-shadow:0 0 .5em rgba(255,56,96,.25);
color:#fff
}
.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{
background-color:#ff1f4b;
border-color:transparent;
color:#fff
}
.file.is-small{
font-size:.75rem
}
.file.is-medium{
font-size:1.25rem
}
.file.is-medium .file-icon .fa{
font-size:21px
}
.file.is-large{
font-size:1.5rem
}
.file.is-large .file-icon .fa{
font-size:28px
}
.file.has-name .file-cta{
border-bottom-right-radius:0;
border-top-right-radius:0
}
.file.has-name .file-name{
border-bottom-left-radius:0;
border-top-left-radius:0
}
.file.has-name.is-empty .file-cta{
border-radius:3px
}
.file.has-name.is-empty .file-name{
display:none
}
.file.is-boxed .file-cta,.file.is-boxed .file-label{
-ms-flex-direction:column;
flex-direction:column
}
.file.is-boxed .file-cta{
height:auto;
padding:1em 3em
}
.file.is-boxed .file-name{
border-width:0 1px 1px
}
.file.is-boxed .file-icon{
height:1.5em;
width:1.5em
}
.file.is-boxed .file-icon .fa{
font-size:21px
}
.file.is-boxed.is-small .file-icon .fa{
font-size:14px
}
.file.is-boxed.is-medium .file-icon .fa{
font-size:28px
}
.file.is-boxed.is-large .file-icon .fa{
font-size:35px
}
.file.is-boxed.has-name .file-cta{
border-radius:3px 3px 0 0
}
.file.is-boxed.has-name .file-name{
border-radius:0 0 3px 3px;
border-width:0 1px 1px
}
.file.is-centered{
-ms-flex-pack:center;
justify-content:center
}
.file.is-fullwidth .file-label{
width:100%
}
.file.is-fullwidth .file-name{
-ms-flex-positive:1;
flex-grow:1;
max-width:none
}
.file.is-right{
-ms-flex-pack:end;
justify-content:flex-end
}
.file.is-right .file-cta{
border-radius:0 3px 3px 0
}
.file.is-right .file-name{
border-radius:3px 0 0 3px;
border-width:1px 0 1px 1px;
-ms-flex-order:-1;
order:-1
}
.file-label{
-ms-flex-align:stretch;
align-items:stretch;
display:-ms-flexbox;
display:flex;
cursor:pointer;
-ms-flex-pack:start;
justify-content:flex-start;
overflow:hidden;
position:relative
}
.file-label:hover .file-cta{
background-color:#eee;
color:#363636
}
.file-label:hover .file-name{
border-color:#d5d5d5
}
.file-label:active .file-cta{
background-color:#e8e8e8;
color:#363636
}
.file-label:active .file-name{
border-color:#cfcfcf
}
.file-input{
height:.01em;
left:0;
outline:none;
position:absolute;
top:0;
width:.01em
}
.file-cta,.file-name{
-moz-appearance:none;
-webkit-appearance:none;
-ms-flex-align:center;
align-items:center;
border:1px solid transparent;
box-shadow:none;
display:-ms-inline-flexbox;
display:inline-flex;
font-size:1rem;
height:2.25em;
-ms-flex-pack:start;
justify-content:flex-start;
line-height:1.5;
padding-left:calc(.625em - 1px);
padding-right:calc(.625em - 1px);
position:relative;
vertical-align:top;
border-color:#dbdbdb;
border-radius:3px;
font-size:1em;
padding:calc(.375em - 1px) 1em;
white-space:nowrap
}
.file-cta.is-active,.file-cta.is-focused,.file-cta:active,.file-cta:focus,.file-name.is-active,.file-name.is-focused,.file-name:active,.file-name:focus{
outline:none
}
.file-cta[disabled],.file-name[disabled]{
cursor:not-allowed
}
.file-cta{
background-color:#f5f5f5;
color:#4a4a4a
}
.file-name{
border-color:#dbdbdb;
border-style:solid;
border-width:1px 1px 1px 0;
display:block;
max-width:16em;
overflow:hidden;
text-align:left;
text-overflow:ellipsis
}
.file-icon{
-ms-flex-align:center;
align-items:center;
display:-ms-flexbox;
display:flex;
height:1em;
-ms-flex-pack:center;
justify-content:center;
margin-right:.5em;
width:1em
}
.file-icon .fa{
font-size:14px
}
.label{
color:#363636;
display:block;
font-size:1rem;
font-weight:700
}
.label:not(:last-child){
margin-bottom:.5em
}
.label.is-small{
font-size:.75rem
}
.label.is-medium{
font-size:1.25rem
}
.label.is-large{
font-size:1.5rem
}
.help{
display:block;
font-size:.75rem;
margin-top:.25rem
}
.help.is-white{
color:#fff
}
.help.is-black{
color:#0a0a0a
}
.help.is-light{
color:#f5f5f5
}
.help.is-dark{
color:#363636
}
.help.is-primary{
color:#00d1b2
}
.help.is-link{
color:#3273dc
}
.help.is-info{
color:#209cee
}
.help.is-success{
color:#23d160
}
.help.is-warning{
color:#ffdd57
}
.help.is-danger{
color:#ff3860
}
.field:not(:last-child){
margin-bottom:.75rem
}
.field.has-addons{
display:-ms-flexbox;
display:flex;
-ms-flex-pack:start;
justify-content:flex-start
}
.field.has-addons .control:not(:last-child){
margin-right:-1px
}
.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{
border-radius:0
}
.field.has-addons .control:first-child .button,.field.has-addons .control:first-child .input,.field.has-addons .control:first-child .select select{
border-bottom-right-radius:0;
border-top-right-radius:0
}
.field.has-addons .control:last-child .button,.field.has-addons .control:last-child .input,.field.has-addons .control:last-child .select select{
border-bottom-left-radius:0;
border-top-left-radius:0
}
.field.has-addons .control .button.is-hovered,.field.has-addons .control .button:hover,.field.has-addons .control .input.is-hovered,.field.has-addons .control .input:hover,.field.has-addons .control .select select.is-hovered,.field.has-addons .control .select select:hover{
z-index:1
}
.field.has-addons .control .button.is-active,.field.has-addons .control .button.is-focused,.field.has-addons .control .button:active,.field.has-addons .control .button:focus,.field.has-addons .control .input.is-active,.field.has-addons .control .input.is-focused,.field.has-addons .control .input:active,.field.has-addons .control .input:focus,.field.has-addons .control .select select.is-active,.field.has-addons .control .select select.is-focused,.field.has-addons .control .select select:active,.field.has-addons .control .select select:focus{
z-index:2
}
.field.has-addons .control .button.is-active:hover,.field.has-addons .control .button.is-focused:hover,.field.has-addons .control .button:active:hover,.field.has-addons .control .button:focus:hover,.field.has-addons .control .input.is-active:hover,.field.has-addons .control .input.is-focused:hover,.field.has-addons .control .input:active:hover,.field.has-addons .control .input:focus:hover,.field.has-addons .control .select select.is-active:hover,.field.has-addons .control .select select.is-focused:hover,.field.has-addons .control .select select:active:hover,.field.has-addons .control .select select:focus:hover{
z-index:3
}
.field.has-addons .control.is-expanded{
-ms-flex-positive:1;
flex-grow:1
}
.field.has-addons.has-addons-centered{
-ms-flex-pack:center;
justify-content:center
}
.field.has-addons.has-addons-right{
-ms-flex-pack:end;
justify-content:flex-end
}
.field.has-addons.has-addons-fullwidth .control{
-ms-flex-positive:1;
flex-grow:1;
-ms-flex-negative:0;
flex-shrink:0
}
.field.is-grouped{
display:-ms-flexbox;
display:flex;
-ms-flex-pack:start;
justify-content:flex-start
}
.field.is-grouped>.control{
-ms-flex-negative:0;
flex-shrink:0
}
.field.is-grouped>.control:not(:last-child){
margin-bottom:0;
margin-right:.75rem
}
.field.is-grouped>.control.is-expanded{
-ms-flex-positive:1;
flex-grow:1;
-ms-flex-negative:1;
flex-shrink:1
}
.field.is-grouped.is-grouped-centered{
-ms-flex-pack:center;
justify-content:center
}
.field.is-grouped.is-grouped-right{
-ms-flex-pack:end;
justify-content:flex-end
}
.field.is-grouped.is-grouped-multiline{
-ms-flex-wrap:wrap;
flex-wrap:wrap
}
.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){
margin-bottom:.75rem
}
.field.is-grouped.is-grouped-multiline:last-child{
margin-bottom:-.75rem
}
.field.is-grouped.is-grouped-multiline:not(:last-child){
margin-bottom:0
}
@media print,screen and (min-width:769px){
.field.is-horizontal{
display:-ms-flexbox;
display:flex
}
}
.field-label .label{
font-size:inherit
}
@media screen and (max-width:768px){
.field-label{
margin-bottom:.5rem
}
}
@media print,screen and (min-width:769px){
.field-label{
-ms-flex-preferred-size:0;
flex-basis:0;
-ms-flex-positive:1;
flex-grow:1;
-ms-flex-negative:0;
flex-shrink:0;
margin-right:1.5rem;
text-align:right
}
.field-label.is-small{
font-size:.75rem;
padding-top:.375em
}
.field-label.is-normal{
padding-top:.375em
}
.field-label.is-medium{
font-size:1.25rem;
padding-top:.375em
}
.field-label.is-large{
font-size:1.5rem;
padding-top:.375em
}
}
.field-body .field .field{
margin-bottom:0
}
@media print,screen and (min-width:769px){
.field-body{
display:-ms-flexbox;
display:flex;
-ms-flex-preferred-size:0;
flex-basis:0;
-ms-flex-positive:5;
flex-grow:5;
-ms-flex-negative:1;
flex-shrink:1
}
.field-body .field{
margin-bottom:0
}
.field-body>.field{
-ms-flex-negative:1;
flex-shrink:1
}
.field-body>.field:not(.is-narrow){
-ms-flex-positive:1;
flex-grow:1
}
.field-body>.field:not(:last-child){
margin-right:.75rem
}
}
.control{
font-size:1rem;
position:relative;
text-align:left
}
.control.has-icon .icon{
color:#dbdbdb;
height:2.25em;
pointer-events:none;
position:absolute;
top:0;
width:2.25em;
z-index:3
}
.control.has-icon .input:focus+.icon{
color:#7a7a7a
}
.control.has-icon .input.is-small+.icon{
font-size:.75rem
}
.control.has-icon .input.is-medium+.icon{
font-size:1.25rem
}
.control.has-icon .input.is-large+.icon{
font-size:1.5rem
}
.control.has-icon:not(.has-icon-right) .icon{
left:0
}
.control.has-icon:not(.has-icon-right) .input{
padding-left:2.25em
}
.control.has-icon.has-icon-right .icon{
right:0
}
.control.has-icon.has-icon-right .input{
padding-right:2.25em
}
.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{
color:#7a7a7a
}
.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{
font-size:.75rem
}
.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{
font-size:1.25rem
}
.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{
font-size:1.5rem
}
.control.has-icons-left .icon,.control.has-icons-right .icon{
color:#dbdbdb;
height:2.25em;
pointer-events:none;
position:absolute;
top:0;
width:2.25em;
z-index:3
}
.control.has-icons-left .input,.control.has-icons-left .select select{
padding-left:2.25em
}
.control.has-icons-left .icon.is-left{
left:0
}
.control.has-icons-right .input,.control.has-icons-right .select select{
padding-right:2.25em
}
.control.has-icons-right .icon.is-right{
right:0
}
.control.is-loading:after{
animation:a .5s infinite linear;
border:2px solid #dbdbdb;
border-radius:290486px;
border-right-color:transparent;
border-top-color:transparent;
content:"";
display:block;
height:1em;
position:relative;
width:1em;
position:absolute!important;
right:.625em;
top:.625em;
z-index:3
}
.control.is-loading.is-small:after{
font-size:.75rem
}
.control.is-loading.is-medium:after{
font-size:1.25rem
}
.control.is-loading.is-large:after{
font-size:1.5rem
}
.subtitle,.title{
word-break:break-word
}
.subtitle:not(:last-child),.title:not(:last-child){
margin-bottom:1.5rem
}
.subtitle em,.subtitle span,.title em,.title span{
font-weight:inherit
}
.subtitle sub,.subtitle sup,.title sub,.title sup{
font-size:.75em
}
.subtitle .tag,.title .tag{
vertical-align:middle
}
.title{
color:#363636;
font-size:2rem;
font-weight:600;
line-height:1.125
}
.title strong{
color:inherit;
font-weight:inherit
}
.title+.highlight{
margin-top:-.75rem
}
.title:not(.is-spaced)+.subtitle{
margin-top:-1.5rem
}
.title.is-1{
font-size:3rem
}
.title.is-2{
font-size:2.5rem
}
.title.is-3{
font-size:2rem
}
.title.is-4{
font-size:1.5rem
}
.title.is-5{
font-size:1.25rem
}
.title.is-6{
font-size:1rem
}
.title.is-7{
font-size:.75rem
}
.subtitle{
color:#4a4a4a;
font-size:1.25rem;
font-weight:400;
line-height:1.25
}
.subtitle strong{
color:#363636;
font-weight:600
}
.subtitle:not(.is-spaced)+.title{
margin-top:-1.5rem
}
.subtitle.is-1{
font-size:3rem
}
.subtitle.is-2{
font-size:2.5rem
}
.subtitle.is-3{
font-size:2rem
}
.subtitle.is-4{
font-size:1.5rem
}
.subtitle.is-5{
font-size:1.25rem
}
.subtitle.is-6{
font-size:1rem
}
.subtitle.is-7{
font-size:.75rem
}
.message{
background-color:#f5f5f5;
border-radius:3px;
font-size:1rem
}
.message:not(:last-child){
margin-bottom:1.5rem
}
.message strong{
color:currentColor
}
.message a:not(.button):not(.tag){
color:currentColor;
text-decoration:underline
}
.message.is-small{
font-size:.75rem
}
.message.is-medium{
font-size:1.25rem
}
.message.is-large{
font-size:1.5rem
}
.message.is-white{
background-color:#fff
}
.message.is-white .message-header{
background-color:#fff;
color:#0a0a0a
}
.message.is-white .message-body{
border-color:#fff;
color:#4d4d4d
}
.message.is-black{
background-color:#fafafa
}
.message.is-black .message-header{
background-color:#0a0a0a;
color:#fff
}
.message.is-black .message-body{
border-color:#0a0a0a;
color:#090909
}
.message.is-light{
background-color:#fafafa
}
.message.is-light .message-header{
background-color:#f5f5f5;
color:#363636
}
.message.is-light .message-body{
border-color:#f5f5f5;
color:#505050
}
.message.is-dark{
background-color:#fafafa
}
.message.is-dark .message-header{
background-color:#363636;
color:#f5f5f5
}
.message.is-dark .message-body{
border-color:#363636;
color:#2a2a2a
}
.message.is-primary{
background-color:#f5fffd
}
.message.is-primary .message-header{
background-color:#00d1b2;
color:#fff
}
.message.is-primary .message-body{
border-color:#00d1b2;
color:#021310
}
.message.is-link{
background-color:#f6f9fe
}
.message.is-link .message-header{
background-color:#3273dc;
color:#fff
}
.message.is-link .message-body{
border-color:#3273dc;
color:#22509a
}
.message.is-info{
background-color:#f6fbfe
}
.message.is-info .message-header{
background-color:#209cee;
color:#fff
}
.message.is-info .message-body{
border-color:#209cee;
color:#12537e
}
.message.is-success{
background-color:#f6fef9
}
.message.is-success .message-header{
background-color:#23d160;
color:#fff
}
.message.is-success .message-body{
border-color:#23d160;
color:#0e301a
}
.message.is-warning{
background-color:#fffdf5
}
.message.is-warning .message-header{
background-color:#ffdd57;
color:rgba(0,0,0,.7)
}
.message.is-warning .message-body{
border-color:#ffdd57;
color:#3b3108
}
.message.is-danger{
background-color:#fff5f7
}
.message.is-danger .message-header{
background-color:#ff3860;
color:#fff
}
.message.is-danger .message-body{
border-color:#ff3860;
color:#cd0930
}
.message-header{
-ms-flex-align:center;
align-items:center;
background-color:#4a4a4a;
border-radius:3px 3px 0 0;
color:#fff;
display:-ms-flexbox;
display:flex;
-ms-flex-pack:justify;
justify-content:space-between;
line-height:1.25;
padding:.5em .75em;
position:relative
}
.message-header .delete{
-ms-flex-positive:0;
flex-grow:0;
-ms-flex-negative:0;
flex-shrink:0;
margin-left:.75em
}
.message-header+.message-body{
border-top-left-radius:0;
border-top-right-radius:0;
border-top:none
}
.message-body{
border:1px solid #dbdbdb;
border-radius:3px;
color:#4a4a4a;
padding:1em 1.25em
}
.message-body code,.message-body pre{
background-color:#fff
}
.message-body pre code{
background-color:transparent
}
.block:not(:last-child),.detect:not(:last-child),.instructions:not(:last-child),.snippet:not(:last-child),.stabs:not(:last-child),.table-container:not(:last-child),div.case:not(:last-child){
margin-bottom:1.5rem
}
::-moz-selection{
background-color:#ffe270
}
::selection{
background-color:#ffe270
}
@font-face{
font-family:Archia;
src:url(https://jgthms.com/fonts/archia-regular-webfont.eot);
src:url(https://jgthms.com/fonts/archia-regular-webfont.eot#iefix) format("embedded-opentype"),url(https://jgthms.com/fonts/archia-regular-webfont.woff2) format("woff2"),url(https://jgthms.com/fonts/archia-regular-webfont.woff) format("woff"),url(https://jgthms.com/fonts/archia-regular-webfont.ttf) format("truetype");
font-weight:400;
font-style:normal
}
@font-face{
font-family:Archia;
src:url(https://jgthms.com/fonts/archia-semibold-webfont.eot);
src:url(https://jgthms.com/fonts/archia-semibold-webfont.eot#iefix) format("embedded-opentype"),url(https://jgthms.com/fonts/archia-semibold-webfont.woff2) format("woff2"),url(https://jgthms.com/fonts/archia-semibold-webfont.woff) format("woff"),url(https://jgthms.com/fonts/archia-semibold-webfont.ttf) format("truetype");
font-weight:600;
font-style:normal
}
body{
padding-bottom:50vh
}
.main{
margin-left:auto;
margin-right:auto;
max-width:29rem
}
.snippet{
position:relative
}
.snippet-copy{
color:#909197;
font-size:.75em;
white-space:nowrap
}
@media screen and (max-width:699px){
.snippet-contents{
margin-bottom:.5rem
}
}
@media screen and (min-width:700px){
.snippet{
margin-left:-1.5rem;
margin-right:-1.5rem
}
.snippet-copy{
left:calc(100% + 1.5rem);
position:absolute;
top:21px
}
}
.header,.step{
padding:2rem
}
#step39{
text-align:center
}
#step39 .newsletter-content{
text-align:left
}
.status{
margin-bottom:1.5rem
}
.detect{
background-color:#f5f5f5;
border-radius:3px;
padding:1.25em 1.5em
}
.fourteen{
-ms-flex-align:end;
align-items:flex-end;
background-color:#ffe270;
color:#000;
display:-ms-inline-flexbox;
display:inline-flex;
height:4rem;
-ms-flex-pack:end;
justify-content:flex-end;
padding-right:2px;
width:4rem
}
.button{
-moz-appearance:none;
-webkit-appearance:none;
background-color:#2795ee;
border:none;
border-radius:3px;
color:#fff;
cursor:pointer;
display:inline-block;
font-size:1rem;
padding:.5em 1em;
vertical-align:top
}
.gj{
min-height:40px;
position:relative
}
.check{
-ms-flex-align:center;
align-items:center;
animation-delay:1.2s;
animation-duration:.29s;
animation-name:d;
animation-timing-function:ease-in-out;
display:-ms-flexbox;
display:flex;
height:40px;
-ms-flex-pack:center;
justify-content:center;
transform-origin:center;
width:40px
}
@media screen and (max-width:699px){
.check{
margin-bottom:10px
}
}
@media screen and (min-width:700px){
.check,.content h2 .stamp{
position:absolute;
right:calc(100% + 1rem)
}
.check{
top:-5px
}
.content h2 .stamp{
top:3px
}
}
.check-circle{
animation-duration:1s;
animation-fill-mode:both;
animation-name:b;
animation-timing-function:cubic-bezier(0,1,.6,1.08);
background-color:#87ffe1;
border-radius:290486px;
height:40px;
transform-origin:center;
width:40px
}
.check-circle,.check-svg{
position:absolute
}
.check-svg svg{
dipslay:block
}
.check-svg polyline{
animation-delay:.25s;
animation-duration:.5s;
animation-fill-mode:forwards;
animation-name:c;
stroke-dasharray:26;
stroke-dashoffset:26
}
@keyframes b{
0%{
transform:scale(0)
}
to{
transform:scale(1)
}
}
@keyframes c{
to{
stroke-dashoffset:0
}
}
@keyframes d{
0%,to{
transform:scale(1)
}
50%{
transform:scale(1.1)
}
}
.sides{
animation-duration:.5s;
animation-fill-mode:both;
background-color:#fff;
border-radius:5px;
bottom:5vw;
display:none;
padding:1rem;
padding-right:2rem;
position:fixed;
right:5vw;
transform-origin:bottom right;
width:10rem;
z-index:4
}
.sides.is-active{
animation-name:b;
display:block
}
@media screen and (max-width:999px){
.sides,.sides.is-active{
display:none
}
}
.side{
display:none;
white-space:nowrap
}
.side.is-active{
display:block
}
.side-title{
font-size:1.5rem
}
.side-item{
animation-duration:1s;
color:#363636;
display:none;
font-size:.875rem;
padding:.25em .5em
}
.side-item.is-active{
animation-name:e;
display:block
}
.step{
animation-duration:1s;
display:none
}
.step.is-active{
animation-name:e;
display:block
}
.thing{
display:none
}
.thing.is-active{
display:block
}
.case{
display:none
}
html.case-mobile div.case.is-mobile{
display:block
}
html.case-mobile span.case.is-mobile{
display:inline
}
html.case-mobile .not-mobile{
display:none!important
}
html.case-tablet div.case.is-tablet{
display:block
}
html.case-tablet span.case.is-tablet{
display:inline
}
html.case-tablet .not-tablet{
display:none!important
}
html.case-desktop div.case.is-desktop{
display:block
}
html.case-desktop span.case.is-desktop{
display:inline
}
html.case-desktop .not-desktop{
display:none!important
}
html.case-windows div.case.is-windows{
display:block
}
html.case-windows span.case.is-windows{
display:inline
}
html.case-windows .not-windows{
display:none!important
}
html.case-mac div.case.is-mac{
display:block
}
html.case-mac span.case.is-mac{
display:inline
}
html.case-mac .not-mac{
display:none!important
}
html.case-linux div.case.is-linux{
display:block
}
html.case-linux span.case.is-linux{
display:inline
}
html.case-linux .not-linux{
display:none!important
}
html.case-chrome div.case.is-chrome{
display:block
}
html.case-chrome span.case.is-chrome{
display:inline
}
html.case-chrome .not-chrome{
display:none!important
}
html.case-firefox div.case.is-firefox{
display:block
}
html.case-firefox span.case.is-firefox{
display:inline
}
html.case-firefox .not-firefox{
display:none!important
}
html.case-safari div.case.is-safari{
display:block
}
html.case-safari span.case.is-safari{
display:inline
}
html.case-safari .not-safari{
display:none!important
}
html.case-edge div.case.is-edge{
display:block
}
html.case-edge span.case.is-edge{
display:inline
}
html.case-edge .not-edge{
display:none!important
}
html.case-opera div.case.is-opera{
display:block
}
html.case-opera span.case.is-opera{
display:inline
}
html.case-opera .not-opera{
display:none!important
}
.stamp{
border-radius:2px;
color:hsla(0,0%,4%,.6);
font-size:.875rem;
line-height:1;
padding:.25em .5em;
padding-top:calc(.25em + 1px);
vertical-align:middle
}
.stamp.is-type{
background-color:#ffa270
}
.stamp.is-tool{
background-color:#eac9ff
}
.stamp.is-info{
background-color:#a8d8ff
}
.stamp.is-concept{
background-color:#ffe270
}
.stamp.is-victory{
background-color:#87ffe1
}
.button,.content h2,.content h3,.label,.share,.side,.snippet-copy,.stab:before,.subtitle,.title{
font-family:Archia,sans-serif;
font-weight:600
}
.title{
font-size:1.875rem
}
.title:not(.is-spaced)+.subtitle{
margin-top:-1.25rem
}
.share em,.subtitle{
font-weight:400
}
.subtitle a{
color:#ff3860
}
.subtitle a:hover{
color:#363636
}
.message-body,.panorama,.sides{
box-shadow:0 2rem 4rem -1rem rgba(0,0,0,.2)
}
.message a:not(.button):not(.tag){
border-bottom:2px solid rgba(0,0,0,.1);
text-decoration:none
}
.message a:not(.button):not(.tag):hover{
border-bottom-color:currentColor
}
.message-body{
border-width:0 0 0 5px
}
.message-body p:not(:last-child){
margin-bottom:.5em
}
#return{
display:none
}
#return.is-active{
display:block
}
.table-container{
-webkit-overflow-scrolling:touch;
overflow:auto;
overflow-y:hidden;
max-width:100%
}
.stabs{
border:1px solid #dbdbdb;
box-shadow:0 0 0 5px #f3f5f6;
border-radius:5px;
counter-reset:a
}
.stabs.is-vertical .stab .stabilo{
white-space:normal
}
.stab{
box-shadow:inset 0 -5px 10px #f3f5f6;
counter-increment:a;
display:-ms-flexbox;
display:flex;
-ms-flex-direction:column;
flex-direction:column;
padding:1em;
position:relative;
width:100%
}
.stab:not(:last-child){
border-bottom:1px solid #dbdbdb
}
.stab:before{
content:counter(a);
font-size:.875em;
line-height:1.5rem;
opacity:.5;
position:absolute;
right:calc(100% + 1em);
top:1rem
}
.stab-label{
-ms-flex-positive:1;
flex-grow:1;
-ms-flex-negative:1;
flex-shrink:1;
font-size:.875em;
padding-right:1em
}
.stab-code{
-ms-flex-positive:0;
flex-grow:0;
-ms-flex-negative:0;
flex-shrink:0
}
@media screen and (min-width:600px){
.stabs:not(.is-vertical) .stab{
-ms-flex-direction:row;
flex-direction:row
}
}
.shares{
-ms-flex-align:stretch;
align-items:stretch;
display:-ms-flexbox;
display:flex;
-ms-flex-wrap:wrap;
flex-wrap:wrap;
-ms-flex-pack:justify;
justify-content:space-between;
margin-bottom:1.5rem;
margin-top:1.5rem
}
:root{
--html:#ff470f;
--css:#00d1b2;
--github:#333;
--facebook:#3b5998;
--twitter:#55acee;
--whatsapp:#25d366;
--patreon:#f96854;
--paypal:#012169;
--fortyfour:#5f45bb;
--bulma:#00d1b2;
--udemy:#ec5252;
--hn:#f60;
--reddit:#5f99cf
}
.share{
border-radius:5px;
color:var(--brand);
margin-bottom:1rem;
padding:1.5em 0 1.75em;
position:relative;
text-align:center;
transition-duration:.2s;
transition-property:background-color;
width:calc(50% - .5rem)
}
.share:before{
bottom:0;
left:0;
position:absolute;
right:0;
top:0;
border:3px solid var(--brand);
border-radius:5px;
content:"";
opacity:.1
}
.share span{
display:block
}
.share svg{
height:2em;
width:2em
}
.share svg path{
fill:currentColor
}
.share em{
font-size:.75em;
font-style:normal;
opacity:.5;
position:relative
}
.share strong{
display:block;
position:relative
}
.share:hover{
background-color:var(--brand);
color:#fff
}
.share.is-html{
--brand:var(--html)
}
.share.is-css{
--brand:var(--css)
}
.share.is-github{
--brand:var(--github)
}
.share.is-facebook{
--brand:var(--facebook)
}
.share.is-twitter{
--brand:var(--twitter)
}
.share.is-whatsapp{
--brand:var(--whatsapp)
}
.share.is-paypal{
--brand:var(--paypal)
}
.share.is-patreon{
--brand:var(--patreon)
}
.share.is-fortyfour{
--brand:var(--fortyfour);
width:auto
}
.share.is-bulma{
--brand:var(--bulma);
width:auto
}
.share.is-hn{
--brand:var(--hn);
margin-bottom:0
}
.share.is-reddit{
--brand:var(--reddit);
margin-bottom:0
}
.share.is-css:hover img,.share.is-html:hover img,.share.is-paypal:hover img{
mix-blend-mode:screen
}
.share.is-patreon,.share.is-paypal{
width:100%
}
.share.is-patreon em,.share.is-paypal em{
font-size:1em
}
.share.is-patreon strong,.share.is-paypal strong{
display:inline
}
.share.is-udemy{
padding-bottom:1em;
padding-top:0
}
.share.is-udemy em{
color:#7a7a7a;
opacity:1
}
.share.is-udemy:hover{
background-color:#f5f5f5;
color:#363636
}
.share.is-udemy-advanced{
width:100%
}
.content kbd{
-moz-osx-font-smoothing:auto;
-webkit-font-smoothing:auto;
font-family:monospace;
font-size:.875em;
font-weight:400
}
.content kbd.key{
background-color:#f5f5f5;
border:1px solid #dbdbdb;
border-radius:3px;
box-shadow:0 1px 0 hsla(0,0%,4%,.2),inset 0 0 0 1px #fff;
color:#b86bff;
padding:.25em .5em
}
.content h2{
font-size:1.5em;
padding-top:0;
position:relative
}
.content h3{
color:#ff3860;
font-size:1.125em;
margin:1em 0
}
.content table{
border:1px solid #dbdbdb
}
.content pre{
padding:1.25rem 1.5rem
}
.content li a,.content p a{
border-bottom:2px solid rgba(50,115,220,.1);
padding-bottom:2px
}
.content li a:hover,.content p a:hover{
border-bottom-color:#3273dc
}
.content li a[target=_blank]:after,.content p a[target=_blank]:after{
content:"??";
font-size:.75em;
margin-left:.5em;
margin-right:.25em
}
.content .label{
font-size:.875em
}
.content .label:not(:last-child){
margin-bottom:.5em
}
.content .focus{
margin:2em 0;
text-align:center
}
.content .focus a{
display:inline-block;
vertical-align:top
}
.content .focus a[target=_blank]:after{
display:none
}
.content .focus a.share{
border-bottom:none;
width:100%
}
.content .madeby{
color:#7a7a7a;
font-size:.875em
}
.content .madeby a[target=_blank]:after{
content:"??"
}
.content .panorama{
display:block;
margin-bottom:3rem
}
.content .panorama img{
display:block
}
.content .stabilo{
background-color:transparent;
color:#dbdbdb;
white-space:nowrap
}
.content .stabilo span{
background-color:#f3f5f6
}
.content .stabilo span.is-blue{
color:#2795ee
}
.content .stabilo span.is-black{
color:#39464e
}
.content .stabilo span.is-green{
color:#249d7f
}
.content .stabilo span.is-red{
color:#ed5c65
}
.content .stabilo span.is-purple{
color:#a151d2
}
.content .newsletter{
background-color:#fff8f1;
border-radius:5px;
margin-bottom:1.5rem;
padding:2rem
}
.content .newsletter h3{
margin-top:0
}
.content .newsletter .help em{
color:hsla(0,0%,4%,.5);
font-style:normal
}
@keyframes e{
0%{
background-color:#ffffe0
}
to{
background-color:transparent
}
}
.highlight{
background-color:#f3f5f6;
border-radius:3px
}
.highlight .highlight{
background:none;
color:orange
}
.highlight .highlight .kd{
color:#a151d2
}
.highlight .highlight .mi{
color:#ed5c65
}
.highlight .highlight .nx{
color:#2795ee
}
.highlight .highlight .p{
color:#39464e
}
.highlight .highlight .s1{
color:#249d7f
}
.highlight .highlight .nb{
color:#2795ee
}
.highlight .highlight .k,.highlight .highlight .kc,.highlight .highlight .o{
color:#a151d2
}
</style>
</head>
<body>
<main class="main">
<header class="header">
<h1 class="title">JavaScript in <strong class="fourteen">14</strong> minutes</h1>
<p class="subtitle">by <a href="https://jgthms.com" target="_blank">Jeremy Thomas</a></p>
<div class="block">
<a href="https://bulma.io" target="_blank">
<img src="https://jgthms.com/javascript-in-14-minutes/images/made-with-bulma.png" alt="Made with Bulma" width="128" height="24">
</a>
</div>
<div class="content">
<p>Since you've already learned <a href="https://jgthms.com/web-design-in-4-minutes/" target="_blank">Web design in 4 minutes</a>, it's time to dive into the Web's main programming language: <strong>JavaScript</strong>.</p>
</div>
<!-- Case: noscript -->
<noscript>
<div class="message is-warning">
<div class="message-body">
To learn JavaScript, you need to enable it first!
<br>
<a href="https://www.enable-javascript.com/" target="_blank" rel="nofollow">Learn how to enable JavaScript in your web browser</a>.
</div>
</div>
<style type="text/css">#introduction{ display: none; }</style>
</noscript>
<!-- Case: mobile or tablet -->
<div class="case is-mobile is-tablet">
<div class="message is-warning">
<div class="message-body">
<p>
It looks like you're on a <strong><span class="case is-mobile">mobile device</span> <span class="case is-tablet">tablet</span></strong>! ?
</p>
<p>
But fear not! ?
</p>
<p>
While this tutorial is not optimized for this platform, I still made it readable enough for you to enjoy.
</p>
<p>
You should however revisit it on a desktop later if you can, to experience all the features!
</p>
<p>Anyway, <a onclick="showStep(1);">let's get started</a>!</p>
</div>
</div>
</div>
<!-- Case: desktop -->
<div id="introduction" class="case is-desktop">
<div class="content">
<p>I believe you are using this:</p>
<div id="platform" class="detect">
<div class="field">
<div class="label"><strong>Operating System</strong></div>
<div class="select">
<select id="os">
<option value="">---</option>
<option value="windows">Windows</option>
<option value="mac">Mac OS</option>
<option value="linux">Linux</option>
</select>
</div>
</div>
<div class="field">
<div class="label"><strong>Web Browser</strong></div>
<div class="select">
<select id="browser">
<option value="">---</option>
<option value="chrome">Google Chrome</option>
<option value="firefox">Mozilla Firefox</option>
<option value="safari">Apple Safari</option>
<option value="edge">Microsoft Edge</option>
<option value="opera">Opera</option>
</select>
</div>
</div>
</div>
<p>If this information is correct, let's <a onclick="showStep(1);">get started</a>.</p>
</div>
</div>
<!-- Case: return -->
<div id="return" class="message is-success">
<div class="message-body">
<p>
It looks that you've already been here! ?
<br>
Do you want to <a id="resume">resume from where you left off</a> or <a id="reset">start over</a>?
</p>
</div>
</div>
</header>
<!-- 01 -->
<div id="step1" class="step">
<div class="content">
<h2>Console <span class="stamp is-tool">tool</span></h2>
<p>
Your browser comes with a <strong>developer console</strong> that allows you to type JavaScript directly in this webpage.
</p>
<div class="case is-chrome not-mobile not-tablet">
Since you're using <strong>Google Chrome</strong>, open the JavaScript console with
<span class="case is-windows is-linux"><kbd class="key">Ctrl</kbd><kbd class="plus">+</kbd><kbd class="key">Shift</kbd><kbd class="plus">+</kbd><kbd class="key">J</kbd> or <kbd class="key">F12</kbd></span>
<span class="case is-mac"><kbd class="key">option</kbd><kbd class="plus">+</kbd><kbd class="key">command</kbd><kbd class="plus">+</kbd><kbd class="key">J</kbd></span>
</div>
<div class="case is-firefox not-mobile not-tablet">
Since you're using <strong>Mozilla Firefox</strong>, open the Web console with
<span class="case is-windows is-linux"><kbd class="key">Ctrl</kbd><kbd class="plus">+</kbd><kbd class="key">Shift</kbd><kbd class="plus">+</kbd><kbd class="key">K</kbd> or <kbd class="key">F12</kbd></span>
<span class="case is-mac"><kbd class="key">option</kbd><kbd class="plus">+</kbd><kbd class="key">command</kbd><kbd class="plus">+</kbd><kbd class="key">K</kbd></span>
</div>
<div class="case is-edge not-mobile not-tablet">
Since you're using <strong>Microsoft Edge</strong>, open the JavaScript console with
<span class="case is-windows"><kbd class="key">F12</kbd></span>
</div>
<div class="case is-opera not-mobile not-tablet">
Since you're using <strong>Opera</strong>, open the JavaScript console with
<span class="case is-windows is-linux"><kbd class="key">Ctrl</kbd><kbd class="plus">+</kbd><kbd class="key">Shift</kbd><kbd class="plus">+</kbd><kbd class="key">I</kbd></span>
<span class="case is-mac"><kbd class="key">option</kbd><kbd class="plus">+</kbd><kbd class="key">command</kbd><kbd class="plus">+</kbd><kbd class="key">I</kbd></span>
</div>
<div class="case is-safari not-mobile not-tablet">
<p>Since you're using <strong>Apple Safari</strong>:</p>
<ol>
<li>Go to <strong>Preferences</strong> with <kbd class="key">command</kbd><kbd class="plus">+</kbd><kbd class="key">,</kbd></li>
<li>Go to the <strong>Advanced</strong> tab</li>
<li>Enable <strong>Show Develop menu in menu bar</strong></li>
<li>Open the JavaScript console <kbd class="key">option</kbd><kbd class="plus">+</kbd><kbd class="key">command</kbd><kbd class="plus">+</kbd><kbd class="key">C</kbd></li>
</ol>
</div>
<p>Let's see if it works!</p>
<p>In the console, type (or paste) the following, and press <kbd class="key">Enter</kbd></p>
</div>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">(</span><span class="s1">'Hello World!'</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
<!-- 02 -->
<div id="step2" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Great job!</h2>
<p>You've just used <code>alert()</code>, a native <strong>JavaScript function</strong> that comes with every browser.</p>
<p>But what have you <a onclick="showStep(3);">done exactly</a>?</p></div>
</div>
</div>
<!-- 03 -->
<div id="step3" class="step">
<div class="content">
<h2>Functions <span class="stamp is-concept">concept</span></h2>
<p>You've <strong>called</strong> the <code>alert()</code> <em>function</em> with the <code>'Hello World!'</code> <em>argument</em>.</p>
<p>You have basically done 4 things:</p>
<div class="stabs">
<div class="stab">
<div class="stab-label">you typed the <strong>name</strong> of the function</div>
<div class="stab-code"><code class="stabilo"><span class="is-blue">alert</span>('Hello World!')</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>parenthesis</strong></div>
<div class="stab-code"><code class="stabilo">alert<span class="is-black">(</span>'Hello World!')</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed an <strong>argument</strong></div>
<div class="stab-code"><code class="stabilo">alert(<span class="is-green">'Hello World!'</span>)</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the parenthesis</div>
<div class="stab-code"><code class="stabilo">alert('Hello World!'<span class="is-black">)</span></code></div>
</div>
</div>
<p>Sometimes, there's no argument.<br>
Sometimes, there's multiple arguments.<br>
Most of them are required, but some of them can be optional.</p>
<p>In this case, <code>alert()</code> requires only one argument.</p>
<p>But what <a onclick="showStep(4);">type of argument</a> is that?</p>
</div>
</div>
<!-- 04 -->
<div id="step4" class="step">
<div class="content">
<h2>Strings <span class="stamp is-type">type</span></h2>
<p>When you handle text, you're using <strong>strings</strong>, which are a series of <em>characters</em>. In our case, we used a series of <strong>12 characters</strong>: <code>Hello World!</code>. This includes all lowercase and uppercase letters, the space, and the exclamation point.</p>
<p>To define where the string <em>starts</em> and where it <em>ends</em>, you need to wrap it in <strong>quotes</strong> (either single <code>'</code> or double <code>"</code>).</p>
<p>When you defined the <code>'Hello World!'</code> string:</p>
<ol>
<li>you typed a single <strong>quote</strong></li>
<li>you typed the <strong>12 characters</strong></li>
<li>you typed another single <strong>quote</strong></li>
</ol>
<p>What if you wanted to deal with <a onclick="showStep(5);">numbers instead</a>?</p>
</div>
</div>
<!-- 05 -->
<div id="step5" class="step">
<div class="content">
<h2>Numbers <span class="stamp is-type">type</span></h2>
<p>Like any other programming language, JavaScript can handle <strong>numbers</strong>.</p>
<p>These numbers can be big or small, with or without decimals, combined through numeric operations…</p>
<p>Type or paste the following snippet in your console:</p>
</div>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">(</span><span class="mi">9</span><span class="o">+</span><span class="mi">5</span> <span class="o">*</span> <span class="mi">3</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
<!-- 06 -->
<div id="step6" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Perfect!</h2>
<p>Notice a few things:</p>
<ul>
<li>you're using the <code>+</code> and <code>*</code> <strong>operators</strong></li>
<li>the <strong>mathematical order</strong> is respected: first <code>5 * 3</code> is calculated, then <code>9 + 15</code></li>
<li>the <strong>spaces</strong> around the <code>*</code> symbol don't affect the output ; they're just here to help us (humans!) <em>read</em> the code.</li>
</ul>
<p>You can find numbers in <a onclick="showStep(7);">lots of places</a>.</p>
</div>
</div>
<!-- 07 -->
<div id="step7" class="step">
<div class="content">
<h2>Browser dimensions <span class="stamp is-info">info</span></h2>
<p>Numbers are everywhere! Especially in a browser.</p>
<p>For example, your current browser window has a certain <strong>width</strong> that you can access with JavaScript.</p>
<p>Type the following:</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 08 -->
<div id="step8" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Wonderful!</h2>
<p>
This means your browser's window is <strong id="browserWidth">1680</strong> pixels wide.
</p>
<p>
As you would have guessed, <code>window.innerHeight</code> exists as well, as does <code>window.scrollY</code>, which gives you the current scroll position.
</p>
<p>But what is <code>window</code> <a onclick="showStep(9);">exactly</a>?</p>
</div>
</div>
<!-- 09 -->
<div id="step9" class="step">
<div class="content">
<h2>Objects <span class="stamp is-type">type</span></h2>
<p>
<code>window</code> is a JavaScript <strong>object</strong>.
</p>
<p>
<code>innerWidth</code> is a <strong>property</strong> of the <code>window</code> object.
<br>
To access this property, you used a dot <code>.</code> to specify you wanted the <code>innerWidth</code> that exists <em>within</em> the <code>window</code> object.
</p>
<p>The JavaScript object is basically a <strong>type</strong> that contains other things.</p>
<p>For example, <code>window</code> also has:</p>
<ul>
<li><code>window.origin</code> which is a string</li>
<li><code>window.scrollY</code> which is a number</li>
<li><code>window.location</code> which is an object</li>
</ul>
<p>If <code>window</code> is an object that contains <code>location</code> which is another object, this means that <a onclick="showStep(10);">JavaScript objects support</a>…</p>
</div>
</div>
<!-- 10 -->
<div id="step10" class="step">
<div class="content">
<h2>Nesting <span class="stamp is-info">info</span></h2>
<p>A property of an object can be an object itself (inception!).</p>
<p>Since <code>window.location</code> is an object too, it has properties of its own. To access these properties, just add another dot <code>.</code> and the name of the property.</p>
<p>For example, the <code>href</code> property exists:</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 11 -->
<div id="step11" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Awesome!</h2>
<p>You just displayed the <strong>full URL</strong> of this webpage. This is because:</p>
<ul>
<li><code>window</code> is an object</li>
<li><code>location</code> is an object</li>
<li><code>href</code> is a string</li>
</ul>
<p>
There's no limit to how deeply objects can be nested.
<br>
There's also no limit to the number of properties an object can have.
</p>
<p>
As we've seen, the properties of an object can be of any type: strings, numbers, objects, and even functions. In the latter case, it's <a onclick="showStep(12);">called…</a>
</p>
</div>
</div>
<!-- 12 -->
<div id="step12" class="step">
<div class="content">
<h2>Methods <span class="stamp is-info">info</span></h2>
<p>When an object's <strong>property</strong> is a <strong>function</strong>, it's called a <strong>method</strong> instead.</p>
<p>Actually, the <code>alert()</code> function we've been using so far is a method of the <code>window</code> object!</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">alert</span><span class="p">(</span><span class="s1">'OMG'</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 13 -->
<div id="step13" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
OMG indeed!</h2>
<p>
Since <code>window</code> is the top-level object in the browser, you can access all its properties and methods directly.
</p>
<p>
That's why typing <code>location.href</code> is the same as typing <code>window.location.href</code>.
</p>
<p>
Or why <code>alert()</code> is equivalent to <code>window.alert()</code>.
</p>
<p>
Objects are useful for grouping several properties under the same name and scope, and defining a <strong>hierarchy</strong> in the data. It's like a tree, where each branch can have other smaller branches.
</p>
<p>
But what if you only needed a <a onclick="showStep(14);">list of things</a>…
</p>
</div>
</div>
<!-- 14 -->
<div id="step14" class="step">
<div class="content">
<h2>Arrays <span class="stamp is-type">type</span></h2>
<p>A JavaScript <strong>array</strong> is a type that can contain multiple values, as if they were in an ordered list.</p>
<p>Let's pass an array of <strong>3 strings</strong> to the <code>alert()</code> function:</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">([</span><span class="s1">'What'</span><span class="p">,</span> <span class="s1">'is'</span><span class="p">,</span> <span class="s1">'up'</span><span class="p">])</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 15 -->
<div id="step15" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Exactly!</h2>
<p>
You already know the syntax for calling the <code>alert</code> function: <code>alert(argument)</code>.
</p>
<p>
In this case, the argument you passed is an array with 3 items that you have defined like this:
</p>
<div class="stabs">
<div class="stab">
<div class="stab-label">you opened a <strong>square bracket</strong></div>
<div class="stab-code"><code class="stabilo"><span class="is-black">[</span>'What', 'is', 'up']</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>first item</strong> of the array, a string</div>
<div class="stab-code"><code class="stabilo">[<span class="is-green">'What'</span>, 'is', 'up']</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed a <strong>comma</strong> to separate the items</div>
<div class="stab-code"><code class="stabilo">['What'<span class="is-black">,</span> 'is', 'up']</code></div>
</div>
<div class="stab">
<div class="stab-label">you added <strong>two other items</strong> to the list</div>
<div class="stab-code"><code class="stabilo">['What', <span class="is-green">'is'</span><span class="is-black">, </span><span class="is-green">'up'</span>]</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the square bracket</div>
<div class="stab-code"><code class="stabilo">['What', 'is', 'up'<span class="is-black">]</span></code></div>
</div>
</div>
<p>
An array can contain any <strong>type</strong> of values: strings, numbers, objects, other arrays, and <em>more</em>…
</p>
<p>
Try out this snippet:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">([</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">])</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 16 -->
<div id="step16" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
True!</h2>
<p>
The first item <code>2 + 5</code> is a number, while the second one <code>'samurai'</code> is a string.
</p>
<p>
What about the <strong>third argument</strong>? It's not a string because it's not wrapped in quotes, and it's not a number either.
</p>
<p>
So <a onclick="showStep(17);">what is it</a>?
</p>
</div>
</div>
<!-- 17 -->
<div id="step17" class="step">
<div class="content">
<h2>Booleans <span class="stamp is-type">type</span></h2>
<p>While strings and numbers have an infinite amount of <em>possible</em> values, a <strong>boolean</strong> can only be either <code>true</code> or <code>false</code>.</p>
<p>
By combining the <code>alert()</code> function and the 3-item array on a <em>single</em> line, it makes our code less readable.
</p>
<p>
What if we could split the two by moving the array onto <a onclick="showStep(18);">its own line</a>?
</p>
</div>
</div>
<!-- 18 -->
<div id="step18" class="step">
<div class="content">
<h2>Variables <span class="stamp is-concept">concept</span></h2>
<p>
We can move the array into a <strong>variable</strong>.
</p>
<p>
A variable is a <strong>container</strong> that stores a certain <strong>value</strong>. It has a <strong>name</strong> (so you can identify and re-use it), and it has a <strong>value</strong> (so you can update it later on).
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
</code></pre></div></div>
</div>
</div>
<ul>
<li>
<code>my_things</code> is the <strong>name</strong> of the variable
</li>
<li>
<code>[2 + 5, 'samurai', true]</code> is the <strong>value</strong> of the variable
</li>
</ul>
<p>
Here's the breakdown:
</p>
<div class="stabs is-vertical">
<div class="stab">
<div class="stab-label">you typed the <strong>keyword</strong> <code>var</code></div>
<div class="stab-code"><code class="stabilo"><span class="is-purple">var</span> my_things = [2 + 5, 'samurai', true];</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>name</strong> of the variable</div>
<div class="stab-code"><code class="stabilo">var <span class="is-blue">my_things</span> = [2 + 5, 'samurai', true];</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>assignment</strong> operator <code>=</code></div>
<div class="stab-code"><code class="stabilo">var my_things <span class="is-purple">=</span> [2 + 5, 'samurai', true];</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>array</strong></div>
<div class="stab-code"><code class="stabilo">var my_things = <span class="is-black">[</span><span class="is-red">2</span><span class="is-purple"> + </span><span class="is-red">5</span><span class="is-black">, </span><span class="is-green">'samurai'</span><span class="is-black">, </span><span class="is-purple">true</span><span class="is-black">]</span>;</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed a <strong>semicolon</strong> to end the statement</div>
<div class="stab-code"><code class="stabilo">var my_things = [2 + 5, 'samurai', true]<span class="is-black">;</span></code></div>
</div>
</div>
<p>
This means that <code>my_things</code> is equal to <code>[2 + 5, 'samurai', true]</code>.
</p>
<p>
We can now reinstate the <code>alert</code> function:
</p>
<p>
Since we now have <em>two statements</em>, we need to separate them with a <strong>semicolon</strong> <code>;</code> in order to know where one ends and the next one begins.
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 19 -->
<div id="step19" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Wonderful!</h2>
<p>
By storing our array into a variable, we managed to make our code more <strong>readable</strong>.
</p>
<div class="message is-info">
<div class="message-body">
<p>
If you look at other recent tutorials on the Web, you'll see variables defined using the keywords <code>const</code> and <code>let</code>. While they are extremely useful, they're hard for me to explain if you're not familiar with the basics of JavaScript.
</p>
<p>
So that's why I decided to use the keyword <code>var</code> here since it's easier to use and understand when learning JavaScript.
</p>
<p>
If what I just said didn't make sense, don't worry about it and keep on reading :-)
</p>
</div>
</div>
<p>
Although this <code>my_things</code> variable contains a list of several things, we might want to deal with only a <strong>single</strong> item of the list.
</p>
<p>
To access a <em>specific item</em> of an array, you first need to know its <strong>index</strong> (or position) within the array. You then need to wrap this index into <strong>square brackets</strong>.
</p>
<p>
Can you guess which item is gonna be displayed?
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 20 -->
<div id="step20" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
You guessed it!</h2>
<p>
It's the <strong>second item</strong> that showed up! In programming, indexes start at zero <code>0</code>.
</p>
<div class="stabs is-vertical">
<div class="stab">
<div class="stab-label">you typed the <strong>name</strong> of the array</div>
<div class="stab-code"><code class="stabilo"><span class="is-blue">my_things</span>[1]</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>square bracket</strong></div>
<div class="stab-code"><code class="stabilo">my_things<span class="is-black">[</span>1]</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>index</strong> of the item you wanted to access</div>
<div class="stab-code"><code class="stabilo">my_things[<span class="is-red">1</span>]</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the square bracket</div>
<div class="stab-code"><code class="stabilo">my_things[1<span class="is-black">]</span></code></div>
</div>
</div>
<p>
It turns out that variables are <strong>objects</strong> too! Which means that variables also have <strong>properties</strong> and <strong>methods</strong>.
</p>
<p>
For example, <code>my_things</code> has a property called <code>length</code>:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 21 -->
<div id="step21" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
That's right!</h2>
<p>
The array has <strong>3</strong> items. You'll see that if you add or remove items in <code>my_things</code>, this <code>length</code> value will change accordingly.
</p>
<p>
While readability and properties are useful, the main point of a variable is that it's <strong>editable</strong>: you can change the value afterwards!
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">);</span>
<span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="s1">'LOVE'</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 22 -->
<div id="step22" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Yep!</h2>
<p>
Two alert boxes have been displayed, but with different values! That's because between the first call and the second one, the value of <code>my_things</code> has been <strong>updated</strong>: a fourth item, the string <code>'LOVE'</code>, was added.
</p>
<p>
Note that the second time we're assigning a value to <code>my_things</code>, we're <strong>not</strong> using the <code>var</code> keyword: it's because we're editing the <code>my_things</code> variable defined two lines above.
</p>
<p>
<strong>You only use the keyword <code>var</code> when you're <em>creating</em> a new variable</strong>, not when you're <em>editing</em> one.
</p>
<p>
Do you remember I told you variables had <strong>methods</strong> too (since they're objects)? Another way to edit an array's value is by using the <code>push()</code> method:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">);</span>
<span class="nx">my_things</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'The Button'</span><span class="p">);</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 23 -->
<div id="step23" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Fantastic!</h2>
<p>
The <code>my_things</code> array ends up with <strong>4</strong> items.
</p>
<p>
While the <code>push()</code> method altered the array, others simply <strong>return</strong> a value:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="s1">'ninja'</span><span class="p">));</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 24 -->
<div id="step24" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
No ninja here!</h2>
<p>
The <code>includes()</code> method checked if the string <code>'ninja'</code> was present in the array. Since it wasn't, the method returned <code>false</code>, a <strong>boolean</strong> value.
</p>
<p>
As a matter of fact, when dealing with booleans, typing the keywords <code>true</code> or <code>false</code> is quite rare. Usually, booleans exist as a result of a function call (like <code>includes()</code>) or a <strong>comparison</strong>.
</p>
<p>
Here's a "<em>greater than</em>" comparison:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">alert</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span> <span class="o">></span> <span class="mi">400</span><span class="p">)</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 25 -->
<div id="step25" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Great again!</h2>
<p>
This means your browser window is <strong id="wider">not</strong> wider than <strong>400 pixels</strong>.
</p>
<div class="stabs">
<div class="stab">
<div class="stab-label">you typed the <strong>first item</strong> to compare, a <strong>number</strong></div>
<div class="stab-code"><code class="stabilo"><span class="is-blue">window<span class="is-black">.</span>innerWidth</span> > 400</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the "greater than" <strong>operator</strong></div>
<div class="stab-code"><code class="stabilo">window.innerWidth <span class="is-purple">></span> 400</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>second item</strong>, also a <strong>number</strong></div>
<div class="stab-code"><code class="stabilo">window.innerWidth > <span class="is-red">400</span></code></div>
</div>
</div>
<p>
Just like the <code>+</code> and <code>*</code> before, <code>></code> is a JavaScript <strong>operator</strong>.
</p>
<p>
When you make such a comparison with the "<em>greater than</em>" operator <code>></code>, you obtain a <strong>boolean</strong> value.
</p>
<p>
Since the result of a <strong>comparison</strong> only has <strong>2</strong> outcomes (<code>true</code> or <code>false</code>), it's useful in cases where your code has to <a onclick="showStep(26);">make a decision</a>…
</p>
</div>
</div>
<!-- 26 -->
<div id="step26" class="step">
<div class="content">
<h2>Conditional statements <span class="stamp is-concept">concept</span></h2>
<p>
Conditional statements are one of the most important concepts in programming. They allow your code to perform certain commands <em>only if</em> certain conditions are met. These conditions can for example be based on:
</p>
<ul>
<li>
a user's input (is the password entered correct?)
</li>
<li>
the current state (is it day or night?)
</li>
<li>
the value of a certain element (is this person older than 18?)
</li>
</ul>
<p>
For now, let's trigger an alert box only if you happen to be on my domain!
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">==</span> <span class="s1">'jgthms.com'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Welcome on my domain! ?'</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
<div class="message is-info">
<div class="message-body">
<p>If you want to <strong>type</strong> this code instead of simply copy-pasting it, press <kbd class="key">Shift</kbd><kbd class="plus">+</kbd><kbd class="key">Enter</kbd> to add line breaks in the console!</p>
</div>
</div>
</div>
</div>
<!-- 27 -->
<div id="step27" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Equal indeed!</h2>
<p>
We're doing another comparison here, but with the "<em>equal to</em>" operator <code>==</code> instead.
</p>
<div class="stabs is-vertical">
<div class="stab">
<div class="stab-label">you typed the <strong>keyword</strong> <code>if</code></div>
<div class="stab-code"><code class="stabilo"><span class="is-purple">if</span> (window.location.hostname == 'jgthms.com') {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>parenthesis</strong></div>
<div class="stab-code"><code class="stabilo">if <span class="is-black">(</span>window.location.hostname == 'jgthms.com') {</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed a <strong>comparison</strong></div>
<div class="stab-code"><code class="stabilo">if (<span class="is-blue">window</span><span class="is-black">.</span><span class="is-blue">location</span><span class="is-black">.</span><span class="is-blue">hostname</span><span class="is-purple"> == </span><span class="is-green">'jgthms.com'</span>) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the parenthesis</div>
<div class="stab-code"><code class="stabilo">if (window.location.hostname == 'jgthms.com'<span class="is-black">)</span> {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>curly bracket</strong></div>
<div class="stab-code"><code class="stabilo">if (window.location.hostname == 'jgthms.com') <span class="is-black">{</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you entered a <strong>block of code</strong> that's only executed if the previous condition is <strong>true</strong></div>
<div class="stab-code"><code class="stabilo"><span class="is-blue"> alert</span><span class="is-black">(</span><span class="is-green">'Welcome on my domain! ?'</span><span class="is-black">)</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the curly bracket</div>
<div class="stab-code"><code class="stabilo"><span class="is-black">}</span></code></div>
</div>
</div>
<p>
Since the alert box <em>did</em> appear, it means that the <strong>hostname</strong> is indeed <em>equal to</em> <code>'jgthms.com'</code>!
</p>
<p>
We've handled the case when the comparison returns <code>true</code>.
</p>
<p>
To handle the <strong>opposite case</strong>, when the hostname isn't <code>'jgthms.com'</code>, we can use the "<em>not equal to</em>" <strong>operator</strong> <code>!=</code>:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">!=</span> <span class="s1">'jgthms.com'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Please come back soon! ?'</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
</div>
<p>
If you try out this snippet, you'll see that it doesn't trigger anything! (Unless this tutorial has been copied to another domain ?).
</p>
<p>
What if we wanted to handle both cases <strong>simultaneously</strong>? We could write two <code>if</code> statements in a row. But since one statement is the <em>exact opposite</em> of the other, we can <strong>combine</strong> them with a <code>else</code> statment:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">==</span> <span class="s1">'jgthms.com'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Welcome on my domain! ?'</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Please come back soon! ?'</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 28 -->
<div id="step28" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Still equal!</h2>
<p>With this conditional setup, we can be sure that:</p>
<ul>
<li><strong>only one</strong> of the two alerts will be triggered, but never both</li>
<li>at least one of the two alerts <em>will</em> be triggered, because we're covering <strong>all</strong> cases</li>
</ul>
<p>
While <code>else</code> is useful for covering all <em>remaining</em> cases, sometimes you want to handle more than two cases.
</p>
<p>
By using <code>else if</code> you can add <strong>intermediate</strong> statements and handle multiple cases:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span> <span class="o">></span> <span class="mi">2000</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Big screen! ?'</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span> <span class="o"><</span> <span class="mi">600</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Probably a mobile phone ?'</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s1">'Decent size ?'</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 29 -->
<div id="step29" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
You got it!</h2>
<p>
As soon as one comparison returns <code>true</code>, it will be triggered, and all following statements will be ignored. That's why only one alert box showed up!
</p>
<p>
Conditional statements make use of the <strong>keywords</strong> <code>if</code> and <code>else</code>, followed by a set of <strong>parentheses</strong>.
</p>
<p>
This pattern of keyword/parentheses combination also happens to exist for another <a onclick="showStep(30);">essential programming concept…</a>
</p>
</div>
</div>
<!-- 30 -->
<div id="step30" class="step">
<div class="content">
<h2>Loops <span class="stamp is-concept">concept</span></h2>
<p>
When you want to execute a block of code a <em>certain amount</em> of times, you can use a JavaScript <strong>loop</strong>.
</p>
<p>
Can you guess how many alert boxes this snippet will trigger?
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="mi">3</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 31 -->
<div id="step31" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Three it is!</h2>
<p>
There were exactly <strong>3</strong> alert boxes! Let's dissect what happened:
</p>
<ul>
<li>
<code>var i = 0</code> is the <strong>initial state</strong><br>
Before the loop even starts, the variable <code>i</code> is assigned a value of zero <code>0</code>.
</li>
<li>
<code>i < 3</code> is the <strong>conditional statement</strong><br>
On every iteration of the loop, we check this comparison.<br>
If it's <code>true</code>, we execute the code in the block.<br>
If it's <code>false</code>, we exit the loop.<br>
</li>
<li>
<code>i++</code> is the <strong>increment expression</strong><br>
<em>If</em> the block of code is executed, this expression is executed.<br>
In this case, the value of <code>i</code> is incremented by 1.
</li>
</ul>
<p>
Here's how you implemented it:
</p>
<div class="stabs is-vertical">
<div class="stab">
<div class="stab-label">you typed the <strong>keyword</strong> <code>for</code></div>
<div class="stab-code"><code class="stabilo"><span class="is-purple">for</span> (var i = 0; i < 3; i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>parenthesis</strong></div>
<div class="stab-code"><code class="stabilo">for <span class="is-black">(</span>var i = 0; i < 3; i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you entered the <strong>initial state</strong></div>
<div class="stab-code"><code class="stabilo">for (<span class="is-purple">var </span><span class="is-blue">i</span><span class="is-purple"> = </span><span class="is-red">0</span>; i < 3; i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed a <strong>semicolon</strong> to separate the expressions</div>
<div class="stab-code"><code class="stabilo">for (var i = 0<span class="is-black">;</span> i < 3; i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you entered the <strong>comparison</strong> check</div>
<div class="stab-code"><code class="stabilo">for (var i = 0; <span class="is-blue">i</span><span class="is-purple"> < </span><span class="is-red">3</span>; i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed a <strong>semicolon</strong> to separate the expressions</div>
<div class="stab-code"><code class="stabilo">for (var i = 0; i < 3<span class="is-black">;</span> i++) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you entered the <strong>increment</strong> expression</div>
<div class="stab-code"><code class="stabilo">for (var i = 0; i < 3; <span class="is-blue">i</span><span class="is-purple">++</span>) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the parenthesis</div>
<div class="stab-code"><code class="stabilo">for (var i = 0; i < 3; i++<span class="is-black">)</span> {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>curly bracket</strong></div>
<div class="stab-code"><code class="stabilo">for (var i = 0; i < 3; i++) <span class="is-black">{</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you entered a <strong>block of code</strong> that's only executed if the comparison check is <strong>true</strong></div>
<div class="stab-code"><code class="stabilo"><span class="is-blue"> alert</span><span class="is-black">(</span><span class="is-blue">i</span><span class="is-black">);</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the curly bracket</div>
<div class="stab-code"><code class="stabilo"><span class="is-black">}</span></code></div>
</div>
</div>
<p>
Let's analyze each iteration of the loop:
</p>
<div class="table-container">
<table>
<thead>
<tr>
<th>Iteration</th>
<th>Value of <code>i</code></th>
<th>Test</th>
<th>Trigger the alert?</th>
</tr>
</thead>
<tbody>
<tr>
<td>1st</td>
<td>0</td>
<td><code>0 < 3</code></td>
<td>Yes</td>
</tr>
<tr>
<td>2nd</td>
<td>1</td>
<td><code>1 < 3</code></td>
<td>Yes</td>
</tr>
<tr>
<td>3rd</td>
<td>2</td>
<td><code>2 < 3</code></td>
<td>Yes</td>
</tr>
<tr>
<td>4th</td>
<td>3</td>
<td><code>3 < 3</code></td>
<td><strong>No!</strong></td>
</tr>
</tbody>
</table>
</div>
<p>
This loop allowed us to <strong>repeat</strong> an action N times. That's what computers are all about!
</p>
<p>
Of all the types of variables we've covered so far, there is one in particular <a onclick="showStep(32);">worth looping through…</a>
</p>
</div>
</div>
<!-- 32 -->
<div id="step32" class="step">
<div class="content">
<h2>Looping through arrays <span class="stamp is-tool">tool</span></h2>
<p>
Arrays are a perfect candidate for loops, because in programming we often want to repeat the <strong>same action</strong> for <em>each</em> item of an array.
</p>
<p>
Let's say we wanted to trigger an alert box for <em>each</em> item of an array. While we could write as many <code>alert()</code> statements as there are items in the array (?), this solution is cumbersome and ineffective! It would be prone to errors, and wouldn't scale at all with bigger arrays.
</p>
<p>
Since programming languages are here to help us simplify our work, let's figure out a better way. We already know a few things:
</p>
<ul>
<li>
We know how to get an array's <strong>length</strong>
</li>
<li>
We know how to access an array's item by using the <strong>index</strong>
</li>
<li>
We have access to the variable <code>i</code>, which conveniently increments 1 by 1
</li>
</ul>
<p>
By combining these informations, we can devise the following snippet:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">my_things</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">my_things</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
<span class="p">}</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 33 -->
<div id="step33" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
In a row!</h2>
<p>
One by one, the items of the array were displayed in their own alert box.
</p>
<p>
While using a loop simplifies the process of going through each item of an array, we still had to create a <code>for</code> block <strong>manually</strong> and create a new variable <code>i</code> whose only purpose was to increment after each loop.
</p>
<p>
I know what you're thinking. "<em><a onclick="showStep(34);">There must be a better way</a>!</em>"
</p>
</div>
</div>
<!-- 34 -->
<div id="step34" class="step">
<div class="content">
<h2>forEach loop <span class="stamp is-tool">tool</span></h2>
<p>
Arrays actually have a <strong>method</strong> called <code>forEach()</code>, which allows to perform a task <em>for each</em> item in the array:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">my_things</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'samurai'</span><span class="p">,</span> <span class="kc">true</span><span class="p">];</span>
<span class="nx">my_things</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">item</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 35 -->
<div id="step35" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Better!</h2>
<p>
Note a few improvements:
</p>
<ul>
<li>
There is no <code>i</code> variable involved
</li>
<li>
We don't need to access the array's <code>length</code>
</li>
<li>
We don't need to use the <strong>index</strong> with <code>my_thing[i]</code> to access the item
</li>
</ul>
<p>
Remember the syntax of the <code>alert()</code> function? It was <code>alert(argument)</code>.
</p>
<p>
If you look carefully, you can see that <code>forEach()</code> has the exact same syntax! It's <code>forEach(argument)</code> but where the argument happens to be a <strong>function</strong> that spans 3 lines.
</p>
<p>
So far, we've used a few functions and methods:
</p>
<ul>
<li>
the <code>alert()</code> function (or window method)
</li>
<li>
the <code>push()</code> array method
</li>
<li>
the <code>includes()</code> array method
</li>
<li>
the <code>forEach()</code> array method
</li>
</ul>
<p>
We know how to <strong>call</strong> a function, but how do you actually <a onclick="showStep(36);">create one</a>?
</p>
</div>
</div>
<!-- 36 -->
<div id="step36" class="step">
<div class="content">
<h2>Creating a custom function <span class="stamp is-info">info</span></h2>
<p>
The power of programming languages is the ability to create your <strong>own functions</strong>, that fit <em>your</em> needs.
</p>
<p>
Remember the keyword/parentheses combination that we used for <code>if/else</code> and <code>for</code>? Well, guess what: it's <em>almost</em> the same pattern here!
</p>
<p>
I'm saying "almost" because the only difference is that a function needs a <strong>name</strong>!
</p>
<p>
Let's <strong>create</strong> a function called <code>greet()</code>, with <strong>1</strong> parameter called <code>name</code>, and then immediately <strong>call</strong> it:
</p>
<div class="snippet">
<div class="snippet-contents">
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">greet</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="s1">'Hey there '</span> <span class="o">+</span> <span class="nx">name</span><span class="p">;</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">greet</span><span class="p">(</span><span class="s1">'Alex'</span><span class="p">);</span>
</code></pre></div></div>
</div>
<a class="snippet-copy not-mobile not-tablet">
Copy to clipboard
</a>
</div>
<div class="run-snippet case is-mobile is-tablet">
<a class="button">Run snippet</a>
</div>
</div>
</div>
<!-- 37 -->
<div id="step37" class="step">
<div class="content">
<h2 class="gj"><div class="check">
<div class="check-circle"></div>
<svg class="check-svg" width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline stroke="#65B280" stroke-width="4" points="11 19 18 26 29 14"></polyline>
</g>
</svg>
</div>
Greetings!</h2>
<p>
You've created your first function! It's a simple one but it can teach you a lot.
</p>
<p>
Note a few things:
</p>
<ul>
<li>
the <strong>name</strong> of the function is <code>greet</code>
</li>
<li>
the <strong>parameter</strong> is called <code>name</code>: it's like a variable, since it acts as a container for a value
</li>
<li>
we're creating a <strong>variable</strong> called <code>message</code> (a string) whose value is <code>'Hey there ' + name</code>
</li>
<li>
what this <strong>plus</strong> sign <code>+</code> does is <strong>concatenate</strong> (or combine) the two strings to make a single longer one
</li>
<li>
we're <strong>calling</strong> the <code>alert()</code> function, and use the <code>message</code> variable as parameter
</li>
<li>
after having created the function, we're calling it with the argument <code>'Alex'</code>
</li>
</ul>
<div class="message is-warning">
<div class="message-body">
<p>
You might wonder why we're calling <code>name</code> a <strong>parameter</strong> when so far we've called <strong>argument</strong> the things we pass to a function. Well there's a difference!
</p>
<ul>
<li>
When you <strong>define</strong> a function with <code>function greet(name)</code>, <code>name</code> is here a <strong>parameter</strong>: it's like a <em>variable</em> in your function's definition.
</li>
<li>
When you <strong>call</strong> a function with <code>greet('Alex')</code>, <code>'Alex'</code> is here an <strong>argument</strong>: it's the <em>data</em> you pass to the function when calling it.
</li>
</ul>
<p>
So whether you define a function or call it, you describe what's in the parenthesis as either parameters or arguments.
</p>
</div>
</div>
<p>
If we break it down step by step:
</p>
<div class="stabs is-vertical">
<div class="stab">
<div class="stab-label">you typed the <strong>keyword</strong> <code>function</code></div>
<div class="stab-code"><code class="stabilo"><span class="is-purple">function</span> greet(name) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you typed the <strong>name</strong> of the function</div>
<div class="stab-code"><code class="stabilo">function <span class="is-blue">greet</span>(name) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>parenthesis</strong></div>
<div class="stab-code"><code class="stabilo">function greet<span class="is-black">(</span>name) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you created a <strong>parameter</strong> called <code>name</code></div>
<div class="stab-code"><code class="stabilo">function greet(<span class="is-blue">name</span>) {</code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the parenthesis</div>
<div class="stab-code"><code class="stabilo">function greet(name<span class="is-black">)</span> {</code></div>
</div>
<div class="stab">
<div class="stab-label">you opened a <strong>curly bracket</strong></div>
<div class="stab-code"><code class="stabilo">function greet(name) <span class="is-black">{</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you entered a <strong>block of code</strong> that's only executed whenever the function is <strong>called</strong></div>
<div class="stab-code"><code class="stabilo"> <span class="is-purple">var</span><span class="is-blue"> message </span><span class="is-purple">= </span><span class="is-green">'Hey there '</span><span class="is-purple"> +</span><span class="is-blue"> name</span><span class="is-black">;</span></code><br><code class="stabilo"> <span class="is-blue">alert</span><span class="is-black">(</span><span class="is-blue">message</span><span class="is-black">);</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>closed</strong> the curly bracket</div>
<div class="stab-code"><code class="stabilo"><span class="is-black">}</span></code></div>
</div>
<div class="stab">
<div class="stab-label">you <strong>called</strong> the function with a string as argument</div>
<div class="stab-code"><code class="stabilo"><span class="is-blue">greet</span><span class="is-black">(</span><span class="is-green">'Alex'</span><span class="is-black">)</span><span class="is-black">;</span></code></div>
</div>
</div>
<p>
Unless we call the <code>greet()</code> function at the end, nothing happens! That's because the <code>alert()</code> call is <em>inside</em> the scope of <code>greet()</code> so it's not triggered unless the parent function <code>greet()</code> itself is called!
</p>
<p>
Basically, by <strong>creating</strong> <code>greet()</code>, you're only telling the browser: "<em>Hey! I've created this new function. So if at some point I call it, please execute whatever is inside!</em>".
</p>
<p>
That's why, when you <strong>call</strong> <code>greet()</code> at the end, the browser executes its content, which happens to be calling <code>alert()</code>.
</p>
<p>
It's important to understand that functions are a <strong>2-step</strong> process: creating it first, calling it afterwards.
</p>
<p>
As a matter of fact, the <code>alert()</code> function we've used all along was already created beforehand. It just exists somewhere inside your browser.
</p>
<p>
Anyway, we've already covered <em>a lot</em> in 14 minutes!<br>
So, <a onclick="showStep(38);">what's next</a>?
</p>
</div>
</div>
<!-- 38 -->
<div id="step38" class="step">
<div class="content">
<h2>Next steps <span class="stamp is-victory">victory!</span></h2>
<h3>Learn JavaScript</h3>
<p>
We've barely covered the basics here. But don't worry! There are <em>tons</em> of resources available online!
</p>
<p>
Here are a few <strong>free</strong> resources I'd recommend:
</p>
<ul>
<li>
<a href="https://eloquentjavascript.net/" rel="nofollow" target="_blank">Eloquent JavaScript</a>
</li>
<li>
<a href="https://www.freecodecamp.org/" rel="nofollow" target="_blank">freeCodeCamp</a>
</li>
<li>
<a href="https://javascript.info/" rel="nofollow" target="_blank">The Modern JavaScript Tutorial</a>
</li>
<li>
<a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript" rel="nofollow" target="_blank">Mozilla Developer Network</a>
</li>
<li>
<a href="https://github.com/getify/You-Dont-Know-JS" rel="nofollow" target="_blank">You Don't Know JS</a>
</li>
</ul>
<p>
If you prefer <strong>video tutorials</strong>, check out these <strong><a href="https://click.linksynergy.com/fs-bin/click?id=76TvM1KGjYg&offerid=358574.81&type=3&subid=0" target="_blank">Udemy courses</a><IMG class="lazyload" border=0 width=1 height=1 data-src="https://ad.linksynergy.com/fs-bin/show?id=76TvM1KGjYg&bids=358574.81&type=3&subid=0" ></strong>:
</p>
<nav class="shares">
<a class="share is-udemy" href="https://click.linksynergy.com/link?id=76TvM1KGjYg&offerid=358574.1463348&type=2&murl=https%3A%2F%2Fwww.udemy.com%2Fmodern-javascript-from-the-beginning%2F" target="_blank"><IMG border=0 src="https://udemy-images.udemy.com/course/480x270/1463348_52a4.jpg" >
<br>
<img
src="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@3x.png 3x"
alt="Udemy logo"
width="72"
height="21">
<br>
<em>21.5 hours ?</em>
<strong>Modern JavaScript From The Beginning</strong>
</a>
<IMG class="lazyload" border=0 width=1 height=1 data-src="https://ad.linksynergy.com/fs-bin/show?id=76TvM1KGjYg&bids=358574.1463348&type=2&subid=0" >
<a class="share is-udemy" href="https://click.linksynergy.com/link?id=76TvM1KGjYg&offerid=358574.851712&type=2&murl=https%3A%2F%2Fwww.udemy.com%2Fthe-complete-javascript-course%2F" target="_blank"><IMG border=0 src="https://udemy-images.udemy.com/course/480x270/851712_fc61_5.jpg" >
<br>
<img
src="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@3x.png 3x"
alt="Udemy logo"
width="72"
height="21">
<br>
<em>17.5 hours ?</em>
<strong>The Complete JavaScript Course: Build a Real-World Project</strong>
</a>
<IMG class="lazyload" border=0 width=1 height=1 data-src="https://ad.linksynergy.com/fs-bin/show?id=76TvM1KGjYg&bids=358574.851712&type=2&subid=0" >
</nav>
<p>
If you're in a rush, try this <strong>shorter</strong> course!
</p>
<nav class="shares">
<a class="share is-udemy is-udemy-advanced" href="https://click.linksynergy.com/link?id=76TvM1KGjYg&offerid=358574.670034&type=2&murl=https%3A%2F%2Fwww.udemy.com%2Ftop-javascript-interview-questions-and-answers%2F" target="_blank"><IMG border=0 src="https://udemy-images.udemy.com/course/480x270/670034_ce04_4.jpg" >
<br>
<img
src="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/udemy-logo.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/udemy-logo@3x.png 3x"
alt="Udemy logo"
width="72"
height="21">
<br>
<em>Only 3.5 hours! ?</em>
<strong>Advanced Javascript</strong>
</a>
<IMG class="lazyload" border=0 width=1 height=1 data-src="https://ad.linksynergy.com/fs-bin/show?id=76TvM1KGjYg&bids=358574.670034&type=2&subid=0" >
</nav>
<h3>Learn HTML and CSS</h3>
<p>
JavaScript is only one third of what makes a webpage! You also need to know <strong>HTML</strong> and <strong>CSS</strong>.
</p>
<p>
Luckily, I've created <strong>two free references</strong> for you to browse through, so you can learn everything each language has to offer!
</p>
<nav class="shares">
<a
class="share is-html"
href="https://htmlreference.io"
target="_blank"
>
<img
src="https://jgthms.com/javascript-in-14-minutes/images/html-reference.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/html-reference.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/html-reference@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/html-reference@3x.png 3x"
alt="HTML Reference"
width="64"
height="64">
<br>
<em>Discover</em>
<strong>HTML Reference</strong>
</a>
<a
class="share is-css"
href="https://cssreference.io"
target="_blank"
>
<img
src="https://jgthms.com/javascript-in-14-minutes/images/css-reference.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/css-reference.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/css-reference@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/css-reference@3x.png 3x"
alt="CSS Reference"
width="64"
height="64">
<br>
<em>Discover</em>
<strong>CSS Reference</strong>
</a>
</nav>
<h3>Learn my CSS framework</h3>
<p>
I designed this page with <strong>Bulma</strong>, my free open source CSS framework based on Flexbox. <a href="https://bulma.io" target="_blank">Check it out!</a>
</p>
<p class="focus">
<a class="share is-bulma" href="https://bulma.io/" target="_blank">
<img
src="https://jgthms.com/javascript-in-14-minutes/images/bulma-modern-css-framework-flexbox.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/bulma-modern-css-framework-flexbox.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/bulma-modern-css-framework-flexbox@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/bulma-modern-css-framework-flexbox@3x.png 3x"
alt="Bulma CSS framework based on Flexbox"
width="256"
height="160">
</a>
</p>
<h3>Read my book</h3>
<p>
I wrote a <strong>44-page PDF</strong> called "<a href="https://jgthms.com/css-in-44-minutes-ebook" target="_blank">CSS in 44 minutes</a>" which teaches how to build your own personal webpage from scratch with HTML5 and CSS3.
</p>
<p class="focus">
<a class="share is-fortyfour" href="https://jgthms.com/css-in-44-minutes-ebook" target="_blank">
<img
src="https://jgthms.com/javascript-in-14-minutes/images/css-in-44-minutes-book-cover.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/css-in-44-minutes-book-cover.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/css-in-44-minutes-book-cover@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/css-in-44-minutes-book-cover@3x.png 3x"
alt="CSS in 44 minutes ebook"
width="168"
height="235">
</a>
</p>
<p>
As a bonus, the book also includes a small <strong>chapter on JavaScript</strong> in which I talk about functions, conditionals, objects, strings, and even explains how to interact with CSS.
</p>
<p>
I guess now there's <a onclick="showStep(39);">only one thing left to do</a>…
</p>
</div>
</div>
<!-- 39 -->
<div id="step39" class="step">
<div class="content">
<h2>Share and support! ?</h2>
<nav class="shares">
<a
class="share is-facebook"
href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fjgthms.com%2Fjavascript-in-14-minutes%2F"
rel="nofollow"
target="_blank"
>
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="https://www.w3.org/2000/svg"><path d="M1579 128q35 0 60 25t25 60v1366q0 35-25 60t-60 25h-391v-595h199l30-232h-229v-148q0-56 23.5-84t91.5-28l122-1v-207q-63-9-178-9-136 0-217.5 80t-81.5 226v171h-200v232h200v595h-735q-35 0-60-25t-25-60v-1366q0-35 25-60t60-25h1366z"/></svg>
</span>
<em>Share on</em>
<strong>Facebook</strong>
</a>
<a
class="share is-twitter"
data-social-network="Twitter"
data-social-action="tweet"
data-social-target="https://jgthms.com/javascript-in-14-minutes/"
href="https://twitter.com/intent/tweet?text=JavaScript%20in%2014%20minutes&url=https%3A%2F%2Fjgthms.com%2Fjavascript-in-14-minutes%2F&via=jgthms"
rel="nofollow"
target="_blank"
>
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="https://www.w3.org/2000/svg"><path d="M1684 408q-67 98-162 167 1 14 1 42 0 130-38 259.5t-115.5 248.5-184.5 210.5-258 146-323 54.5q-271 0-496-145 35 4 78 4 225 0 401-138-105-2-188-64.5t-114-159.5q33 5 61 5 43 0 85-11-112-23-185.5-111.5t-73.5-205.5v-4q68 38 146 41-66-44-105-115t-39-154q0-88 44-163 121 149 294.5 238.5t371.5 99.5q-8-38-8-74 0-134 94.5-228.5t228.5-94.5q140 0 236 102 109-21 205-78-37 115-142 178 93-10 186-50z"/></svg>
</span>
<em>Share on</em>
<strong>Twitter</strong>
</a>
<a class="share is-paypal" href="https://www.paypal.me/jgthmsuk" target="_blank">
<img
src="https://jgthms.com/javascript-in-14-minutes/images/paypal.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/paypal.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/paypal@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/paypal@3x.png 3x"
alt="PayPal"
width="100"
height="26">
<br>
<em>Donate on</em>
<strong>PayPal</strong>
</a>
<a class="share is-whatsapp" href="whatsapp://send?text=https%3A%2F%2Fjgthms.com%2Fjavascript-in-14-minutes%2F" data-action="share/whatsapp/share">
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1113 974q13 0 97.5 44t89.5 53q2 5 2 15 0 33-17 76-16 39-71 65.5t-102 26.5q-57 0-190-62-98-45-170-118t-148-185q-72-107-71-194v-8q3-91 74-158 24-22 52-22 6 0 18 1.5t19 1.5q19 0 26.5 6.5t15.5 27.5q8 20 33 88t25 75q0 21-34.5 57.5t-34.5 46.5q0 7 5 15 34 73 102 137 56 53 151 101 12 7 22 7 15 0 54-48.5t52-48.5zm-203 530q127 0 243.5-50t200.5-134 134-200.5 50-243.5-50-243.5-134-200.5-200.5-134-243.5-50-243.5 50-200.5 134-134 200.5-50 243.5q0 203 120 368l-79 233 242-77q158 104 345 104zm0-1382q153 0 292.5 60t240.5 161 161 240.5 60 292.5-60 292.5-161 240.5-240.5 161-292.5 60q-195 0-365-94l-417 134 136-405q-108-178-108-389 0-153 60-292.5t161-240.5 240.5-161 292.5-60z"/></svg>
</span>
<em>Share via</em>
<strong>WhatsApp</strong>
</a>
<a class="share is-github" href="https://github.com/jgthms/javascript-in-14-minutes" target="_blank">
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="https://www.w3.org/2000/svg"><path d="M896 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 .5-76.5t.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 .5 88.5t.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zm-477 1103q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zm31 34q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zm30 45q9-7 0-19-8-13-17-6-9 5 0 18t17 7zm42 42q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zm57 25q3-11-13-16-15-4-19 7t13 15q15 6 19-6zm63 5q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zm58-10q-2-11-18-9-16 3-14 15t18 8 14-14z"/></svg>
</span>
<em>Star on</em>
<strong>GitHub</strong>
</a>
<a class="share is-patreon" href="https://www.patreon.com/jgthms" target="_blank">
<img
src="https://jgthms.com/javascript-in-14-minutes/images/become_a_patron_button.png"
srcset="https://jgthms.com/javascript-in-14-minutes/images/become_a_patron_button.png 1x,
https://jgthms.com/javascript-in-14-minutes/images/become_a_patron_button@2x.png 2x,
https://jgthms.com/javascript-in-14-minutes/images/become_a_patron_button@3x.png 3x"
alt="Become a Patron"
width="153"
height="36">
<br>
<em>Support me on</em>
<strong>Patreon</strong>
</a>
<a class="share is-hn" href="https://news.ycombinator.com/item?id=16687634" target="_blank" rel="nofollow">
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M937 1004l266-499h-112l-157 312q-24 48-44 92l-42-92-155-312h-120l263 493v324h101v-318zm727-588v960q0 119-84.5 203.5t-203.5 84.5h-960q-119 0-203.5-84.5t-84.5-203.5v-960q0-119 84.5-203.5t203.5-84.5h960q119 0 203.5 84.5t84.5 203.5z"/></svg></span>
<em>Discuss on</em>
<strong>Hacker News</strong>
</a>
<a class="share is-reddit" href="https://www.reddit.com/r/javascript/comments/87i1m6/javascript_in_14_minutes/" target="_blank" rel="nofollow">
<span><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1095 1167q16 16 0 31-62 62-199 62t-199-62q-16-15 0-31 6-6 15-6t15 6q48 49 169 49 120 0 169-49 6-6 15-6t15 6zm-307-181q0 37-26 63t-63 26-63.5-26-26.5-63q0-38 26.5-64t63.5-26 63 26.5 26 63.5zm395 0q0 37-26.5 63t-63.5 26-63-26-26-63 26-63.5 63-26.5 63.5 26 26.5 64zm251-120q0-49-35-84t-85-35-86 36q-130-90-311-96l63-283 200 45q0 37 26 63t63 26 63.5-26.5 26.5-63.5-26.5-63.5-63.5-26.5q-54 0-80 50l-221-49q-19-5-25 16l-69 312q-180 7-309 97-35-37-87-37-50 0-85 35t-35 84q0 35 18.5 64t49.5 44q-6 27-6 56 0 142 140 243t337 101q198 0 338-101t140-243q0-32-7-57 30-15 48-43.5t18-63.5zm358 30q0 182-71 348t-191 286-286 191-348 71-348-71-286-191-191-286-71-348 71-348 191-286 286-191 348-71 348 71 286 191 191 286 71 348z"/></svg></span>
<em>Discuss on</em>
<strong>Reddit</strong>
</a>
</nav>
<form class="newsletter" action="https://mail.jgthms.com/subscribe" method="POST" accept-charset="utf-8" target="_blank">
<div class="field">
<h3>Subscribe to my newsletter</h3>
<p>And get notified when I launch other<br><strong>free tutorials</strong>! ?</p>
</div>
<div class="newsletter-content">
<div class="field">
<p class="label" for="name">Name</p>
<div class="control">
<input class="input" type="text" name="name" id="name" placeholder="e.g. Alex Smith">
</div>
</div>
<div class="field">
<p class="label" for="email">Email</p>
<div class="control">
<input class="input" type="email" name="email" id="email" placeholder="e.g. alexsmith@gmail.com" required>
</div>
</div>
<div style="display:none;">
<label for="hp">HP</label>
<input type="text" name="hp" id="hp">
</div>
<input type="hidden" name="list" value="bbkZEpnfTh892DlmV8k763es8Q">
<div class="field">
<div class="control">
<button class="button" id="submit">Subscribe</button>
</div>
</div>
<p class="help"><em>No spam of course!</em> <span style="font-size: 1rem; vertical-align: middle;">?</span></p>
</div>
</form>
<p>
Thanks for reading!
</p>
<p class="madeby">
Made by <a href="https://jgthms.com/" target="_blank">@jgthms</a>
</p>
</div>
</div>
<aside id="sides" class="sides">
<div id="sideConcepts" class="side">
<div class="side-title">
<span class="stamp is-concept">concepts</span>
</div>
<div id="sideFunctions" class="side-item">
<span class="side-word is-concept">Functions</span>
</div>
<div id="sideVariables" class="side-item">
<span class="side-word is-concept">Variables</span>
</div>
<div id="sideConditionals" class="side-item">
<span class="side-word is-concept">Conditionals</span>
</div>
<div id="sideLoops" class="side-item">
<span class="side-word is-concept">Loops</span>
</div>
</div>
<div id="sideTypes" class="side">
<div class="side-title">
<span class="stamp is-type">types</span>
</div>
<div id="sideStrings" class="side-item">
<span class="side-word is-type">Strings</span>
</div>
<div id="sideNumbers" class="side-item">
<span class="side-word is-type">Numbers</span>
</div>
<div id="sideObjects" class="side-item">
<span class="side-word is-type">Objects</span>
</div>
<div id="sideArrays" class="side-item">
<span class="side-word is-type">Arrays</span>
</div>
<div id="sideBooleans" class="side-item">
<span class="side-word is-type">Booleans</span>
</div>
</div>
</aside>
</main>
<script>
/*! js-cookie v2.1.4 | MIT */
! function(a) {
var b = !1;
if ("function" == typeof define && define.amd && (define(a), b = !0), "object" == typeof exports && (module.exports = a(), b = !0), !b) {
var c = window.Cookies,
d = window.Cookies = a();
d.noConflict = function() {
return window.Cookies = c, d
}
}
}(function() {
function a() {
for (var a = 0, b = {}; a < arguments.length; a++) {
var c = arguments[a];
for (var d in c) b[d] = c[d]
}
return b
}
function b(c) {
function d(b, e, f) {
var g;
if ("undefined" != typeof document) {
if (arguments.length > 1) {
if (f = a({
path: "/"
}, d.defaults, f), "number" == typeof f.expires) {
var h = new Date;
h.setMilliseconds(h.getMilliseconds() + 864e5 * f.expires), f.expires = h
}
f.expires = f.expires ? f.expires.toUTCString() : "";
try {
g = JSON.stringify(e), /^[\{\[]/.test(g) && (e = g)
} catch (p) {}
e = c.write ? c.write(e, b) : encodeURIComponent(e + "").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent), b = encodeURIComponent(b + ""), b = b.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent), b = b.replace(/[\(\)]/g, escape);
var i = "";
for (var j in f) f[j] && (i += "; " + j, !0 !== f[j] && (i += "=" + f[j]));
return document.cookie = b + "=" + e + i
}
b || (g = {});
for (var k = document.cookie ? document.cookie.split("; ") : [], l = 0; l < k.length; l++) {
var m = k[l].split("="),
n = m.slice(1).join("=");
'"' === n.charAt(0) && (n = n.slice(1, -1));
try {
var o = m[0].replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
if (n = c.read ? c.read(n, o) : c(n, o) || n.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent), this.json) try {
n = JSON.parse(n)
} catch (p) {}
if (b === o) {
g = n;
break
}
b || (g[o] = n)
} catch (p) {}
}
return g
}
}
return d.set = d, d.get = function(a) {
return d.call(d, a)
}, d.getJSON = function() {
return d.apply({
json: !0
}, [].slice.call(arguments))
}, d.defaults = {}, d.remove = function(b, c) {
d(b, "", a(c, {
expires: -1
}))
}, d.withConverter = b, d
}
return b(function() {})
});
/*!
* Bowser - a browser detector
* https://github.com/ded/bowser
* MIT License | (c) Dustin Diaz 2015
*/
! function(e, t, n) {
typeof module != "undefined" && module.exports ? module.exports = n() : typeof define == "function" && define.amd ? define(t, n) : e[t] = n()
}(this, "bowser", function() {
function t(t) {
function n(e) {
var n = t.match(e);
return n && n.length > 1 && n[1] || ""
}
function r(e) {
var n = t.match(e);
return n && n.length > 1 && n[2] || ""
}
function N(e) {
switch (e) {
case "NT":
return "NT";
case "XP":
return "XP";
case "NT 5.0":
return "2000";
case "NT 5.1":
return "XP";
case "NT 5.2":
return "2003";
case "NT 6.0":
return "Vista";
case "NT 6.1":
return "7";
case "NT 6.2":
return "8";
case "NT 6.3":
return "8.1";
case "NT 10.0":
return "10";
default:
return undefined
}
}
var i = n(/(ipod|iphone|ipad)/i).toLowerCase(),
s = /like android/i.test(t),
o = !s && /android/i.test(t),
u = /nexus\s*[0-6]\s*/i.test(t),
a = !u && /nexus\s*[0-9]+/i.test(t),
f = /CrOS/.test(t),
l = /silk/i.test(t),
c = /sailfish/i.test(t),
h = /tizen/i.test(t),
p = /(web|hpw)os/i.test(t),
d = /windows phone/i.test(t),
v = /SamsungBrowser/i.test(t),
m = !d && /windows/i.test(t),
g = !i && !l && /macintosh/i.test(t),
y = !o && !c && !h && !p && /linux/i.test(t),
b = r(/edg([ea]|ios)\/(\d+(\.\d+)?)/i),
w = n(/version\/(\d+(\.\d+)?)/i),
E = /tablet/i.test(t) && !/tablet pc/i.test(t),
S = !E && /[^-]mobi/i.test(t),
x = /xbox/i.test(t),
T;
/opera/i.test(t) ? T = {
name: "Opera",
opera: e,
version: w || n(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i)
} : /opr\/|opios/i.test(t) ? T = {
name: "Opera",
opera: e,
version: n(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || w
} : /SamsungBrowser/i.test(t) ? T = {
name: "Samsung Internet for Android",
samsungBrowser: e,
version: w || n(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i)
} : /coast/i.test(t) ? T = {
name: "Opera Coast",
coast: e,
version: w || n(/(?:coast)[\s\/](\d+(\.\d+)?)/i)
} : /yabrowser/i.test(t) ? T = {
name: "Yandex Browser",
yandexbrowser: e,
version: w || n(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)
} : /ucbrowser/i.test(t) ? T = {
name: "UC Browser",
ucbrowser: e,
version: n(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i)
} : /mxios/i.test(t) ? T = {
name: "Maxthon",
maxthon: e,
version: n(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i)
} : /epiphany/i.test(t) ? T = {
name: "Epiphany",
epiphany: e,
version: n(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i)
} : /puffin/i.test(t) ? T = {
name: "Puffin",
puffin: e,
version: n(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i)
} : /sleipnir/i.test(t) ? T = {
name: "Sleipnir",
sleipnir: e,
version: n(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i)
} : /k-meleon/i.test(t) ? T = {
name: "K-Meleon",
kMeleon: e,
version: n(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i)
} : d ? (T = {
name: "Windows Phone",
osname: "Windows Phone",
windowsphone: e
}, b ? (T.msedge = e, T.version = b) : (T.msie = e, T.version = n(/iemobile\/(\d+(\.\d+)?)/i))) : /msie|trident/i.test(t) ? T = {
name: "Internet Explorer",
msie: e,
version: n(/(?:msie |rv:)(\d+(\.\d+)?)/i)
} : f ? T = {
name: "Chrome",
osname: "Chrome OS",
chromeos: e,
chromeBook: e,
chrome: e,
version: n(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
} : /edg([ea]|ios)/i.test(t) ? T = {
name: "Microsoft Edge",
msedge: e,
version: b
} : /vivaldi/i.test(t) ? T = {
name: "Vivaldi",
vivaldi: e,
version: n(/vivaldi\/(\d+(\.\d+)?)/i) || w
} : c ? T = {
name: "Sailfish",
osname: "Sailfish OS",
sailfish: e,
version: n(/sailfish\s?browser\/(\d+(\.\d+)?)/i)
} : /seamonkey\//i.test(t) ? T = {
name: "SeaMonkey",
seamonkey: e,
version: n(/seamonkey\/(\d+(\.\d+)?)/i)
} : /firefox|iceweasel|fxios/i.test(t) ? (T = {
name: "Firefox",
firefox: e,
version: n(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i)
}, /\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(t) && (T.firefoxos = e, T.osname = "Firefox OS")) : l ? T = {
name: "Amazon Silk",
silk: e,
version: n(/silk\/(\d+(\.\d+)?)/i)
} : /phantom/i.test(t) ? T = {
name: "PhantomJS",
phantom: e,
version: n(/phantomjs\/(\d+(\.\d+)?)/i)
} : /slimerjs/i.test(t) ? T = {
name: "SlimerJS",
slimer: e,
version: n(/slimerjs\/(\d+(\.\d+)?)/i)
} : /blackberry|\bbb\d+/i.test(t) || /rim\stablet/i.test(t) ? T = {
name: "BlackBerry",
osname: "BlackBerry OS",
blackberry: e,
version: w || n(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
} : p ? (T = {
name: "WebOS",
osname: "WebOS",
webos: e,
version: w || n(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
}, /touchpad\//i.test(t) && (T.touchpad = e)) : /bada/i.test(t) ? T = {
name: "Bada",
osname: "Bada",
bada: e,
version: n(/dolfin\/(\d+(\.\d+)?)/i)
} : h ? T = {
name: "Tizen",
osname: "Tizen",
tizen: e,
version: n(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || w
} : /qupzilla/i.test(t) ? T = {
name: "QupZilla",
qupzilla: e,
version: n(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || w
} : /chromium/i.test(t) ? T = {
name: "Chromium",
chromium: e,
version: n(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || w
} : /chrome|crios|crmo/i.test(t) ? T = {
name: "Chrome",
chrome: e,
version: n(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
} : o ? T = {
name: "Android",
version: w
} : /safari|applewebkit/i.test(t) ? (T = {
name: "Safari",
safari: e
}, w && (T.version = w)) : i ? (T = {
name: i == "iphone" ? "iPhone" : i == "ipad" ? "iPad" : "iPod"
}, w && (T.version = w)) : /googlebot/i.test(t) ? T = {
name: "Googlebot",
googlebot: e,
version: n(/googlebot\/(\d+(\.\d+))/i) || w
} : T = {
name: n(/^(.*)\/(.*) /),
version: r(/^(.*)\/(.*) /)
}, !T.msedge && /(apple)?webkit/i.test(t) ? (/(apple)?webkit\/537\.36/i.test(t) ? (T.name = T.name || "Blink", T.blink = e) : (T.name = T.name || "Webkit", T.webkit = e), !T.version && w && (T.version = w)) : !T.opera && /gecko\//i.test(t) && (T.name = T.name || "Gecko", T.gecko = e, T.version = T.version || n(/gecko\/(\d+(\.\d+)?)/i)), !T.windowsphone && (o || T.silk) ? (T.android = e, T.osname = "Android") : !T.windowsphone && i ? (T[i] = e, T.ios = e, T.osname = "iOS") : g ? (T.mac = e, T.osname = "macOS") : x ? (T.xbox = e, T.osname = "Xbox") : m ? (T.windows = e, T.osname = "Windows") : y && (T.linux = e, T.osname = "Linux");
var C = "";
T.windows ? C = N(n(/Windows ((NT|XP)( \d\d?.\d)?)/i)) : T.windowsphone ? C = n(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i) : T.mac ? (C = n(/Mac OS X (\d+([_\.\s]\d+)*)/i), C = C.replace(/[_\s]/g, ".")) : i ? (C = n(/os (\d+([_\s]\d+)*) like mac os x/i), C = C.replace(/[_\s]/g, ".")) : o ? C = n(/android[ \/-](\d+(\.\d+)*)/i) : T.webos ? C = n(/(?:web|hpw)os\/(\d+(\.\d+)*)/i) : T.blackberry ? C = n(/rim\stablet\sos\s(\d+(\.\d+)*)/i) : T.bada ? C = n(/bada\/(\d+(\.\d+)*)/i) : T.tizen && (C = n(/tizen[\/\s](\d+(\.\d+)*)/i)), C && (T.osversion = C);
var k = !T.windows && C.split(".")[0];
if (E || a || i == "ipad" || o && (k == 3 || k >= 4 && !S) || T.silk) T.tablet = e;
else if (S || i == "iphone" || i == "ipod" || o || u || T.blackberry || T.webos || T.bada) T.mobile = e;
return T.msedge || T.msie && T.version >= 10 || T.yandexbrowser && T.version >= 15 || T.vivaldi && T.version >= 1 || T.chrome && T.version >= 20 || T.samsungBrowser && T.version >= 4 || T.firefox && T.version >= 20 || T.safari && T.version >= 6 || T.opera && T.version >= 10 || T.ios && T.osversion && T.osversion.split(".")[0] >= 6 || T.blackberry && T.version >= 10.1 || T.chromium && T.version >= 20 ? T.a = e : T.msie && T.version < 10 || T.chrome && T.version < 20 || T.firefox && T.version < 20 || T.safari && T.version < 6 || T.opera && T.version < 10 || T.ios && T.osversion && T.osversion.split(".")[0] < 6 || T.chromium && T.version < 20 ? T.c = e : T.x = e, T
}
function r(e) {
return e.split(".").length
}
function i(e, t) {
var n = [],
r;
if (Array.prototype.map) return Array.prototype.map.call(e, t);
for (r = 0; r < e.length; r++) n.push(t(e[r]));
return n
}
function s(e) {
var t = Math.max(r(e[0]), r(e[1])),
n = i(e, function(e) {
var n = t - r(e);
return e += (new Array(n + 1)).join(".0"), i(e.split("."), function(e) {
return (new Array(20 - e.length)).join("0") + e
}).reverse()
});
while (--t >= 0) {
if (n[0][t] > n[1][t]) return 1;
if (n[0][t] !== n[1][t]) return -1;
if (t === 0) return 0
}
}
function o(e, r, i) {
var o = n;
typeof r == "string" && (i = r, r = void 0), r === void 0 && (r = !1), i && (o = t(i));
var u = "" + o.version;
for (var a in e)
if (e.hasOwnProperty(a) && o[a]) {
if (typeof e[a] != "string") throw new Error("Browser version in the minVersion map should be a string: " + a + ": " + String(e));
return s([u, e[a]]) < 0
}
return r
}
function u(e, t, n) {
return !o(e, t, n)
}
var e = !0,
n = t(typeof navigator != "undefined" ? navigator.userAgent || "" : "");
return n.test = function(e) {
for (var t = 0; t < e.length; ++t) {
var r = e[t];
if (typeof r == "string" && r in n) return !0
}
return !1
}, n.isUnsupportedBrowser = o, n.compareVersions = s, n.check = u, n._detect = t, n.detect = t, n
})
/*!
* clipboard.js v2.0.0
* https://zenorocha.github.io/clipboard.js
*
* Licensed MIT © Zeno Rocha
*/
! function(t, e) {
"object" == typeof exports && "object" == typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define([], e) : "object" == typeof exports ? exports.ClipboardJS = e() : t.ClipboardJS = e()
}(this, function() {
return function(t) {
function e(o) {
if (n[o]) return n[o].exports;
var r = n[o] = {
i: o,
l: !1,
exports: {}
};
return t[o].call(r.exports, r, r.exports, e), r.l = !0, r.exports
}
var n = {};
return e.m = t, e.c = n, e.i = function(t) {
return t
}, e.d = function(t, n, o) {
e.o(t, n) || Object.defineProperty(t, n, {
configurable: !1,
enumerable: !0,
get: o
})
}, e.n = function(t) {
var n = t && t.__esModule ? function() {
return t.default
} : function() {
return t
};
return e.d(n, "a", n), n
}, e.o = function(t, e) {
return Object.prototype.hasOwnProperty.call(t, e)
}, e.p = "", e(e.s = 3)
}([function(t, e, n) {
var o, r, i;
! function(a, c) {
r = [t, n(7)], o = c, void 0 !== (i = "function" == typeof o ? o.apply(e, r) : o) && (t.exports = i)
}(0, function(t, e) {
"use strict";
function n(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}
var o = function(t) {
return t && t.__esModule ? t : {
default: t
}
}(e),
r = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
},
i = function() {
function t(t, e) {
for (var n = 0; n < e.length; n++) {
var o = e[n];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
}
}
return function(e, n, o) {
return n && t(e.prototype, n), o && t(e, o), e
}
}(),
a = function() {
function t(e) {
n(this, t), this.resolveOptions(e), this.initSelection()
}
return i(t, [{
key: "resolveOptions",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
this.action = t.action, this.container = t.container, this.emitter = t.emitter, this.target = t.target, this.text = t.text, this.trigger = t.trigger, this.selectedText = ""
}
}, {
key: "initSelection",
value: function() {
this.text ? this.selectFake() : this.target && this.selectTarget()
}
}, {
key: "selectFake",
value: function() {
var t = this,
e = "rtl" == document.documentElement.getAttribute("dir");
this.removeFake(), this.fakeHandlerCallback = function() {
return t.removeFake()
}, this.fakeHandler = this.container.addEventListener("click", this.fakeHandlerCallback) || !0, this.fakeElem = document.createElement("textarea"), this.fakeElem.style.fontSize = "12pt", this.fakeElem.style.border = "0", this.fakeElem.style.padding = "0", this.fakeElem.style.margin = "0", this.fakeElem.style.position = "absolute", this.fakeElem.style[e ? "right" : "left"] = "-9999px";
var n = window.pageYOffset || document.documentElement.scrollTop;
this.fakeElem.style.top = n + "px", this.fakeElem.setAttribute("readonly", ""), this.fakeElem.value = this.text, this.container.appendChild(this.fakeElem), this.selectedText = (0, o.default)(this.fakeElem), this.copyText()
}
}, {
key: "removeFake",
value: function() {
this.fakeHandler && (this.container.removeEventListener("click", this.fakeHandlerCallback), this.fakeHandler = null, this.fakeHandlerCallback = null), this.fakeElem && (this.container.removeChild(this.fakeElem), this.fakeElem = null)
}
}, {
key: "selectTarget",
value: function() {
this.selectedText = (0, o.default)(this.target), this.copyText()
}
}, {
key: "copyText",
value: function() {
var t = void 0;
try {
t = document.execCommand(this.action)
} catch (e) {
t = !1
}
this.handleResult(t)
}
}, {
key: "handleResult",
value: function(t) {
this.emitter.emit(t ? "success" : "error", {
action: this.action,
text: this.selectedText,
trigger: this.trigger,
clearSelection: this.clearSelection.bind(this)
})
}
}, {
key: "clearSelection",
value: function() {
this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges()
}
}, {
key: "destroy",
value: function() {
this.removeFake()
}
}, {
key: "action",
set: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "copy";
if (this._action = t, "copy" !== this._action && "cut" !== this._action) throw new Error('Invalid "action" value, use either "copy" or "cut"')
},
get: function() {
return this._action
}
}, {
key: "target",
set: function(t) {
if (void 0 !== t) {
if (!t || "object" !== (void 0 === t ? "undefined" : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element');
if ("copy" === this.action && t.hasAttribute("disabled")) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
if ("cut" === this.action && (t.hasAttribute("readonly") || t.hasAttribute("disabled"))) throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
this._target = t
}
},
get: function() {
return this._target
}
}]), t
}();
t.exports = a
})
}, function(t, e, n) {
function o(t, e, n) {
if (!t && !e && !n) throw new Error("Missing required arguments");
if (!c.string(e)) throw new TypeError("Second argument must be a String");
if (!c.fn(n)) throw new TypeError("Third argument must be a Function");
if (c.node(t)) return r(t, e, n);
if (c.nodeList(t)) return i(t, e, n);
if (c.string(t)) return a(t, e, n);
throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")
}
function r(t, e, n) {
return t.addEventListener(e, n), {
destroy: function() {
t.removeEventListener(e, n)
}
}
}
function i(t, e, n) {
return Array.prototype.forEach.call(t, function(t) {
t.addEventListener(e, n)
}), {
destroy: function() {
Array.prototype.forEach.call(t, function(t) {
t.removeEventListener(e, n)
})
}
}
}
function a(t, e, n) {
return u(document.body, t, e, n)
}
var c = n(6),
u = n(5);
t.exports = o
}, function(t, e) {
function n() {}
n.prototype = {
on: function(t, e, n) {
var o = this.e || (this.e = {});
return (o[t] || (o[t] = [])).push({
fn: e,
ctx: n
}), this
},
once: function(t, e, n) {
function o() {
r.off(t, o), e.apply(n, arguments)
}
var r = this;
return o._ = e, this.on(t, o, n)
},
emit: function(t) {
var e = [].slice.call(arguments, 1),
n = ((this.e || (this.e = {}))[t] || []).slice(),
o = 0,
r = n.length;
for (o; o < r; o++) n[o].fn.apply(n[o].ctx, e);
return this
},
off: function(t, e) {
var n = this.e || (this.e = {}),
o = n[t],
r = [];
if (o && e)
for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]);
return r.length ? n[t] = r : delete n[t], this
}
}, t.exports = n
}, function(t, e, n) {
var o, r, i;
! function(a, c) {
r = [t, n(0), n(2), n(1)], o = c, void 0 !== (i = "function" == typeof o ? o.apply(e, r) : o) && (t.exports = i)
}(0, function(t, e, n, o) {
"use strict";
function r(t) {
return t && t.__esModule ? t : {
default: t
}
}
function i(t, e) {
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
}
function a(t, e) {
if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
return !e || "object" != typeof e && "function" != typeof e ? t : e
}
function c(t, e) {
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function, not " + typeof e);
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
enumerable: !1,
writable: !0,
configurable: !0
}
}), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : t.__proto__ = e)
}
function u(t, e) {
var n = "data-clipboard-" + t;
if (e.hasAttribute(n)) return e.getAttribute(n)
}
var l = r(e),
s = r(n),
f = r(o),
d = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
return typeof t
} : function(t) {
return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
},
h = function() {
function t(t, e) {
for (var n = 0; n < e.length; n++) {
var o = e[n];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
}
}
return function(e, n, o) {
return n && t(e.prototype, n), o && t(e, o), e
}
}(),
p = function(t) {
function e(t, n) {
i(this, e);
var o = a(this, (e.__proto__ || Object.getPrototypeOf(e)).call(this));
return o.resolveOptions(n), o.listenClick(t), o
}
return c(e, t), h(e, [{
key: "resolveOptions",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
this.action = "function" == typeof t.action ? t.action : this.defaultAction, this.target = "function" == typeof t.target ? t.target : this.defaultTarget, this.text = "function" == typeof t.text ? t.text : this.defaultText, this.container = "object" === d(t.container) ? t.container : document.body
}
}, {
key: "listenClick",
value: function(t) {
var e = this;
this.listener = (0, f.default)(t, "click", function(t) {
return e.onClick(t)
})
}
}, {
key: "onClick",
value: function(t) {
var e = t.delegateTarget || t.currentTarget;
this.clipboardAction && (this.clipboardAction = null), this.clipboardAction = new l.default({
action: this.action(e),
target: this.target(e),
text: this.text(e),
container: this.container,
trigger: e,
emitter: this
})
}
}, {
key: "defaultAction",
value: function(t) {
return u("action", t)
}
}, {
key: "defaultTarget",
value: function(t) {
var e = u("target", t);
if (e) return document.querySelector(e)
}
}, {
key: "defaultText",
value: function(t) {
return u("text", t)
}
}, {
key: "destroy",
value: function() {
this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), this.clipboardAction = null)
}
}], [{
key: "isSupported",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : ["copy", "cut"],
e = "string" == typeof t ? [t] : t,
n = !!document.queryCommandSupported;
return e.forEach(function(t) {
n = n && !!document.queryCommandSupported(t)
}), n
}
}]), e
}(s.default);
t.exports = p
})
}, function(t, e) {
function n(t, e) {
for (; t && t.nodeType !== o;) {
if ("function" == typeof t.matches && t.matches(e)) return t;
t = t.parentNode
}
}
var o = 9;
if ("undefined" != typeof Element && !Element.prototype.matches) {
var r = Element.prototype;
r.matches = r.matchesSelector || r.mozMatchesSelector || r.msMatchesSelector || r.oMatchesSelector || r.webkitMatchesSelector
}
t.exports = n
}, function(t, e, n) {
function o(t, e, n, o, r) {
var a = i.apply(this, arguments);
return t.addEventListener(n, a, r), {
destroy: function() {
t.removeEventListener(n, a, r)
}
}
}
function r(t, e, n, r, i) {
return "function" == typeof t.addEventListener ? o.apply(null, arguments) : "function" == typeof n ? o.bind(null, document).apply(null, arguments) : ("string" == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function(t) {
return o(t, e, n, r, i)
}))
}
function i(t, e, n, o) {
return function(n) {
n.delegateTarget = a(n.target, e), n.delegateTarget && o.call(t, n)
}
}
var a = n(4);
t.exports = r
}, function(t, e) {
e.node = function(t) {
return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType
}, e.nodeList = function(t) {
var n = Object.prototype.toString.call(t);
return void 0 !== t && ("[object NodeList]" === n || "[object HTMLCollection]" === n) && "length" in t && (0 === t.length || e.node(t[0]))
}, e.string = function(t) {
return "string" == typeof t || t instanceof String
}, e.fn = function(t) {
return "[object Function]" === Object.prototype.toString.call(t)
}
}, function(t, e) {
function n(t) {
var e;
if ("SELECT" === t.nodeName) t.focus(), e = t.value;
else if ("INPUT" === t.nodeName || "TEXTAREA" === t.nodeName) {
var n = t.hasAttribute("readonly");
n || t.setAttribute("readonly", ""), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute("readonly"), e = t.value
} else {
t.hasAttribute("contenteditable") && t.focus();
var o = window.getSelection(),
r = document.createRange();
r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), e = o.toString()
}
return e
}
t.exports = n
}])
});
/*! Lazy Load 2.0.0-beta.2 - MIT license - Copyright 2007-2017 Mika Tuupola */ ! function(t, e) {
"object" == typeof exports ? module.exports = e(t) : "function" == typeof define && define.amd ? define([], e(t)) : t.LazyLoad = e(t)
}("undefined" != typeof global ? global : this.window || this.global, function(t) {
"use strict";
function e(t, e) {
this.settings = r(s, e || {}), this.images = t || document.querySelectorAll(this.settings.selector), this.observer = null, this.init()
}
const s = {
src: "data-src",
srcset: "data-srcset",
selector: ".lazyload"
},
r = function() {
let t = {},
e = !1,
s = 0,
o = arguments.length;
"[object Boolean]" === Object.prototype.toString.call(arguments[0]) && (e = arguments[0], s++);
for (; s < o; s++) ! function(s) {
for (let o in s) Object.prototype.hasOwnProperty.call(s, o) && (e && "[object Object]" === Object.prototype.toString.call(s[o]) ? t[o] = r(!0, t[o], s[o]) : t[o] = s[o])
}(arguments[s]);
return t
};
if (e.prototype = {
init: function() {
if (!t.IntersectionObserver) return void this.loadImages();
let e = this,
s = {
root: null,
rootMargin: "0px",
threshold: [0]
};
this.observer = new IntersectionObserver(function(t) {
t.forEach(function(t) {
if (t.intersectionRatio > 0) {
e.observer.unobserve(t.target);
let s = t.target.getAttribute(e.settings.src),
r = t.target.getAttribute(e.settings.srcset);
"img" === t.target.tagName.toLowerCase() ? (s && (t.target.src = s), r && (t.target.srcset = r)) : t.target.style.backgroundImage = "url(" + s + ")"
}
})
}, s), this.images.forEach(function(t) {
e.observer.observe(t)
})
},
loadAndDestroy: function() {
this.settings && (this.loadImages(), this.destroy())
},
loadImages: function() {
if (!this.settings) return;
let t = this;
this.images.forEach(function(e) {
let s = e.getAttribute(t.settings.src),
r = e.getAttribute(t.settings.srcset);
"img" === e.tagName.toLowerCase() ? (s && (e.src = s), r && (e.srcset = r)) : e.style.backgroundImage = "url(" + s + ")"
})
},
destroy: function() {
this.settings && (this.observer.disconnect(), this.settings = null)
}
}, t.lazyload = function(t, s) {
return new e(t, s)
}, t.jQuery) {
const s = t.jQuery;
s.fn.lazyload = function(t) {
return t = t || {}, t.attribute = t.attribute || "data-src", new e(s.makeArray(this), t), this
}
}
return e
});
;(function() {
lazyload();
})();
'use strict';
var memory = Cookies.getJSON('memory') || {};
var html_el = document.documentElement;
var platform_el = document.getElementById('platform');
var os_el = document.getElementById('os');
var browser_el = document.getElementById('browser');
var browser_width_el = document.getElementById('browserWidth');
var wider_el = document.getElementById('wider');
var return_el = document.getElementById('return');
var resume_el = document.getElementById('resume');
var reset_el = document.getElementById('reset');
var state = {
current_step: 0,
platform: '',
browser: '',
os: ''
};
window.old_alert = window.alert;
window.alert = function (str) {
window.old_alert.apply(this, arguments);
var function_to_call = 'checkStep' + state.current_step;
if (window[function_to_call]) {
window[function_to_call](str);
}
};
function checkStep1(str) {
if (str == 'Hello World!') {
return showStep(2);
} else if (str.toLowerCase() == 'hello world!') {
return console.log('Watch out! In JavaScript, uppercase and lowercase letters are different. Make sure all letters have the proper case.');
}
console.log('Please type the correct string.');
}
function checkStep5(str) {
if (str == 24) {
return showStep(6);
}
console.log('Try again!');
}
function checkStep7(str) {
if (str == window.innerWidth) {
browser_width_el.innerHTML = window.innerWidth;
return showStep(8);
}
console.log('The answer should be ' + window.innerWidth + '!');
}
function checkStep10(str) {
if (str == window.location.href) {
return showStep(11);
}
}
function checkStep12(str) {
if (str == 'OMG') {
return showStep(13);
}
}
function checkStep14(str) {
if (str == 'What,is,up') {
return showStep(15);
}
}
function checkStep15(str) {
if (str == '7,samurai,true') {
return showStep(16);
}
}
function checkStep18(str) {
if (!state.desktop) {
return showStep(19);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (str == my_things) {
return showStep(19);
}
}
function checkStep19(str) {
if (!state.desktop) {
return showStep(20);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (my_things.length < 2) {
return console.log('Please create an array with at least 2 items.');
} else if (str != my_things[1]) {
return console.log('Please choose the item at index 1.');
} else if (str == my_things[1]) {
return showStep(20);
}
console.log('Please create an array called "my_things" and choose the item at index 1.');
}
function checkStep20(str) {
if (!state.desktop) {
return showStep(21);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (str == my_things.length) {
return showStep(21);
}
console.log('Please create an array called "my_things".');
}
function checkStep21(str) {
if (!state.desktop) {
return showStep(22);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (str == '7,samurai,true') {
return;
} else if (str == '7,samurai,true,LOVE') {
return showStep(22);
}
console.log('Please create an array called "my_things" and add the string "LOVE".');
}
function checkStep22(str) {
if (!state.desktop) {
return showStep(23);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (str == '7,samurai,true') {
return;
} else if (str == '7,samurai,true,The Button') {
return showStep(23);
}
console.log('Please create an array called "my_things" and add the string "The Button".');
}
function checkStep23(str) {
if (!state.desktop) {
return showStep(24);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (str == true) {
return console.log('Please test for an element that is NOT in the array.');
} else if (str == false) {
return showStep(24);
}
console.log('Please create an array called "my_things" and call the method "includes()".');
}
function checkStep24(str) {
if (str == window.innerWidth > 400) {
var displaying = window.innerWidth > 400 ? 'none' : 'inline';
wider.style.display = displaying;
return showStep(25);
}
console.log('Try again!');
}
function checkStep26(str) {
if (str.startsWith('Welcome on my domain')) {
return showStep(27);
}
console.log('Try again!');
}
function checkStep27(str) {
if (str.startsWith('Welcome on my domain')) {
return showStep(28);
} else if (str.startsWith('Please come back soon')) {
return console.log('Make sure you use the "==" operator.');
}
console.log('Try again!');
}
function checkStep28(str) {
if (window.innerWidth > 2000 && str.startsWith('Big screen') || window.innerWidth < 600 && str.startsWith('Probably a mobile phone')) {
return showStep(29);
} else if (str.startsWith('Decent size')) {
return showStep(29);
}
console.log('Make sure you type all statements in the correct order.');
}
function checkStep30(str) {
if (str == '0' || str == '1') {
return;
} else if (str == '2') {
return showStep(31);
}
console.log('Try again!');
}
function checkArrayLoop(str, nextStep) {
if (!state.desktop) {
return showStep(nextStep);
} else if (typeof my_things == 'undefined') {
return console.log('Please create an array called "my_things".');
} else if (my_things.length < 2) {
return console.log('Please create an array with at least 2 items.');
} else if (str == my_things[my_things.length - 1]) {
return showStep(nextStep);
} else if (my_things.includes(str)) {
return;
}
console.log('Please create an array called "my_things" and loop through it.');
}
function checkStep32(str) {
checkArrayLoop(str, 33);
}
function checkStep34(str) {
checkArrayLoop(str, 35);
}
function checkStep36(str) {
if (!state.desktop) {
return showStep(37);
} else if (typeof greet == 'undefined') {
return console.log('Please create a function called "greet".');
} else if (str.startsWith('Hey there ')) {
return showStep(37);
}
console.log('Please create a function called "greet" and call it with the parameter \'Alex\'.');
}
function showStep(num) {
var skipSave = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
showElement('step' + num);
state.current_step = num;
return_el.classList.remove('is-active');
if (!skipSave) {
memory['latest_step'] = num;
Cookies.set('memory', memory);
}
if (num == 3) {
showSide('sides');
showSide('sideConcepts');
showSide('sideFunctions');
} else if (num == 4) {
showSide('sideTypes');
showSide('sideStrings');
} else if (num == 5) {
showSide('sideNumbers');
} else if (num == 9) {
showSide('sideObjects');
} else if (num == 14) {
showSide('sideArrays');
} else if (num == 17) {
showSide('sideBooleans');
} else if (num == 18) {
showSide('sideVariables');
} else if (num == 26) {
showSide('sideConditionals');
} else if (num == 30) {
showSide('sideLoops');
}
}
function showElement(id) {
var el = document.getElementById(id);
if (el) {
el.classList.add('is-active');
el.scrollIntoView(true);
}
}
function showSide(id) {
var el = document.getElementById(id);
if (el) {
el.classList.add('is-active');
}
}
function runSnippet() {
var els = document.querySelectorAll('.run-snippet');
if (els.length > 0) {
els.forEach(function (el) {
var snippet_contents = el.previousElementSibling.firstElementChild.firstElementChild.firstElementChild.firstElementChild;
var snippet_code = snippet_contents.outerText;
var run_button = el.querySelector('a');
run_button.addEventListener('click', function () {
eval(snippet_code);
});
});
}
}
function detectPlatform() {
state.mobile = bowser.mobile || false;
state.tablet = bowser.tablet || false;
state.desktop = !state.mobile && !state.tablet;
if (state.mobile) {
state.platform = 'mobile';
} else if (state.tablet) {
state.platform = 'tablet';
} else if (state.desktop) {
state.platform = 'desktop';
}
if (bowser.chrome || bowser.chromium) {
state.browser = 'chrome';
} else if (bowser.firefox) {
state.browser = 'firefox';
} else if (bowser.msedge) {
state.browser = 'edge';
} else if (bowser.safari) {
state.browser = 'safari';
} else if (bowser.opera) {
state.browser = 'opera';
}
if (bowser.mac) {
state.os = 'mac';
} else if (bowser.windows) {
state.os = 'windows';
} else if (bowser.linux) {
state.os = 'linux';
}
os_el.value = state.os;
browser_el.value = state.browser;
setPlatform();
}
function setPlatform() {
html_el.className = '';
html_el.classList.add('case-' + state.platform);
html_el.classList.add('case-' + state.browser);
html_el.classList.add('case-' + state.os);
}
function jumpToStep(num) {
for (var i = 1; i <= num; i++) {
showStep(i, true);
}
}
function resetSteps() {
return_el.classList.remove('is-active');
window.scrollTo(0, 0);
memory = {};
Cookies.remove('memory');
}
document.addEventListener('DOMContentLoaded', function () {
detectPlatform();
runSnippet();
os_el.addEventListener('change', function (event) {
state.os = event.target.value;
setPlatform();
});
browser_el.addEventListener('change', function (event) {
state.browser = event.target.value;
setPlatform();
});
resume_el.addEventListener('click', function (event) {
jumpToStep(memory.latest_step);
});
reset_el.addEventListener('click', function (event) {
var answer = confirm('Are you sure?');
if (answer == true) {
resetSteps();
}
});
if (memory && memory.hasOwnProperty('latest_step')) {
return_el.classList.add('is-active');
}
new ClipboardJS('.snippet-copy', {
target: function target(trigger) {
return trigger.previousElementSibling.firstElementChild.firstElementChild.firstElementChild.firstElementChild;
}
});
});
</script>
</body>
</html>