var Console = {
  init: function() {
    this.History = new ConsoleStorage();
  },
  eval: function(input) {
    console.log('eval', input);
    var result;
    try {
      result = eval(input);
    } catch (e) {
      console.error(e);
      result = e.message;
    };

    Console.History.add(new Console.Command(input, result));
  },
  controller: function() {
    Console.init();
    this.eval = Console.eval;
  },
  view: function(ctrl) {
    return [m.component(Console.HistoryWidget, Console.History.get),
            m.component(Console.Input, { eval: ctrl.eval })];
  }
};

Console.Command = function(command, outcome) {
  this.input = m.prop(command);
  this.result = m.prop(outcome);
};

Console.HistoryWidget = {
  controller: function(provider) {
    this.get = provider;
  },
  view: function(history) {
    return <div>
              {
                history.get().map(function(command, index) {
                  return [<div>{ command.input() }</div>,
                          <div>{ command.result() }</div>]
                })
              }
           </div>;
  }
};

Console.Input = {
  controller: function(args) {
    this.input = m.prop('');
    this.exec = function(e) {
      if (e.keyCode === 13 && !e.shiftKey) {
        args.eval(this.input());
        this.input('');
        e.preventDefault();
      }
    };
  },
  view: function(ctrl) {
    var parentStyle = {
      position   : 'relative',
      border     : '1px solid #888',
      background : '#fff'
    };

    var childStyle = {
      margin     : 0,
      outline    : 0,
      border     : 0,
      padding    : '5px',
      background : 'transparent',
      font       : '400 13/16px monospace',
      whiteSpace : 'pre-wrap',
      wordWrap   : 'break-word'
    };

    var preStyle = Object.assign({
      display    : 'block',
      visibility : 'hidden'
    }, childStyle);

    var textareaStyle = Object.assign({
      boxSizing : 'border-box',
      width     : '100%',
      height    : '100%',
      overflow  : 'hidden',
      position  : 'absolute',
      top       : '0',
      left      : '0',
      resize    : 'none'
    }, childStyle);

    return <div id="console-input" style={ parentStyle }>
              <pre style={ preStyle }>
                <span textContent={ ctrl.input() } ></span>
                <br />
              </pre>
              <textarea
                style={ textareaStyle }
                value={ ctrl.input() }
                oninput={ m.withAttr('value', ctrl.input) }
                onkeydown={ ctrl.exec.bind(ctrl) }>
              </textarea>
           </div>
  }
};

m.mount(document.getElementById('consoleApp'), Console);
@@ -106,40 +106,8 @@
 ) %7B%0A
-    console.log('eval', input);%0A
     
@@ -228,24 +228,88 @@
 ge;%0A    %7D;%0A%0A
+    console.log('input, /* output, */ result', input, result);%0A%0A
     Console.
@@ -847,27 +847,207 @@
 ) %7B%0A    
-return %3Cdiv
+var parentStyle = %7B%0A      boxSizing  : 'border-box',%0A      padding    : '5px',%0A      font       : '400 13px monospace',%0A      overflowY  : 'auto'%0A    %7D;%0A%0A    return %3Cdiv style=%7B parentStyle %7D
 %3E%0A      

Apply some minimal styling to the console history widget