markdown FCC 48G计算器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown FCC 48G计算器相关的知识,希望对你有一定的参考价值。


html {
  height: 100%;
}

body {
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAEUlEQVQImWNgYGD4z4AGMAUANfEC/vDaGN0AAAAASUVORK5CYII=) repeat fixed,
              url(https://c2.staticflickr.com/6/5077/5864814103_710f2f5b70_b.jpg)
              center center no-repeat fixed;
  background-size: auto, cover;
}

.container {
  -webkit-perspective: 1000px;
          perspective: 1000px;
}

.right {
  float: right;
}

.left {
  float: left;
}

.hide {
  display: none;
}

#overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: hsla(0, 0%, 0%, 0.7);
  z-index: 9;
  visibility: hidden;
  opacity: 0;
  -webkit-transition: all 0.75s ease;
  transition: all 0.75s ease;
}

#overlay.overlay-show {
  visibility: visible;
  opacity: 1;
}

#modal {
  position: absolute;
  top: 40px;
  width: 275px;
  margin-left: -140px;
  left: 50%;
  z-index: 10;
  opacity: 0;
  -webkit-transform: translateY(-30px);
          transform: translateY(-30px);
  -webkit-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

#modal.modal-show {
  opacity: 1;
  -webkit-transform: translateY(0px);
          transform: translateY(0px);
}

.modal-tab {
  background-color: hsl(360, 50%, 50%);
  border-top-right-radius: 10px;
  border-top-left-radius: 10px;
  width: 50px;
  padding: 5px 5px 0px 5px;
}

.modal-content {
  background-color: white;
  padding: 5px;
  border-width: 5px 2px 2px 2px;
  border-style: solid;
  border-color: hsl(360, 50%, 50%);
}

.image {
  padding: 5px;
  width: 95%;
  border: 1px solid black;
}

.caption {
  font-size: 0.58em;
  margin-top: 0;
}

#calculator {
  width: 300px;
  border: 3px solid black;
  outline: 1px solid transparent;
  border-radius: 10px;
  margin: auto;
  overflow: hidden;
  -webkit-transform: rotateX(4deg);
          transform: rotateX(4deg);
  box-shadow: 1px 5px 3px 0px hsla(0, 0%, 0%, 1),
              0 0px 2px 2px hsla(0, 0%, 60%, 0.9) inset,
              0 0px 0px 8px hsla(0, 0%, 0%, 1) inset;
  padding: 8px;
}

#logo {
  cursor: pointer;
}

.flash {
  -webkit-animation: flash 2s;
          animation: flash 2s;
}

@-webkit-keyframes flash {
  0% { }
  30% {
    background-color: hsla(60, 100%, 75%, 0.5);
    box-shadow: 0px 0px 20px 5px hsl(60, 100%, 75%);
  }
  70% {
    background-color: hsl(60, 100%, 75%);
    box-shadow: 0px 0px 20px 5px hsl(60, 100%, 75%);
  }
  100% { background-color: none;}
}

@keyframes flash {
  0% { }
  30% {
    background-color: hsla(60, 100%, 75%, 0.5);
    box-shadow: 0px 0px 20px 5px hsl(60, 100%, 75%);
  }
  70% {
    background-color: hsl(60, 100%, 75%);
    box-shadow: 0px 0px 20px 5px hsl(60, 100%, 75%);
  }
  100% { background-color: none;}
}



/*                     */
/*     Screen Area     */
/*                     */

#screen-container {
  background-color: hsl(200, 5%, 40%);
  position:relative;
  z-index: 1;
  height: 200px;
  padding: 40px 20px 20px;
  box-shadow: 0 2px 2px 2px hsla(0, 0%, 0%, 0.7),
              0 0px 2px 2px hsla(0, 0%, 0%, 0.7) inset;
}

#top-header {
  position: absolute;
  top: 5px;
  left: 20px;
  height: 25px;
  width: 260px;
  vertical-align: middle;
  background-color: hsl(200, 5%, 40%);
  color: hsl(140, 0%, 90%);
  z-index: 2;
}

.large {
  font-size: 1.5em;
}

.small-fa {
  font-size: 0.8em;
}

.middle {
  vertical-align: middle;
}

.blue {
  color: hsl(180, 100%, 40%);
}

.nudge-fa {
  top: 3px !important;
  left: -4px !important;
}


#screen {
  position: relative;
  font-family: 'Play', sans-serif;
  font-size: 14px;
  background-color: hsla(40, 25%, 50%, 1);
  height: 100%;
  width: 100%;
}

#screen::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAGElEQVQImWNggIIFXfFpDCicBV3xaTAMAH0OCaz5r9XrAAAAAElFTkSuQmCC) repeat;
  box-shadow: 0 -1px 3px 2px hsla(0, 50%, 0%, 0.8),
              0 -1px 3px 2px black inset;
  pointer-events: none;
}

.screen-header-container {
  padding: 5px 3px 3px 3px;
}

.screen-header {
  padding: 0 5px;
}

.screen-header-row div {
  display: inline-block;
}

.screen-header-container hr {
  border-color: hsl(130, 15%, 10%);
  margin: 0;
}

.screen-main-display-container {

    position: absolute;
    bottom: 30px;
}

.screen-main-display {
  height: 145px;
  width: 600px;
  display: table-cell;
  vertical-align: bottom;
  padding: 0 10px;
  font-size: 22px;
}

.line {
  text-align: right;
  clear: both;
}

.line-content {
  width: 100%;
}

.input-line {
  text-align: left;
}

.cursor {
  //font-size: 0.8em;
  -webkit-animation: blinker 1000ms linear infinite;
          animation: blinker 1000ms linear infinite;
}
@-webkit-keyframes blinker {
  0% { opacity: 1.0; }
  50% { opacity: 0.0; }
  100% { opacity: 1.0; }
}
@keyframes blinker {
  0% { opacity: 1.0; }
  50% { opacity: 0.0; }
  100% { opacity: 1.0; }
}

.screen-menus {
  position: absolute;
  bottom: 3px;
  left: 5px;
}
.menu {
  display: inline-block;
  vertical-align: top;
  position: relative;
  width: 35px;
  height: 15px;
  margin-bottom: 2px;
  text-align: center;
  padding: 2px 2px;
  color: hsla(40, 25%, 50%, 1);
  background-color: hsl(130, 15%, 10%);
}

.menu-folder::before {
  content: '';
  position: absolute;
  top: -3px;
  left: 1px;
  height: 3px;
  width: 10px;
  background-color: hsl(130, 35%, 10%);
}



/*                     */
/*     Keypad Area     */
/*                     */
#keys {
  background-color: hsl(200, 5%, 30%);
  text-align: center;
  position: relative;
  padding-bottom: 15px;
}

#keys:after {
	content:'';
	position: absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
	z-index:1;
	box-shadow: 1px 1px 2px 4px hsla(0, 0%, 0%, 0.8) inset;
  pointer-events: none;
}

.key-button {
  display: table;
  background-color: hsl(200, 5%, 20%);
  color: #fff;
  border: 1px solid hsl(200, 5%, 5%);
  border-radius: 5px;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  box-shadow: 0px 2px black,
              2px 2px 2px 1px hsla(0, 50%, 0%, 0.8),
              -1px -1px 1px 0px hsla(0, 50%, 0%, 0.4) inset,
              0px 0px 4px 1px hsla(200, 5%, 10%, 0.8) inset,
              0px 0px 0px 3px hsl(200, 5%, 20%) inset;
  -webkit-transition: hover 100ms ease-out;
  transition: hover 100ms ease-out;
  cursor: pointer;
}

.key-button:active {
  -webkit-transform: translateX(2px);
          transform: translateX(2px);
  box-shadow: 0px 2px black,
              -1px -1px 1px 0px hsla(0, 50%, 0%, 0.4) inset,
              0px 0px 4px 1px hsla(200, 5%, 10%, 0.8) inset,
              0px 0px 0px 3px hsl(200, 5%, 20%) inset;
}

.key-text {
  width: 100%;
  height: 100%;
  display: table-cell;
  vertical-align: middle;
  pointer-events: none;
}

/*                    */
/*     Small Keys    */
/*                    */
.key-small-container {
  position: relative;
  display: inline-block;
  margin: -2px;
  width: 49px;
  height: 45px;
  vertical-align: bottom;
}

.key-small-button {
  position: absolute;
  bottom: 5px;
  left: 50%;
  width: 36px;
  height: 20px;
  margin-left: -19px;
  font-size: 0.8em;
}

.key-enter-container {
  width: 98px;
}

.key-enter-button {
  width: 87px;
  left: 25%;
}


/*                    */
/*     Large Keys    */
/*                    */
.key-large-container {
  position: relative;
  display: inline-block;
  margin: 4px -1px -1px -1px;
  width: 55px;
  height: 51px;
  vertical-align: bottom;
}

.key-large-button {
  position: absolute;
  bottom: 5px;
  left: 50%;
  width: 44px;
  height: 28px;
  margin-left: -24px;
  //border: 1px solid black;
}

.key-bg-light {
  background-color: hsl(200, 5%, 40%);
}

/*                    */
/*     Alt Keys       */
/*                    */

.key-alt {
  font-size: 0.7em;
  margin-top: 4px;
  text-transform: uppercase;
  font-weight: bold;
  white-space: nowrap;
}
.key-alt-1 {
  background-color: hsl(300, 40%, 50%);
  color: hsl(200, 5%, 20%);
}

.key-alt-2 {
  background-color: hsl(125, 40%, 50%);
  color: hsl(200, 5%, 20%);
}

.key-alt-text-1 {
  color: hsl(300, 40%, 50%);
}

.key-alt-text-2 {
  color: hsl(125, 40%, 50%);
  padding-left: 2px;
}

.math {
  text-transform: none;
}

sup {
  vertical-align: top;
  position: relative;
  top: -0.3em;
}

/*                    */
/*     Option Keys    */
/*                    */
#key-option-row {
  position: relative;
  padding-top: 15px;
  padding-bottom: 10px;
  background-color: hsl(200, 5%, 40%);
  box-shadow: 0 -1px 3px 0px hsla(0, 50%, 0%, 0.8),
              0 -1px 3px 0px black inset;
}

.key-option-container {
  position: relative;
  display: inline-block;
  margin: -2px;
  width: 49px;
  height: 15px;
}

.key-option-button {
  position: absolute;
  bottom: 0px;
  left: 50%;
  width: 32px;
  height: 15px;
  margin-left: -19px;
  background-color: white;
}

/*     Cancel Key    */

#cancel {
  position: absolute;
  bottom: -14px;
  width: 100%;
  color: white;
  font-size: 12px;
}

#attribution-container {
  position: absolute;
  top: 700px;
  bottom: 0px;
  right: 0px;
  min-height: 100px;
  width: 300px;
}

.attribution {
  position: absolute;
  right: 10px;
  bottom: 10px;
  margin-top: 20px;
  padding: 5px;
  background-color: hsla(360, 0%, 0%, 0.4);
  color: #fff;
  font-size: 0.8em;
}
.attribution a {
  color: #fff;
  text-decoration: none;
}
(function(document, window) {
  var $display = document.querySelector('.screen-main-display-container'),
      $headerRow1 = document.querySelector('#header-row1 .screen-header-content'),
      $headerRow1Right = document.querySelector('#header-row1 .screen-header-right'),
      $headerRow2 = document.querySelector('#header-row2 .screen-header-content'),
      $headerRow2Right = document.querySelector('#header-row2 .screen-header-right'),
      $keyAlt1Text = document.querySelectorAll('.key-alt-text-1'),
      $keyAlt2Text = document.querySelectorAll('.key-alt-text-2'),
      $keyButtons = document.querySelectorAll('.key-button'),
      $keyText = document.querySelectorAll('.key-text'),
      $logo = document.querySelector('#logo'),
      $modal = document.querySelector('#modal'),
      $modalClose = document.querySelector('#modal-close'),
      $overlay = document.querySelector('#overlay'),
      altBtnState = '',
      cancelKey = 'k38',
      cursorPosition = 0,
      defaultLineNums = ["1:", "2:", "3:", "4:", "5:"],
      inputLine = false,
      inputMode = 'dec',
      keyboardKeyMap,
      keyMap,
      maxDispDigits = 9,
      maxLineChars = 18,
      menu,
      menuSlots = 6,  // number of menu spaces on screen
      mode = 'deg',
      reDec = new RegExp(/^([\-\+]?)([\d]*)(\.?)([\d]*)([Ee][\-\+]?[\d]+)?$/),
      screenStack = {
        lineNumbers: defaultLineNums.slice(),
        lineContents: []
      };

  keyboardKeyMap = {
    // number pad 0-9 and '.'
    '96': 'k39',
    '97': 'k34',
    '98': 'k35',
    '99': 'k36',
    '100': 'k29',
    '101': 'k30',
    '102': 'k31',
    '103': 'k24',
    '104': 'k25',
    '105': 'k26',
    '110': 'k40',
    // number keys 0-9 and '.'
    '48': 'k39',
    '49': 'k34',
    '50': 'k35',
    '51': 'k36',
    '52': 'k29',
    '53': 'k30',
    '54': 'k31',
    '55': 'k24',
    '56': 'k25',
    '57': 'k26',
    '190': 'k40',
    '13': 'k18',  // etner key
    '107': 'k42',  // '+' key
    '109': 'k37',  // '-' key
    '106': 'k32',  // '*' key
    '111': 'k27',  // '/' key
    '69': 'k41',  // 'e' key
    '8': 'k22',  // backspace key
    '46': 'k21',  // delete key
    '37': 'k15',  // ArrowLeft key
    '39': 'k17',  // ArrowRight key
    '38': 'k10',  // ArrowUp key
    '40': 'k16',  // ArrowDown key
    '27': 'k38'// Escape key
  };


  function forEachNode(NodeList, callback, scope) {
    for(var i = 0; i < NodeList.length; i++) {
      callback.call(scope, NodeList[i], i);
    }
  }

  /**
    *
    *Initialization and Setup Functions
    *
  */

  //setKeys function maps text onto appropriate key.
  function setKeys() {
    //set text for each key
    forEachNode($keyText, function(node, ind) {
      node.innerHTML = keyMap["k" + ind].main.text || "~k" + ind + "~";
    });

    //set alt1 text for each key
    forEachNode($keyAlt1Text, function(node, ind) {
      var offset = ind + 6; //compensate for 6 top keys w/o alt text
      node.innerHTML = keyMap["k" + offset].alt1.text;
    });

    //set alt2 text for each key
    forEachNode($keyAlt2Text, function(node, ind) {
      var offset = ind + 6; //compensate for 6 top keys w/o alt text
      node.innerHTML = keyMap["k" + offset].alt2.text;
    });

    //set Cancel key (overrides key's native main func)
    //should be bottom row key or text will interfere
    var CancelKeyNode = document.createElement("div");
    CancelKeyNode.id = "cancel"
    CancelKeyNode.innerHTML = "Cancel"

    document.getElementById(cancelKey).parentElement.appendChild(CancelKeyNode);
    keyMap[cancelKey].main.func = clearInputLine;
  }

  // set the keyMap object.  This is in a function so that other objects
  // which may be needed can be instantiated first.
  function setKeyMap() {
    keyMap = {
      "k0": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k1": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k2": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k3": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k4": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k5": {
        "main": {
          "text": " ",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k6": {
        "main": {
          "text": "Main",
          "arg": "main",
          "func": menu.goToMenu
        },
        "alt1": {
          "text": "A",
          "arg": "A",
          "func": numClick
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k7": {
        "main": {
          "text": "sin",
          "arg": [1, sin],
          "func": stackOperation
        },
        "alt1": {
          "text": "B",
          "arg": "B",
          "func": numClick
        },
        "alt2": {
          "text": "asin",
          "arg": [1, asin],
          "func": stackOperation
        }
      },
      "k8": {
        "main": {
          "text": "cos",
          "arg": [1, cos],
          "func": stackOperation
        },
        "alt1": {
          "text": "C",
          "arg": "C",
          "func": numClick
        },
        "alt2": {
          "text": "acos",
          "arg": [1, acos],
          "func": stackOperation
        }
      },
      "k9": {
        "main": {
          "text": "tan",
          "arg": [1, tan],
          "func": stackOperation
        },
        "alt1": {
          "text": "D",
          "arg": "D",
          "func": numClick
        },
        "alt2": {
          "text": "atan",
          "arg": [1, atan],
          "func": stackOperation
        }
      },
      "k10": {
        "main": {
          "text": "<i class='fa fa-chevron-up'></i>",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "E",
          "arg": "E",
          "func": numClick
        },
        "alt2": {
          "text": "Up",
          "arg": "",
          "func": menu.goToPrevMenu
        }
      },
      "k11": {
        "main": {
          "text": "Next",
          "arg": "",
          "func": nextMenu
        },
        "alt1": {
          "text": "F",
          "arg": "F",
          "func": numClick
        },
        "alt2": {
          "text": "Prev",
          "arg": "",
          "func": ""
        }
      },
      "k12": {
        "main": {
          "text": "&radic;x",
          "arg": [1, squareRoot],
          "func": stackOperation
        },
        "alt1": {
          "text": "<span class='math'>x<sup>2</sup></span>",
          "arg": [1, squared],
          "func": stackOperation
        },
        "alt2": {
          "text": "<span class='math'><sup>x</sup>&radic;y</span>",
          "arg": [2, xthRoot],
          "func": stackOperation
        }
      },
      "k13": {
        "main": {
          "text": "y<sup>x</sup>",
          "arg": [2, xthPower],
          "func": stackOperation
        },
        "alt1": {
          "text": "<span class='math'>10<sup>x</sup></span>",
          "arg": [1, tenPow],
          "func": stackOperation
        },
        "alt2": {
          "text": "log",
          "arg": [1, log10],
          "func": stackOperation
        }
      },
      "k14": {
        "main": {
          "text": "1/x",
          "arg": [1, inverse],
          "func": stackOperation
        },
        "alt1": {
          "text": "<span class='math'>e<sup>x</sup></span>",
          "arg": [1, exp],
          "func": stackOperation
        },
        "alt2": {
          "text": "ln",
          "arg": [1, ln10],
          "func": stackOperation
        }
      },
      "k15": {
        "main": {
          "text": "<i class='fa fa-chevron-left'></i>",
          "arg": "",
          "func": cursorLeft
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k16": {
        "main": {
          "text": "<i class='fa fa-chevron-down'></i>",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k17": {
        "main": {
          "text": "<i class='fa fa-chevron-right'></i>",
          "arg": "",
          "func": cursorRight
        },
        "alt1": {
          "text": "Swap",
          "arg": "",
          "func": swapLines
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k18": {
        "main": {
          "text": "ENTER",
          "arg": "",
          "func": enterKey
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k19": {
        "main": {
          "text": "&pi;",
          "arg": "",
          "func": piKey
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k20": {
        "main": {
          "text": "mod",
          "arg": [2, modulo],
          "func": stackOperation
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k21": {
        "main": {
          "text": "DEL",
          "arg": "",
          "func": clearStack
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k22": {
        "main": {
          "text": "<i class='fa fa-arrow-left'></i>",
          "arg": "",
          "func": delKey
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k23": {
        "main": {
          "text": "+/-",
          "arg": "",
          "func": toggleSign
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k24": {
        "main": {
          "text": "7",
          "arg": 7,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k25": {
        "main": {
          "text": "8",
          "arg": 8,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k26": {
        "main": {
          "text": "9",
          "arg": 9,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k27": {
        "main": {
          "text": "/",
          "arg": [2, divide],
          "func": stackOperation
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k28": {
        "main": {
          "text": "<i class='fa fa-reply'></i>",
          "arg": "alt1",
          "func": altBtn
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k29": {
        "main": {
          "text": "4",
          "arg": 4,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k30": {
        "main": {
          "text": "5",
          "arg": 5,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k31": {
        "main": {
          "text": "6",
          "arg": 6,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k32": {
        "main": {
          "text": "*",
          "arg": [2, multiply],
          "func": stackOperation
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k33": {
        "main": {
          "text": "<i class='fa fa-share'></i>",
          "arg": "alt2",
          "func": altBtn
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k34": {
        "main": {
          "text": "1",
          "arg": 1,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k35": {
        "main": {
          "text": "2",
          "arg": 2,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k36": {
        "main": {
          "text": "3",
          "arg": 3,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k37": {
        "main": {
          "text": "-",
          "arg": [2, subtract],
          "func": stackOperation
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k38": {
        "main": {
          "text": "ON",
          "arg": "",
          "func": ""
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k39": {
        "main": {
          "text": "0",
          "arg": 0,
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k40": {
        "main": {
          "text": ".",
          "arg": ".",
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k41": {
        "main": {
          "text": "EE",
          "arg": "E",
          "func": numClick
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      },
      "k42": {
        "main": {
          "text": "+",
          "arg": [2,add],
          "func": stackOperation
        },
        "alt1": {
          "text": "",
          "arg": "",
          "func": ""
        },
        "alt2": {
          "text": "",
          "arg": "",
          "func": ""
        }
      }
    };

  }

  /**
    *
    *Screen Functions
    *
  */

  // function returns a copy of the input line with cursor at given position
  function insertCurosr(position) {
    var newLine;

    //verify we're on input line
    if(inputLine === true) {
      //check if input line is array of characters
      if(Array.isArray(screenStack.lineContents[0])) {
        //grab a copy of the input array
        newLine = screenStack.lineContents[0].slice();
      } else { //a string is displayed there, so make it an array.
        newLine = screenStack.lineContents[0].split("");
      }


      //splice in the cursor at the given position
      newLine.splice(position, 0, '<span class="cursor">|</span>');
    }

    return newLine;
  }

  // function to handle excessive characters on a line.
  function formatLine(contents) {
    var formattedLine,
        numExcessChars = contents.length - maxLineChars,
        type = typeof contents,
        startIndex = numExcessChars < 0 ? 0 : numExcessChars;

    if(numExcessChars > 0) {

      if(Array.isArray(contents)) {
        formattedLine = contents.slice();
      } else if(type === 'string') {
        formattedLine = contents.split("");
      }

      if(cursorPosition > startIndex){
        formattedLine.splice(0, contents.length - maxLineChars, "...");
      } else if(cursorPosition <= startIndex && cursorPosition > 1) {
        formattedLine = formattedLine.splice(cursorPosition, maxLineChars - 2);
        formattedLine.unshift("...");
        formattedLine.push("...");
      } else {
        formattedLine = formattedLine.splice(0, maxLineChars - 2);
        formattedLine.push("...");
      }

      if(type === 'string') {
        formattedLine.join("");
      }

    }

    return formattedLine || contents;

  }

  // Format numbers to fit maxDispDigits
  function screenNumberFormat(num) {
    var numLen,
        whole,
        wholeLen;

    // validate input is number, if not attempt conversion.
    if(num === undefined || isNaN(num)) { // if num is undefined should dispaly empty string
      return "";
    } else if(typeof num === 'string') {
      num = parseFloat(num);
    } else if(Array.isArray(num)) {
      num = parseFloat(num.join(""));
    }

    // number of chracters in num
    numLen = num.toString().length;
    whole = Math.floor(num);
    wholeLen = whole.toString().length;

    if(numLen > maxDispDigits) { //num is too large
      // whole number protion is too long then put in exponential form
      if(wholeLen > maxDispDigits ) {
        return num.toExponential(maxDispDigits);
      } else {  // decimals take up too  much room so display in fixed form
        return num.toFixed(maxDispDigits - wholeLen);
      }
    }

    return num;
  }


  // draw the screen
  function refreshScreen() {
    var nodeText = ['<div class="screen-main-display">'],
      j = 1,
      lineNum,
      content;

    // create html for each line
    for (var i = 4; i >= 0; i--) {
      lineNum = screenStack.lineNumbers[i];

      // check for input line and also verify that this is index 0
      // any other index would be anomalous
      if(inputLine === true && i === 0) {

        // insert the cursor and join the input array to be dispalyed as string
        content = formatLine(insertCurosr(cursorPosition)).join("");

        // opening line div tag needs 'input-line' class
        nodeText[j++] = '<div id="line' + i + '" class="line input-line">';
      } else {

        //grabe content from the screenStack object.
        content = screenNumberFormat(screenStack.lineContents[i]);

        // generic opeing line div tag.
        nodeText[j++] = '<div id="line' + i + '" class="line">';
      }

      nodeText[j++] = '<div class="line-number left">';
      nodeText[j++] = lineNum;
      nodeText[j++] = '</div>';
      nodeText[j++] = '<div class="line-content">';
      nodeText[j++] = content;
      nodeText[j++] = '</div>';
      nodeText[j++] = '</div>';
    }

    //close screen-main-dispaly div
    nodeText[j++] = '</div>';

    //replace display with newly created html
    $display.innerHTML = nodeText.join("");

  }


  //Create a new input line
  function openInputLine(char) {
    inputLine = true;
    cursorPosition++;
    //new line is added to front of screenStack
    screenStack.lineNumbers.unshift(""); //has no line number
    screenStack.lineContents.unshift([char.toString()]);
    refreshScreen();
  }

  //Add characters to the input line text
  function concatInputChar(char) {
    screenStack.lineContents[0].splice(cursorPosition, 0, char.toString());
    cursorPosition++;
    refreshScreen();
  }

  //Remove characters from the input line
  function delInputChar() {
    if(cursorPosition > 0) {
      cursorPosition--;
      screenStack.lineContents[0].splice(cursorPosition, 1);
    }
  }

  //Remove the inputLine and return what was there as a float
  function clearInputLine() {
    var input = [];
    //only clear first screenStack entries if current line is
    //an input line.
    if(screenStack.lineNumbers[0] === "") {
      input = screenStack.lineContents[0];
      screenStack.lineNumbers.shift();
      screenStack.lineContents.shift();
      inputLine = false;
      cursorPosition = 0;  // reset cursor position
      refreshScreen();
    }

    return parseFloat(input.join(""));
  }


  // function returns the content of a given line number.
  // line number corresponds to line number on screen.
  // If present, 0 represents input line
  function getLineContents(lineNum) {
    var contents;
    //if input line is present, screenStack.lineContents is indexed correctly
    if(inputLine === true) {
      contents = screenStack.lineContents[lineNum];
    } else {  //if no inptul line, screen line 1 lies at index 0;
      contents = screenStack.lineContents[lineNum - 1] || "";
    }

    return contents;
  }

  function getLineString(lineNum) {
    var str = getLineContents(lineNum);

    return Array.isArray(str) ? str.join("") : str;
  }

  // function clears number of lines specified starting from the bottom of
  // the stack. This occurs irrespective of input line
  function clearLines(num) {
    // defalut to 1 if none specified.
    num = num || 1;

    // delete line conents and numbers for number of lines specified.
    for(var i = 0; i < num; i++) {
      screenStack.lineNumbers.shift();
      screenStack.lineContents.shift();
    }

    //maintain minimum of default line numbers
    if(screenStack.lineNumbers.length < defaultLineNums.length) {
      screenStack.lineNumbers = defaultLineNums.slice();
    }

    // in case was input line, set inputLine to false and reset cursor position
    inputLine = false;
    cursorPosition = 0;
  }

  function addLineToStack(val) {
    var lineNum;

    if(!isNaN(val)) {
      //the next line number value
      lineNum = screenStack.lineNumbers.length + 1;

      //prepend val to the screenStack.lineContents array
      screenStack.lineContents.unshift(val);

      //if another line number is needed, add it to the line numbers.
      if(screenStack.lineContents.length > screenStack.lineNumbers.length) {
        screenStack.lineNumbers.push(lineNum.toString(10) + ":");
      }
    }
  }

  //Place content at a specific line.
  //0 is input line (which may not be visible)
  //If no input line is present, one will be created
  function placeAtLine(lineNum, val) {
    if(lineNum > 0) {
      screenStack.lineContents.splice(lineNum - 1 , 0, val);
    } else {

    }
  }




  /**
    *
    * Menu Functionality
    *
  */

  menu = (function() {
    var $keyOptionButtons = document.querySelectorAll('.key-option-button'),
        $menus = document.querySelectorAll('.menu'),
        slots = menuSlots,
        menuLength,
        mainMenu = 'main',
        menuState = [],
        page = 0,
        screenMenus = {
          main: {
            mode: {
              deg: degKey,
              rad: radKey,
              'd->r': degToRad,
              'r->d': radToDeg
            }
          }
        };

    // Draws appropriate menu text and menu button style
    function drawMenu(menuObj) {
      // get keys for menuObj.  These are the menu block labels
      var keys = Object.keys(menuObj);

      // iterate through the menu divs
      forEachNode($menus, function(node, ind) {
        var key = keys[ind + (page * slots)];

        // if there's something to add to the menus
        if(key) {
          // set the menu html to the key text for each menu
          node.innerHTML = key;

          // check if this key's property is an object.  If so, this is a menu
          // otherwise it is an action button.
          if(typeof menuObj[key] === 'object') {
            node.classList.add('menu-folder');
          } else {
            node.classList.remove('menu-folder');
          }
        } else {  // else ensure the menu space is empty
          node.innerHTML = '';
        }

      });



      menuLength = keys.length;
    }

    function getCurrMenuObj() {
      return menuState.reduce(function(prev, curr) {
        return prev[curr];
      }, screenMenus);
    }

    function nextMenu() {
      if(menuLength > slots) {
        page = ++page % ((menuLength % slots) + 1);
        drawMenu(getCurrMenuObj());
      }
    }

    // navigate to top level menu
    function goToMenu(name) {
      menuState = [name];
      $headerRow2.innerHTML = menuState.join(' -> ');
      drawMenu(getCurrMenuObj());
    }

    // Draws submenu by name relative to the current menu object
    function goToSubMenu(name) {
      menuState.push(name);
      $headerRow2.innerHTML = menuState.join(' -> ');
      drawMenu(getCurrMenuObj());
    }

    function goToPrevMenu() {
      if(menuState.length > 1){
        menuState.pop();
        $headerRow2.innerHTML = menuState.join(' -> ');
        drawMenu(getCurrMenuObj());
      }
    }

    // handle clicks to option buttons
    forEachNode($keyOptionButtons, function(node, ind) {
      node.addEventListener('click', function() {
        var name = $menus[ind].textContent,
            currMenu = getCurrMenuObj();

        if(typeof currMenu[name] === 'object') {  // if button is submenu
          goToSubMenu(name);  // the go to subment
        } else if (typeof currMenu[name] === 'function') {
          currMenu[name]();  // if button is an action/function, run it.
        }

      });
    })

    // initialize the menus
    function init() {
      goToMenu(mainMenu);
    }

    // return the menu object for public reference
    return {
      init: init,
      nextMenu: nextMenu,
      subMenu: goToSubMenu,
      goToMenu: goToMenu,
      goToPrevMenu: goToPrevMenu
    };


  })();



  /**
    *
    * Number Handling
    *
  */

  // returns the number of digits to the right of the decimal.
  function decimalPlaces(num) {
    var decDigits,
        sciDigits,
        match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);

    if (!match) {
      return 0;
    }

    // digits to right of the decimal
    decDigits = match[1] ? match[1].length : 0;

    // decimal places due to scientific notation
    sciDigits = match[2] ? +match[2] : 0;

    return Math.max(0, decDigits - sciDigits);
  }

  // return max decimal places from number arbitrary number of numbers
  function maxDecimalPlaces() {
    var numArr = Array.prototype.slice.call(arguments);

    return numArr.reduce(function(max, curr) {
      return decimalPlaces(curr) > max ? decimalPlaces(curr) : max;
    }, 0);
  }

  function scaleVal() {
    var args = Array.prototype.slice.call(arguments),
        places = maxDecimalPlaces.apply(this, args);

    return Math.pow(10, places);
  }

  /**
    *Calculation/Operation functions
    *These are assigned to keys in the keyMap object
    *
  */

  //
  //Basic Calculator functionality
  //

  //handle any character that needs to be added to input line
  function numClick(char) {
    //check that we have an input line (a line with no line number)
    //otherwise assume input and concat to what's there
    if (screenStack.lineNumbers[0] !== "") {
      openInputLine(char);
    } else {
      concatInputChar(char);
    }

  }

  // toggles a +/- at the given index of an array.
  function toggleSignAt(arr, ind) {
    if(arr[ind] === '+') { //if + make it -
        arr[ind] = '-';
    } else if(arr[ind] === '-') { //if - make it +
        arr[ind] = '+';
    } else {  //else number is implied positive, make it -
        arr.splice(ind, 0, '-');
        cursorPosition++;
    }
  }

  // Take content and return a string with toggled sign for the number portion
  function changeNumberSign(lineContent) {
    var isArray = Array.isArray(lineContent);

    if(isArray) { // lineContent will be array on input line
      toggleSignAt(lineContent, 0);
    } else {
      // other lines contain number, so invert sign
      lineContent *= -1;
    }

    return lineContent;
  }

  // return the index of 'E' for a given line number.
  function indexOfE(lineNum) {
    var num,
        type;

    if(!inputLine) {
      lineNum = lineNum - 1;
    }
    // get info at lineNum
    num = screenStack.lineContents[lineNum];
    type = typeof num;

    //  Find the index of E
    if(Array.isArray(num)) { // if it's an array, join it
      return num.join('').indexOf('E');
    } else if(type === 'Number'){ // if it's a number, toString it.
      return screenStack.lineContents[lineNum].toString().indexOf('E');
    } else if (type === "String") {  // if it's a string, then just find index
      return screenStack.lineContents[lineNum].indexOf('E');
    }

  }

  // toggles the sign of the scientific notation exponent.
  function changeSciSign(lineContent, idxOfE) {
    var isArray = Array.isArray(lineContent);

    if(!isArray) { // line content won't be array for non-input lines
      lineContent.split("");
    }

    toggleSignAt(lineContent, idxOfE + 1);

    return isArray ? lineContent : lineContent.join("");
  }


  //toggle sign of active line
  function toggleSign() {
    var lineNum = inputLine ? 0 : 1,
        currLineContents = getLineContents(lineNum),
        idxOfE;

    // get index of 'E' in case of sci notation.
    idxOfE = indexOfE(lineNum);

    // if cursor is in exponential portion, toggle sign there.
    if(idxOfE > -1 && cursorPosition > idxOfE) {
      changeSciSign(currLineContents, idxOfE);
    } else {  // replace first line of screen with signed version
      screenStack.lineContents[0] = changeNumberSign(currLineContents);
    }

    refreshScreen();
  }

  //validate the syntax of string number for a give mode.
  //  mode: 'dec', 'bin', 'hex'
  function validateSyntax(str, mode) {

    switch(mode) {
      case 'dec':
        return reDec.test(str);
    }

  }

  function enterKey() {
    var val = "";

    if(inputLine === true) {
      val = getLineString(0);
      if(validateSyntax(val, inputMode)) {
        addLineToStack(clearInputLine());
      } else {
        displaySyntaxErr();
      }

    } else {
      val = screenStack.lineContents[0];
      placeAtLine(1, val);
    }

    refreshScreen();
  }

  //Clear the screen stack and reset the line numbers
  function clearStack() {
    //enforce clearing of stack only when input line not present.
    if(inputLine === false) {
      screenStack.lineContents = [];
      screenStack.lineNumbers = defaultLineNums.slice();
      refreshScreen();
    }
  }

  // display syntax error message in the header.
  function displaySyntaxErr() {
    $headerRow1Right.innerHTML = "SYNTAX ERROR";
  }

  function clearSyntaxErr() {
    $headerRow1Right.innerHTML = "";
  }

  // checks the elements of an array and returns false if any are
  // the falsy values used.
  function checkForArgs(arr) {
    return !(arr.some(function(arg) {
      if(arg === undefined || arg === '' || isNaN(arg) || arg === null) {
        return true;
      }
    }));
  }

  // function returs an array of 'num' arguments from the stack in decending
  // order, irrespecitve of the precesnce of the input Line.
  function getFirstLines(num) {
    var arr = [],
        firstLine = 1;  // starting line

    if(inputLine === true) {
      firstLine = 0;  // if on inputline, start with line 0
      num = num - 1;  // adjust num to compensate from starting at zero
    }

    for(var i = firstLine; i <= num; i++ ) {
      if(i === 0) {
        arr.push(parseFloat(getLineString(0))); // handle input line
      } else {
        arr.push(getLineContents(i));
      }
    }

    // check for valid arguments.
    if(checkForArgs(arr)) {
      // return reveresed array so arguemnts are in decending stack order.
      return arr.reverse();
    } else {
      displaySyntaxErr();
      return false;
    }


  }

  // clears the number of lines specfied, runs the callback function
  // on the arguments from those lines, then places the result on the screen.
  function stackOperation(numLinesInOperation, callback) {
    var argsArray = getFirstLines(numLinesInOperation);

    if(argsArray) {
      clearLines(numLinesInOperation);
      addLineToStack(callback.apply(this, argsArray));
    }
    refreshScreen();
  }

  function add(x, y) {
    var scaleFactor = scaleVal(x,y);

    return ( x * scaleFactor + y * scaleFactor ) / scaleFactor;
  }

  function subtract(x, y) {
    var scaleFactor = scaleVal(x,y);

    return ( x * scaleFactor - y * scaleFactor ) / scaleFactor;
  }

  function multiply(x, y) {
    return x * y;
  }

  function divide(x, y) {
    return x / y;
  }

  function modulo(x, y) {
    return x % y;
  }


  //
  // Power/Exponential functionality
  //

  function inverse(x) {
    return 1/x;
  }

  function squareRoot(x) {
    return Math.sqrt(x);
  }

  function xthRoot(x, y) {
    // handle negative numbers with odd roots
    if(x < 0 && y % 2 === 1) {
      return -Math.pow(-x, 1/y);
    } else {
      return Math.pow(x, 1/y);
    }
  }

  function squared(x) {
    return x * x;
  }

  function xthPower(x, y) {
    return Math.pow(x,y);
  }

  function tenPow(x) {
    return Math.pow(10, x);
  }

  function log10(x) {
    return Math.log10(x);
  }

  function ln10(x) {
    return Math.log(x);
  }

  function exp(x) {
    return Math.exp(x);
  }



  //
  // Trig functionality
  //

  function changeMode(angleMode) {
    if(mode === angleMode) {
      return;
    }

    mode = angleMode;
    if(mode === 'rad') {
      $headerRow1.innerHTML = 'rad';
    } else {
      $headerRow1.innerHTML = '';
    }
  }

  function degKey() {
    changeMode('deg');
  }

  function radKey() {
    changeMode('rad');
  }

  function convertToRad(deg) {
    return deg * (Math.PI / 180);
  }

  function convertToDeg(rad) {
    return rad * (180 / Math.PI);
  }

  function degToRad() {
    stackOperation(1, convertToRad);
  }

  function radToDeg() {
    stackOperation(1, convertToDeg);
  }

  function sin(num) {
    if(mode === 'deg') {
       return Math.sin(convertToRad(num));
    } else if(mode === 'rad') {
      return Math.sin(num);
    }
  }

  function cos(num) {
    if(mode === 'deg') {
       return Math.cos(convertToRad(num));
    } else if(mode === 'rad') {
      return Math.cos(num);
    }
  }

  function tan(num) {
    if(mode === 'deg') {
       return Math.tan(convertToRad(num));
    } else if(mode === 'rad') {
      return Math.tan(num);
    }
  }

  function asin(num) {
    if(mode === 'deg') {
       return convertToDeg(Math.asin(num));
    } else if(mode === 'rad') {
      return Math.asin(num);
    }
  }

  function acos(num) {
    if(mode === 'deg') {
       return convertToDeg(Math.acos(num));
    } else if(mode === 'rad') {
      return Math.acos(num);
    }
  }

  function atan(num) {
    if(mode === 'deg') {
       return convertToDeg(Math.atan(num));
    } else if(mode === 'rad') {
      return Math.atan(num);
    }
  }


  //
  // misc math buttons
  //

  function piKey() {
    addLineToStack(Math.PI);
    refreshScreen();
  }


  //
  // Non-math related buttons
  //

  function delKey() {
    if(inputLine) {
      delInputChar();
    } else {
      clearLines(1);
    }
    refreshScreen();
  }

  function cursorLeft() {
    if(cursorPosition > 0 && inputLine === true) {
      cursorPosition--;
      refreshScreen();
    }
  }

  function cursorRight() {
    if(cursorPosition < screenStack.lineContents[0].length &&
       inputLine === true) {
      cursorPosition++;
      refreshScreen();
    }
  }

  function setAltBtnState(type) {
    var btnText = {
      alt1: "<i class='fa fa-reply'></i>",
      alt2:  "<i class='fa fa-share'></i>"
    };

    altBtnState = type;
    if(type !== '') {
      $headerRow2Right.innerHTML = btnText[type];
    } else {
      $headerRow2Right.innerHTML ='';
    }
  }

  function altBtn(name) {
    if(altBtnState === name) {
      setAltBtnState('');
    } else {
      setAltBtnState(name);
    }
  }

  function nextMenu() {
    menu.nextMenu();
  }

  function swapLines() {
    var a, b;

    if(inputLine) {
      a = getLineContents(1);
      b = getLineContents(0);
      screenStack.lineContents[1] = b.join("");
      screenStack.lineContents[0] = a.toString().split("");
      cursorPosition = screenStack.lineContents[0].length;
    } else {
      a = getLineContents(2);
      b = getLineContents(1);
      screenStack.lineContents[1] = b;
      screenStack.lineContents[0] = a;

    }
    refreshScreen();
  }

  /**
    *
    *Event bindings
    *
  */

  // calls the callback function with the given arguments which may be
  // a single argument or an array of arguments.
  function callWithArgs(callback, args) {
    if(typeof callback === 'function') {
      if(Array.isArray(args)) {
        callback.apply(this, args);
      } else {
        callback(args);
      }
    }
  }

  function keyButtonsClick() {
    var key = this.id,
        func,
        arg;

    //  clear any operation syntax error on screeen.
    clearSyntaxErr();

    switch(altBtnState) {
      case 'alt1':
        func = keyMap[key].alt1.func;
        arg = keyMap[key].alt1.arg;
        setAltBtnState('');
        break;

      case 'alt2':
        func = keyMap[key].alt2.func;
        arg = keyMap[key].alt2.arg;
        setAltBtnState('');
        break;

      default:
        func = keyMap[key].main.func;
        arg = keyMap[key].main.arg;
        break;
    }

    // run calc key function
    callWithArgs(func, arg);

  }

  forEachNode($keyButtons, function(node, ind){
    node.addEventListener('click', keyButtonsClick)
  })

  // physical keyboard button bindings
  document.querySelector('body').addEventListener('keydown', function(e){
    var keyPressed,
        calcKey,
        func,
        arg;

    // get key pressed.  Attempt cross browser compatability.
    keyPressed = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;

    // check that key is used
    if(keyboardKeyMap[keyPressed]) {
      e.preventDefault();

      //  clear any operation syntax error on screeen.
      clearSyntaxErr();

      calcKey = keyboardKeyMap[keyPressed];  // get corresponding calc key
      func = keyMap[calcKey].main.func;  // get calc key function
      arg = keyMap[calcKey].main.arg;  // get calc key value

      // run calc key function
      callWithArgs(func, arg);

    }

  });


  // show modal and overaly on logo click
  $logo.addEventListener('click', function() {
    $overlay.classList.add('overlay-show');
    $modal.classList.add('modal-show');
  });

  // hide modal and overylay on model close x click.
  $modalClose.addEventListener('click', function() {
    $overlay.classList.remove('overlay-show');
    $modal.classList.remove('modal-show');
  });

  // highlight the logo to call attention to modal.
  function logoFlash(delay) {
    setTimeout(function() {
      $logo.classList.add('flash');
    }, delay);
  }

  /**
    *
    *Lets' Go!: Initialize the calculator
    *
  */
  (function initialize() {
    menu.init();  // initialize the menu first so that methods are available.
    setKeyMap();
    setKeys();
    refreshScreen();
    logoFlash(1000);
  })();


})(document, window);
<body>
  <div id="overlay">
    <div id="modal">
      <div class="modal-tab">
        Info <i id='modal-close' class="fa fa-close"></i>
      </div>
      <div class="modal-content">
        <p>This calculator was inspired by my handy <a href="https://en.wikipedia.org/wiki/HP_48_series" target="_blank">HP 48G</a> calculator. My high school Calculus teacher required every student to use this calculator (and even sold them to us). I quickly fell in love with it and relished the reverse polish notation (RPN).  It took many years to unlearn RPN so that I could use a regular, non RPN, calculator again without operation errors.</p>

        <a title="By No machine-readable author provided. Heretiq assumed (based on copyright claims). [CC BY-SA 2.5 (http://creativecommons.org/licenses/by-sa/2.5)], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File%3AHP48G.jpg" target="_blank">
          <img class="image" width="256" alt="HP48G" src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/HP48G.jpg/256px-HP48G.jpg"/>
        </a>
      </div>
    </div>
  </div>
  <div class="container">
    <div id="calculator">
      <div id="screen-container">
        <div id="top-header">
          <span class="left">FCC <span class="large middle">48</span></span>
          <span class="right">
            <span id="logo" class="fa-stack small-fa">
              <i class="fa fa-clone fa-rotate-90 fa-stack-2x"></i>
              <i class="fa fa-fire fa-stack-1x blue nudge-fa"></i>
            </span>
          </span>
        </div>
        <div id="screen">
          <div class="screen-header-container">
            <div class="screen-header">
              <div id="header-row1" class="screen-header-row">
                <div class="screen-header-content"></div>
                <div class="screen-header-right right"></div>
              </div>
              <div id="header-row2" class="screen-header-row">
                <div class="screen-header-content">Home</div>
                <div class="screen-header-right right"></div>
              </div>
            </div>
            <hr>
          </div>
          <div class="screen-main-display-container">
            <div class="screen-main-display">
              <div id="line4" class="line">
                <span class="line-number left"></span>
                <span class="content"></span>
              </div>
              <div id="line3" class="line">
                <span class="line-number left"></span>
                <span class="content"></span>
              </div>
              <div id="line2" class="line">
                <span class="line-number left"></span>
                <span class="content"></span>
              </div>
              <div id="line1" class="line">
                <span class="line-number left"></span>
                <span class="content"></span>
              </div>
              <div id="line0" class="line">
                <span class="line-number left"></span>
                <span class="content"></span>
              </div>
            </div>
          </div>
          <div class="screen-menus">
            <div id="menu1" class="menu"></div>
            <div id="menu2" class="menu"></div>
            <div id="menu3" class="menu"></div>
            <div id="menu4" class="menu"></div>
            <div id="menu5" class="menu"></div>
            <div id="menu6" class="menu"></div>
          </div>
        </div>

      </div>

      <div id="keys">
        <div id="key-option-row" class="key-row group">
          <div class="key-option-container">
            <div id="k0" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
          <div class="key-option-container">
            <div id="k1" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
          <div class="key-option-container">
            <div id="k2" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
          <div class="key-option-container">
            <div id="k3" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
          <div class="key-option-container">
            <div id="k4" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
          <div class="key-option-container">
            <div id="k5" class="key-button key-option-button">
              <div class="key-text"></div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k6" class="key-button key-small-button">
              <div class="key-text">6</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k7" class="key-button key-small-button">
              <div class="key-text">7</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k8" class="key-button key-small-button">
              <div class="key-text">8</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k9" class="key-button key-small-button">
              <div class="key-text">9</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k10" class="key-button key-small-button">
              <div class="key-text">10</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k11" class="key-button key-small-button">
              <div class="key-text">11</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k12" class="key-button key-small-button">
              <div class="key-text">12</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k13" class="key-button key-small-button">
              <div class="key-text">13</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k14" class="key-button key-small-button">
              <div class="key-text">14</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k15" class="key-button key-small-button">
              <div class="key-text">15</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k16" class="key-button key-small-button">
              <div class="key-text">16</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k17" class="key-button key-small-button">
              <div class="key-text">17</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-small-container key-enter-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k18" class="key-button key-small-button key-enter-button">
              <div class="key-text">18</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k19" class="key-button key-small-button">
              <div class="key-text">19</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k20" class="key-button key-small-button">
              <div class="key-text">20</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k21" class="key-button key-small-button">
              <div class="key-text">21</div>
            </div>
          </div>
          <div class="key-small-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k22" class="key-button key-small-button">
              <div class="key-text">22</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k23" class="key-button key-large-button">
              <div class="key-text">23</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k24" class="key-button key-large-button">
              <div class="key-text">24</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k25" class="key-button key-large-button">
              <div class="key-text">25</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k26" class="key-button key-large-button">
              <div class="key-text">26</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k27" class="key-button key-large-button">
              <div class="key-text">27</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k28" class="key-button key-large-button key-alt-1">
              <div class="key-text">28</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k29" class="key-button key-large-button">
              <div class="key-text">29</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k30" class="key-button key-large-button">
              <div class="key-text">30</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k31" class="key-button key-large-button">
              <div class="key-text">31</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k32" class="key-button key-large-button">
              <div class="key-text">32</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k33" class="key-button key-large-button  key-alt-2">
              <div class="key-text">33</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k34" class="key-button key-large-button">
              <div class="key-text">34</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k35" class="key-button key-large-button">
              <div class="key-text">35</div>
            </div>
          </div>
          <div class="key-large-container key-bg-light">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k36" class="key-button key-large-button">
              <div class="key-text">36</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k37" class="key-button key-large-button">
              <div class="key-text">37</div>
            </div>
          </div>
        </div>

        <div class="key-row group">
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k38" class="key-button key-large-button">
              <div class="key-text">38</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k39" class="key-button key-large-button">
              <div class="key-text">39</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k40" class="key-button key-large-button">
              <div class="key-text">40</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k41" class="key-button key-large-button">
              <div class="key-text">41</div>
            </div>
          </div>
          <div class="key-large-container">
            <div class="key-alt">
              <span class="key-alt-text-1"></span>
              <span class="key-alt-text-2"></span>
            </div>
            <div id="k42" class="key-button key-large-button">
              <div class="key-text">42</div>
            </div>
          </div>
        </div>

      </div>
    </div>
  </div>
  <div id="attribution-container">
    <div class="attribution">
      <a href="https://www.flickr.com/photos/aheram/5864814103/" target="_blank">Math Homework</a> by <a href="https://tr.gravatar.com/tebm" target="_blank">HARUN PEHLİVAN </a><br>
      is licensed under <a href="http://harunpehlivan-blog.tumblr.com/" target="_blank">CC BY 2.0</a>
    </div>
  </div>
</body>
FCC 48G Calculator
------------------
FreeCodeCamp Zipline: Build a JavaScript Calculator

A tribute to my favorite calculator, the HP 48G
A lot of the alt buttons are empty, as well as the on screen menus.  Maybe one day I'll return to build the calculator out more.... one day.

A [Pen](https://codepen.io/harunpehlivan/pen/KQOmLa) by [HARUN PEHLİVAN](https://codepen.io/harunpehlivan) on [CodePen](https://codepen.io).

[License](https://codepen.io/harunpehlivan/pen/KQOmLa/license).

以上是关于markdown FCC 48G计算器的主要内容,如果未能解决你的问题,请参考以下文章

markdown FCC:产品登陆页面

markdown FCC:调查表

markdown [FCC] Tribute Page MJ

FCC JS基础算法题:Factorialize a Number(计算一个整数的阶乘)

FCC例题

线上 48G Java 应用内存 OOM 真实案例分析(第 2 篇)