<commit_before>/* global FastClick: false, DISQUS: false, DISQUSWIDGETS: true, disqus_identifier:false, ga:false, Drawer: false, ImageLoader: false, Prism: false */
(function ($, window, document, undefined) {

  'use strict';

  $(function () {
    var GHOSTIUM = window.GHOSTIUM;

    // Cache a couple of useful elements
    // =================
    var $window   = $(window),
        $document = $(document),
        $html     = $(document.documentElement),
        $body     = $(document.body),
        $head     = $('head'),
        $surface  = $body,
        $content  = $('.content', $surface);

    // FastClick bindings
    // =================
    FastClick.attach(document.body);

    // Drawer bindings
    // =================
    Drawer.init();

    // PrismJS handler
    // =================
    Prism.languages.html = Prism.languages.markup;

    var _prismHandler = function() {
      $('code').not('[class*="language-"]').addClass(function() {
        var _lang = $(this).attr('class')  || 'markup';

        _lang = _lang.replace(/(language|lang)+\-/gi, '');
        return 'language-' + (Prism.languages.hasOwnProperty(_lang) ? _lang : 'markup');
      });

      Prism.highlightAll();
    };

    _prismHandler();

    // DISQUS Handlers
    // =================
    var _disqusHandler = function() {
      if(!GHOSTIUM.haveDisqus) return;

      if(typeof DISQUS === 'object' && $('#disqus_thread').length) {
        DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = disqus_identifier;
          }
        });
      }
    };

    var _disqusCounterHandler = function() {
      if(!GHOSTIUM.haveDisqus) {
        $('[data-disqus-identifier]').parent('li').remove();
        return;
      }

      if(typeof DISQUSWIDGETS === 'object') {
        var $identifiers = $body.find('[data-disqus-identifier]'),
            $script      = $head.find('script[src*="disqus.com/count-data.js"]');

        var posts = $identifiers
          .map(function() {
            return '1=' + encodeURIComponent($(this).data('disqus-identifier'));
          })
          .sort()
          .get()
        ;

        $script.remove();

        if(posts.length) {
          $head.append($('<script/>', {
            async: true,
            src: $script.attr('src').split('?')[0] + '?' + posts.join('&')
          }));

          DISQUSWIDGETS.getCount();
        }
      }
    };

    _disqusCounterHandler();

    // GA Handler
    // =================
    var _gaHandler = function() {
      if(!GHOSTIUM.haveGA) return;

      if(typeof ga === 'function') {
        ga('set', 'location', window.location.href);
        ga('send', 'pageview');
      }
    };

    // PJax bindings
    // =================
    if ($.support.pjax && GHOSTIUM.enablePjax) {
      $document.on('pjax:start', function() {
        $surface.scrollTop(0);
      });

      $document.on('pjax:end', function() {
        _disqusHandler();
        _gaHandler();
        _disqusCounterHandler();
        _prismHandler();

        $('[data-load-image]', $content).each(function() {
          ImageLoader.load($(this));
        });
      });

      var _pjaxOptions = {
        container: '[data-pjax-container]',
        fragment: '[data-pjax-container]'
      };

      $document.pjax('a[data-pjax]', _pjaxOptions);

      $document.on('submit', 'form[data-pjax]', function(e) {
        $.pjax.submit(e, _pjaxOptions);
      });
    }

    // Data API bindings
    // =================
    $document.on('click', '[data-action]', function(e) {
      var _self = $(this),
         action = _self.data('action');

      var _openWindow = function(url, h, w) {
        var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left,
            dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top,
            left = ((screen.width / 2) - (w / 2)) + dualScreenLeft,
            top = ((screen.height / 2) - (h / 2)) + dualScreenTop;

        var newWindow = window.open(url, '',
          'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,copyhistory=no' +
          ', width=' + w +
          ', height=' + h +
          ', top=' + top +
          ', left=' + left);

        // Puts focus on the newWindow
        if (window.focus) {
            newWindow.focus();
        }
        return newWindow;
      };

      e.preventDefault();

      switch(action) {
        case 'open-drawer':
          Drawer.open();
          break;
        case 'close-drawer':
          Drawer.close();
          break;
        case 'share-gplus':
          _openWindow(
            'https://plus.google.com/share?url=' + encodeURIComponent(location.href),
            600, 600);
          break;
        case 'share-facebook':
          _openWindow(
            'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(location.href),
            436, 626);
          break;
        case 'share-twitter':
          _openWindow(
            'https://twitter.com/share?url=' + encodeURIComponent(location.href) + '&text=' + encodeURIComponent(document.title),
            440, 550);
          break;
      }

      return false;
    });

    // Async load images
    $('[data-load-image]', $body).each(function() {
      ImageLoader.load($(this));
    });

    // Hide drawer button on scroll for best readability
    // =================
    $surface.on('scroll', function() {
      var offset = $surface.scrollTop(),
          btn = $('#drawer-button');
      if(offset === 0) {
        btn.removeClass('drawer-button-hidden');
      } else if(!btn.hasClass('drawer-button-hidden')) {
        btn.addClass('drawer-button-hidden');
      }
    });

    // Smooth scrolling for same page anchors
    // =================
    $document.on('click', 'a[href^=#]:not([href=#])', function(e) {
      e.preventDefault();

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $surface.animate({
          scrollTop: target.offset().top
        }, 500);
        location.hash = this.hash;
        return false;
      }
    });

    // Fix oveflow-scrolling on iOS7
    // =================
    $surface.on('touchstart', function(e) {});

    // Fix keyboard scrolling not working when page load
    // =================
    if($body.hasClass('home-template')) {
      $('.wrapper').eq(0).focus();
    }

    // Fix DISQUS iframe does not resize on mobile orientation change
    // =================
    $window.on('orientationchange', function(e) {
      _disqusHandler();
    });

  });

})(jQuery, window, document);
<commit_msg>Fix error in javascript when navigating to home from a static page<commit_after>/* global FastClick: false, DISQUS: false, DISQUSWIDGETS: true, disqus_identifier:false, ga:false, Drawer: false, ImageLoader: false, Prism: false */
(function ($, window, document, undefined) {

  'use strict';

  $(function () {
    var GHOSTIUM = window.GHOSTIUM;

    // Cache a couple of useful elements
    // =================
    var $window   = $(window),
        $document = $(document),
        $html     = $(document.documentElement),
        $body     = $(document.body),
        $head     = $('head'),
        $surface  = $body,
        $content  = $('.content', $surface);

    // FastClick bindings
    // =================
    FastClick.attach(document.body);

    // Drawer bindings
    // =================
    Drawer.init();

    // PrismJS handler
    // =================
    Prism.languages.html = Prism.languages.markup;

    var _prismHandler = function() {
      $('code').not('[class*="language-"]').addClass(function() {
        var _lang = $(this).attr('class')  || 'markup';

        _lang = _lang.replace(/(language|lang)+\-/gi, '');
        return 'language-' + (Prism.languages.hasOwnProperty(_lang) ? _lang : 'markup');
      });

      Prism.highlightAll();
    };

    _prismHandler();

    // DISQUS Handlers
    // =================
    var _disqusHandler = function() {
      if(!GHOSTIUM.haveDisqus) return;

      if(typeof DISQUS === 'object' && $('#disqus_thread').length) {
        DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = disqus_identifier;
          }
        });
      }
    };

    var _disqusCounterHandler = function() {
      if(!GHOSTIUM.haveDisqus) {
        $('[data-disqus-identifier]').parent('li').remove();
        return;
      }

      if(typeof DISQUSWIDGETS === 'object') {
        var $identifiers = $body.find('[data-disqus-identifier]'),
            $script      = $head.find('script[src*="disqus.com/count-data.js"]');

        var posts = $identifiers
          .map(function() {
            return '1=' + encodeURIComponent($(this).data('disqus-identifier'));
          })
          .sort()
          .get()
        ;

        $script.remove();

        if(posts.length) {
          $head.append($('<script/>', {
            async: true,
            src: '//' + disqus_shortname + '.disqus.com/count.js?' + posts.join('&')
          }));

          DISQUSWIDGETS.getCount();
        }
      }
    };

    _disqusCounterHandler();

    // GA Handler
    // =================
    var _gaHandler = function() {
      if(!GHOSTIUM.haveGA) return;

      if(typeof ga === 'function') {
        ga('set', 'location', window.location.href);
        ga('send', 'pageview');
      }
    };

    // PJax bindings
    // =================
    if ($.support.pjax && GHOSTIUM.enablePjax) {
      $document.on('pjax:start', function() {
        $surface.scrollTop(0);
      });

      $document.on('pjax:end', function() {
        _disqusHandler();
        _gaHandler();
        _disqusCounterHandler();
        _prismHandler();

        $('[data-load-image]', $content).each(function() {
          ImageLoader.load($(this));
        });
      });

      var _pjaxOptions = {
        container: '[data-pjax-container]',
        fragment: '[data-pjax-container]'
      };

      $document.pjax('a[data-pjax]', _pjaxOptions);

      $document.on('submit', 'form[data-pjax]', function(e) {
        $.pjax.submit(e, _pjaxOptions);
      });
    }

    // Data API bindings
    // =================
    $document.on('click', '[data-action]', function(e) {
      var _self = $(this),
         action = _self.data('action');

      var _openWindow = function(url, h, w) {
        var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left,
            dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top,
            left = ((screen.width / 2) - (w / 2)) + dualScreenLeft,
            top = ((screen.height / 2) - (h / 2)) + dualScreenTop;

        var newWindow = window.open(url, '',
          'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,copyhistory=no' +
          ', width=' + w +
          ', height=' + h +
          ', top=' + top +
          ', left=' + left);

        // Puts focus on the newWindow
        if (window.focus) {
            newWindow.focus();
        }
        return newWindow;
      };

      e.preventDefault();

      switch(action) {
        case 'open-drawer':
          Drawer.open();
          break;
        case 'close-drawer':
          Drawer.close();
          break;
        case 'share-gplus':
          _openWindow(
            'https://plus.google.com/share?url=' + encodeURIComponent(location.href),
            600, 600);
          break;
        case 'share-facebook':
          _openWindow(
            'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(location.href),
            436, 626);
          break;
        case 'share-twitter':
          _openWindow(
            'https://twitter.com/share?url=' + encodeURIComponent(location.href) + '&text=' + encodeURIComponent(document.title),
            440, 550);
          break;
      }

      return false;
    });

    // Async load images
    $('[data-load-image]', $body).each(function() {
      ImageLoader.load($(this));
    });

    // Hide drawer button on scroll for best readability
    // =================
    $surface.on('scroll', function() {
      var offset = $surface.scrollTop(),
          btn = $('#drawer-button');
      if(offset === 0) {
        btn.removeClass('drawer-button-hidden');
      } else if(!btn.hasClass('drawer-button-hidden')) {
        btn.addClass('drawer-button-hidden');
      }
    });

    // Smooth scrolling for same page anchors
    // =================
    $document.on('click', 'a[href^=#]:not([href=#])', function(e) {
      e.preventDefault();

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $surface.animate({
          scrollTop: target.offset().top
        }, 500);
        location.hash = this.hash;
        return false;
      }
    });

    // Fix oveflow-scrolling on iOS7
    // =================
    $surface.on('touchstart', function(e) {});

    // Fix keyboard scrolling not working when page load
    // =================
    if($body.hasClass('home-template')) {
      $('.wrapper').eq(0).focus();
    }

    // Fix DISQUS iframe does not resize on mobile orientation change
    // =================
    $window.on('orientationchange', function(e) {
      _disqusHandler();
    });

  });

})(jQuery, window, document);
<|endoftext|>


<commit_before>const Variable = require("./variable");

function coerceTypes(var1, var2, val1, val2) {
  if (var2.type === "INT") {
    if (var1.type === "FLOAT" || var1.type === "DOUBLE") {
      return Math.floor(val1);
    }
  }

  return val1;
}

// Note: We implement `interpret` as a generator in order to support pausing
// execution in the debugger. This allows the caller granular control over the
// execution timing of the virtual machine while also allowing the VM to divulge
// some of its internal state before each command is exectued.
//
// In "production" we syncrnously call `.next()` on the generator until it's
// empty, ignoring all yeilded values. In the debugger we use the yielded data
// to populate the UI, and -- when stepping -- pause execution by waiting
// between calls to `.next()`.
function* interpret(start, program, stack = []) {
  const { commands, methods, variables, classes } = program;

  function twoArgCoercingOperator(operator) {
    const a = stack.pop();
    const b = stack.pop();
    let aValue = a instanceof Variable ? a.getValue() : a;
    const bValue = b instanceof Variable ? b.getValue() : b;

    aValue = coerceTypes(a, b, aValue, bValue);
    stack.push(operator(bValue, aValue));
  }

  function twoArgOperator(operator) {
    const a = stack.pop();
    const b = stack.pop();
    const aValue = a instanceof Variable ? a.getValue() : a;
    const bValue = b instanceof Variable ? b.getValue() : b;

    stack.push(operator(bValue, aValue));
  }

  // Instruction Pointer
  let ip = start;
  while (ip < commands.length) {
    const command = commands[ip];
    // This probably incurrs some perf cost. If it does, we can pass in a flag
    // to enable it only when we are debugging. When we are not, (in prod) we
    // can just jump right over it and we will execute straight through to the
    // return value on the first call to `.next()`.
    yield { i: ip, command, stack, variables, commands };

    switch (command.opcode) {
      // push
      case 1: {
        const offsetIntoVariables = command.arg;
        stack.push(variables[offsetIntoVariables]);
        break;
      }
      // pop
      case 2: {
        stack.pop();
        break;
      }
      // popTo
      case 3: {
        const a = stack.pop();
        let aValue = a instanceof Variable ? a.getValue() : a;
        const offsetIntoVariables = command.arg;
        const toVar = variables[offsetIntoVariables];
        toVar.setValue(aValue);
        break;
      }
      // ==
      case 8: {
        twoArgCoercingOperator((b, a) => b === a);
        break;
      }
      // !=
      case 9: {
        twoArgCoercingOperator((b, a) => b !== a);
        break;
      }
      // >
      case 10: {
        twoArgCoercingOperator((b, a) => b > a);
        break;
      }
      // >=
      case 11: {
        twoArgCoercingOperator((b, a) => b >= a);
        break;
      }
      // <
      case 12: {
        twoArgCoercingOperator((b, a) => b < a);
        break;
      }
      // <=
      case 13: {
        twoArgCoercingOperator((b, a) => b <= a);
        break;
      }
      // jumpIf
      case 16: {
        const value = stack.pop();
        // This seems backwards. Seems like we're doing a "jump if not"
        if (value) {
          break;
        }
        ip = command.arg - 1;
        break;
      }
      // jumpIfNot
      case 17: {
        const value = stack.pop();
        // This seems backwards. Same as above
        if (!value) {
          break;
        }
        ip = command.arg - 1;
        break;
      }
      // jump
      case 18: {
        ip = command.arg - 1;
        break;
      }
      // call
      // strangeCall (seems to behave just like regular call)
      case 24:
      case 112: {
        const methodOffset = command.arg;
        let { name: methodName, typeOffset: classesOffset } = methods[
          methodOffset
        ];
        methodName = methodName.toLowerCase();

        const klass = classes[classesOffset];
        if (!klass) {
          throw new Error("Need to add a missing class to runtime");
        }
        // This is a bit awkward. Because the variables are stored on the stack
        // before the object, we have to find the number of arguments without
        // actually having access to the object instance.
        let argCount = klass.prototype[methodName].length;

        const methodArgs = [];
        while (argCount--) {
          const a = stack.pop();
          const aValue = a instanceof Variable ? a.getValue() : a;
          methodArgs.push(aValue);
        }
        const variable = stack.pop();
        const obj = variable instanceof Variable ? variable.getValue() : variable;
        stack.push(obj[methodName](...methodArgs));
        break;
      }
      // callGlobal
      case 25: {
        const offset = command.arg;
        // Note: We proxy all yielded values from the child `interpret` out to
        // the caller, while capturing the return value, (`value`) for use within the
        // VM.
        const value = yield* interpret(offset, program, stack);
        stack.push(value);
        break;
      }
      // return
      case 33: {
        const a = stack.pop();
        const aValue = a instanceof Variable ? a.getValue() : a;
        return aValue;
      }
      // mov
      case 48: {
        const a = stack.pop();
        const b = stack.pop();
        let aValue = a instanceof Variable ? a.getValue() : a;
        if (b.type === "INT") {
          aValue = Math.floor(aValue);
        }
        b.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // postinc
      case 56: {
        const a = stack.pop();
        const aValue = a.getValue();
        a.setValue(aValue + 1);
        stack.push(aValue);
        break;
      }
      // postdec
      case 57: {
        const a = stack.pop();
        const aValue = a.getValue();
        a.setValue(aValue - 1);
        stack.push(aValue);
        break;
      }
      // preinc
      case 58: {
        const a = stack.pop();
        const aValue = a.getValue() + 1;
        a.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // predec
      case 59: {
        const a = stack.pop();
        const aValue = a.getValue() - 1;
        a.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // + (add)
      case 64: {
        twoArgOperator((b, a) => b + a);
        break;
      }
      // - (subtract)
      case 65: {
        twoArgOperator((b, a) => b - a);
        break;
      }
      // * (multiply)
      case 66: {
        twoArgOperator((b, a) => b * a);
        break;
      }
      // / (divide)
      case 67: {
        twoArgOperator((b, a) => b / a);
        break;
      }
      // % (mod)
      case 68: {
        const a = stack.pop();
        const b = stack.pop();
        const aValue = a instanceof Variable ? a.getValue() : a;
        let bValue = b instanceof Variable ? b.getValue() : b;
        // Need to coerce LHS if not int, RHS is always int (enforced by compiler)
        if (b.type === "FLOAT" || b.type === "DOUBLE") {
          bValue = Math.floor(bValue);
        }
        stack.push(bValue % aValue);
        break;
      }
      // & (binary and)
      case 72: {
        twoArgOperator((b, a) => b & a);
        break;
      }
      // | (binary or)
      case 73: {
        twoArgOperator((b, a) => b | a);
        break;
      }
      // ! (not)
      case 74: {
        const a = stack.pop();
        const aValue = a instanceof Variable ? a.getValue() : a;
        stack.push(aValue ? 0 : 1);
        break;
      }
      // - (negative)
      case 76: {
        const a = stack.pop();
        const aValue = a instanceof Variable ? a.getValue() : a;
        stack.push(-aValue);
        break;
      }
      // logAnd (&&)
      case 80: {
        twoArgOperator((b, a) => b && a);
        break;
      }
      // logOr ||
      case 81: {
        twoArgOperator((b, a) => b || a);
        break;
      }
      // <<
      case 88: {
        twoArgOperator((b, a) => b << a);
        break;
      }
      // >>
      case 89: {
        twoArgOperator((b, a) => b >> a);
        break;
      }
      // new
      case 96: {
        const classesOffset = command.arg;
        const Klass = classes[classesOffset];
        const klassInst = new Klass();
        stack.push(klassInst);
        break;
      }
      default:
        throw new Error(`Unhandled opcode ${command.opcode}`);
    }

    ip++;
  }
}

module.exports = interpret;
<commit_msg>fix variable unboxing issue, move all unboxing to single method (#827)<commit_after>const Variable = require("./variable");

function coerceTypes(var1, var2, val1, val2) {
  if (var2.type === "INT") {
    if (var1.type === "FLOAT" || var1.type === "DOUBLE") {
      return Math.floor(val1);
    }
  }

  return val1;
}

// Note: We implement `interpret` as a generator in order to support pausing
// execution in the debugger. This allows the caller granular control over the
// execution timing of the virtual machine while also allowing the VM to divulge
// some of its internal state before each command is exectued.
//
// In "production" we syncrnously call `.next()` on the generator until it's
// empty, ignoring all yeilded values. In the debugger we use the yielded data
// to populate the UI, and -- when stepping -- pause execution by waiting
// between calls to `.next()`.
function* interpret(start, program, stack = []) {
  const { commands, methods, variables, classes } = program;

  function popStackValue() {
    const v = stack.pop();
    return v instanceof Variable ? v.getValue() : v;
  }

  function twoArgCoercingOperator(operator) {
    const a = stack.pop();
    const b = stack.pop();
    let aValue = a instanceof Variable ? a.getValue() : a;
    const bValue = b instanceof Variable ? b.getValue() : b;

    aValue = coerceTypes(a, b, aValue, bValue);
    stack.push(operator(bValue, aValue));
  }

  function twoArgOperator(operator) {
    const aValue = popStackValue();
    const bValue = popStackValue();

    stack.push(operator(bValue, aValue));
  }

  // Instruction Pointer
  let ip = start;
  while (ip < commands.length) {
    const command = commands[ip];
    // This probably incurrs some perf cost. If it does, we can pass in a flag
    // to enable it only when we are debugging. When we are not, (in prod) we
    // can just jump right over it and we will execute straight through to the
    // return value on the first call to `.next()`.
    yield { i: ip, command, stack, variables, commands };

    switch (command.opcode) {
      // push
      case 1: {
        const offsetIntoVariables = command.arg;
        stack.push(variables[offsetIntoVariables]);
        break;
      }
      // pop
      case 2: {
        stack.pop();
        break;
      }
      // popTo
      case 3: {
        const aValue = popStackValue();
        const offsetIntoVariables = command.arg;
        const toVar = variables[offsetIntoVariables];
        toVar.setValue(aValue);
        break;
      }
      // ==
      case 8: {
        twoArgCoercingOperator((b, a) => b === a);
        break;
      }
      // !=
      case 9: {
        twoArgCoercingOperator((b, a) => b !== a);
        break;
      }
      // >
      case 10: {
        twoArgCoercingOperator((b, a) => b > a);
        break;
      }
      // >=
      case 11: {
        twoArgCoercingOperator((b, a) => b >= a);
        break;
      }
      // <
      case 12: {
        twoArgCoercingOperator((b, a) => b < a);
        break;
      }
      // <=
      case 13: {
        twoArgCoercingOperator((b, a) => b <= a);
        break;
      }
      // jumpIf
      case 16: {
        const value = popStackValue();
        // This seems backwards. Seems like we're doing a "jump if not"
        if (value) {
          break;
        }
        ip = command.arg - 1;
        break;
      }
      // jumpIfNot
      case 17: {
        const value = popStackValue();
        // This seems backwards. Same as above
        if (!value) {
          break;
        }
        ip = command.arg - 1;
        break;
      }
      // jump
      case 18: {
        ip = command.arg - 1;
        break;
      }
      // call
      // strangeCall (seems to behave just like regular call)
      case 24:
      case 112: {
        const methodOffset = command.arg;
        let { name: methodName, typeOffset: classesOffset } = methods[
          methodOffset
        ];
        methodName = methodName.toLowerCase();

        const klass = classes[classesOffset];
        if (!klass) {
          throw new Error("Need to add a missing class to runtime");
        }
        // This is a bit awkward. Because the variables are stored on the stack
        // before the object, we have to find the number of arguments without
        // actually having access to the object instance.
        let argCount = klass.prototype[methodName].length;

        const methodArgs = [];
        while (argCount--) {
          const aValue = popStackValue();
          methodArgs.push(aValue);
        }
        const obj = popStackValue();
        stack.push(obj[methodName](...methodArgs));
        break;
      }
      // callGlobal
      case 25: {
        const offset = command.arg;
        // Note: We proxy all yielded values from the child `interpret` out to
        // the caller, while capturing the return value, (`value`) for use within the
        // VM.
        const value = yield* interpret(offset, program, stack);
        stack.push(value);
        break;
      }
      // return
      case 33: {
        const aValue = popStackValue();
        return aValue;
      }
      // mov
      case 48: {
        const a = stack.pop();
        const b = stack.pop();
        let aValue = a instanceof Variable ? a.getValue() : a;
        if (b.type === "INT") {
          aValue = Math.floor(aValue);
        }
        b.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // postinc
      case 56: {
        const a = stack.pop();
        const aValue = a.getValue();
        a.setValue(aValue + 1);
        stack.push(aValue);
        break;
      }
      // postdec
      case 57: {
        const a = stack.pop();
        const aValue = a.getValue();
        a.setValue(aValue - 1);
        stack.push(aValue);
        break;
      }
      // preinc
      case 58: {
        const a = stack.pop();
        const aValue = a.getValue() + 1;
        a.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // predec
      case 59: {
        const a = stack.pop();
        const aValue = a.getValue() - 1;
        a.setValue(aValue);
        stack.push(aValue);
        break;
      }
      // + (add)
      case 64: {
        twoArgOperator((b, a) => b + a);
        break;
      }
      // - (subtract)
      case 65: {
        twoArgOperator((b, a) => b - a);
        break;
      }
      // * (multiply)
      case 66: {
        twoArgOperator((b, a) => b * a);
        break;
      }
      // / (divide)
      case 67: {
        twoArgOperator((b, a) => b / a);
        break;
      }
      // % (mod)
      case 68: {
        const a = stack.pop();
        const b = stack.pop();
        const aValue = a instanceof Variable ? a.getValue() : a;
        let bValue = b instanceof Variable ? b.getValue() : b;
        // Need to coerce LHS if not int, RHS is always int (enforced by compiler)
        if (b.type === "FLOAT" || b.type === "DOUBLE") {
          bValue = Math.floor(bValue);
        }
        stack.push(bValue % aValue);
        break;
      }
      // & (binary and)
      case 72: {
        twoArgOperator((b, a) => b & a);
        break;
      }
      // | (binary or)
      case 73: {
        twoArgOperator((b, a) => b | a);
        break;
      }
      // ! (not)
      case 74: {
        const aValue = popStackValue();
        stack.push(aValue ? 0 : 1);
        break;
      }
      // - (negative)
      case 76: {
        const aValue = popStackValue();
        stack.push(-aValue);
        break;
      }
      // logAnd (&&)
      case 80: {
        twoArgOperator((b, a) => b && a);
        break;
      }
      // logOr ||
      case 81: {
        twoArgOperator((b, a) => b || a);
        break;
      }
      // <<
      case 88: {
        twoArgOperator((b, a) => b << a);
        break;
      }
      // >>
      case 89: {
        twoArgOperator((b, a) => b >> a);
        break;
      }
      // new
      case 96: {
        const classesOffset = command.arg;
        const Klass = classes[classesOffset];
        const klassInst = new Klass();
        stack.push(klassInst);
        break;
      }
      default:
        throw new Error(`Unhandled opcode ${command.opcode}`);
    }

    ip++;
  }
}

module.exports = interpret;
<|endoftext|>


<commit_before>/*
 * Reconnecting Websocket
 * https://github.com/joewalnes/reconnecting-websocket

// MIT License:
//
// Copyright (c) 2010-2012, Joe Walnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/**
 * This behaves like a WebSocket in every way, except if it fails to connect,
 * or it gets disconnected, it will repeatedly poll until it succesfully connects
 * again.
 *
 * It is API compatible, so when you have:
 *   ws = new WebSocket('ws://....');
 * you can replace with:
 *   ws = new ReconnectingWebSocket('ws://....');
 *
 * The event stream will typically look like:
 *  onconnecting
 *  onopen
 *  onmessage
 *  onmessage
 *  onclose // lost connection
 *  onconnecting
 *  onopen  // sometime later...
 *  onmessage
 *  onmessage
 *  etc...
 *
 * It is API compatible with the standard WebSocket API.
 *
 * Latest version: https://github.com/joewalnes/reconnecting-websocket/
 * - Joe Walnes
 */
function ReconnectingWebSocket(url, protocols) {
    protocols = protocols || [];

    // These can be altered by calling code.
    this.debug = false;
    this.reconnectInterval = 1000;
    this.timeoutInterval = 2000;

    var self = this;
    var ws;
    var forcedClose = false;
    var timedOut = false;

    this.url = url;
    this.protocols = protocols;
    this.readyState = WebSocket.CONNECTING;
    this.URL = url; // Public API

    this.onopen = function(event) {
    };

    this.onclose = function(event) {
    };

    this.onconnecting = function(event) {
    };

    this.onmessage = function(event) {
    };

    this.onerror = function(event) {
    };

    function connect(reconnectAttempt) {
        ws = new WebSocket(url, protocols);

        self.onconnecting();
        if (self.debug || ReconnectingWebSocket.debugAll) {
            console.debug('ReconnectingWebSocket', 'attempt-connect', url);
        }

        var localWs = ws;
        var timeout = setTimeout(function() {
                                 if (self.debug || ReconnectingWebSocket.debugAll) {
                                 console.debug('ReconnectingWebSocket', 'connection-timeout', url);
                                 }
                                 timedOut = true;
                                 localWs.close();
                                 timedOut = false;
                                 }, self.timeoutInterval);

        ws.onopen = function(event) {
            clearTimeout(timeout);
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onopen', url);
            }
            self.readyState = WebSocket.OPEN;
            reconnectAttempt = false;
            self.onopen(event);
        };

        ws.onclose = function(event) {
            clearTimeout(timeout);
            ws = null;
            if (forcedClose) {
                self.readyState = WebSocket.CLOSED;
                self.onclose(event);
            } else {
                self.readyState = WebSocket.CONNECTING;
                self.onconnecting();
                if (!reconnectAttempt && !timedOut) {
                    if (self.debug || ReconnectingWebSocket.debugAll) {
                        console.debug('ReconnectingWebSocket', 'onclose', url);
                    }
                    self.onclose(event);
                }
                setTimeout(function() {
                           connect(true);
                           }, self.reconnectInterval);
            }
        };
        ws.onmessage = function(event) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onmessage', url, event.data);
            }
            self.onmessage(event);
        };
        ws.onerror = function(event) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onerror', url, event);
            }
            self.onerror(event);
        };
    }
    connect(url);

    this.send = function(data) {
        if (ws) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'send', url, data);
            }
            return ws.send(data);
        } else {
            throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';
        }
    };

    this.close = function() {
        forcedClose = true;
        if (ws) {
            ws.close();
        }
    };

    /**
     * Additional public API method to refresh the connection if still open (close, re-open).
     * For example, if the app suspects bad data / missed heart beats, it can try to refresh.
     */
    this.refresh = function() {
        if (ws) {
            ws.close();
        }
    };
}

/**
 * Setting this to true is the equivalent of setting all instances of ReconnectingWebSocket.debug to true.
 */
ReconnectingWebSocket.debugAll = false;

/*********************************************************************************************************/

/*
 * Reforce Websocket Communication
 *
 */

if("WebSocket" in window) {

    var ws = new ReconnectingWebSocket("%%WEBSOCKET_URL%%");

    ws.onopen = function() {
        // Web Socket is connected
        // alert("websocket is open");

        // You can send data now
        // ws.send("Hey man, you got the time?");

        console.log('onOpen!');
    };

    ws.onmessage = function(evt) {
        // alert("received: " + evt.data);
        console.log('onMessage!');
        evt.data == 'r' ? Reveal.right() : Reveal.left();
    };

    ws.onclose = function() {
        console.log('onClose!');
    };

} else alert("Browser doesn't support WebSocket!");
<commit_msg>Add support for impress.js presentations<commit_after>/*
 * Reconnecting Websocket
 * https://github.com/joewalnes/reconnecting-websocket

// MIT License:
//
// Copyright (c) 2010-2012, Joe Walnes
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/**
 * This behaves like a WebSocket in every way, except if it fails to connect,
 * or it gets disconnected, it will repeatedly poll until it succesfully connects
 * again.
 *
 * It is API compatible, so when you have:
 *   ws = new WebSocket('ws://....');
 * you can replace with:
 *   ws = new ReconnectingWebSocket('ws://....');
 *
 * The event stream will typically look like:
 *  onconnecting
 *  onopen
 *  onmessage
 *  onmessage
 *  onclose // lost connection
 *  onconnecting
 *  onopen  // sometime later...
 *  onmessage
 *  onmessage
 *  etc...
 *
 * It is API compatible with the standard WebSocket API.
 *
 * Latest version: https://github.com/joewalnes/reconnecting-websocket/
 * - Joe Walnes
 */
function ReconnectingWebSocket(url, protocols) {
    protocols = protocols || [];

    // These can be altered by calling code.
    this.debug = false;
    this.reconnectInterval = 1000;
    this.timeoutInterval = 2000;

    var self = this;
    var ws;
    var forcedClose = false;
    var timedOut = false;

    this.url = url;
    this.protocols = protocols;
    this.readyState = WebSocket.CONNECTING;
    this.URL = url; // Public API

    this.onopen = function(event) {
    };

    this.onclose = function(event) {
    };

    this.onconnecting = function(event) {
    };

    this.onmessage = function(event) {
    };

    this.onerror = function(event) {
    };

    function connect(reconnectAttempt) {
        ws = new WebSocket(url, protocols);

        self.onconnecting();
        if (self.debug || ReconnectingWebSocket.debugAll) {
            console.debug('ReconnectingWebSocket', 'attempt-connect', url);
        }

        var localWs = ws;
        var timeout = setTimeout(function() {
                                 if (self.debug || ReconnectingWebSocket.debugAll) {
                                 console.debug('ReconnectingWebSocket', 'connection-timeout', url);
                                 }
                                 timedOut = true;
                                 localWs.close();
                                 timedOut = false;
                                 }, self.timeoutInterval);

        ws.onopen = function(event) {
            clearTimeout(timeout);
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onopen', url);
            }
            self.readyState = WebSocket.OPEN;
            reconnectAttempt = false;
            self.onopen(event);
        };

        ws.onclose = function(event) {
            clearTimeout(timeout);
            ws = null;
            if (forcedClose) {
                self.readyState = WebSocket.CLOSED;
                self.onclose(event);
            } else {
                self.readyState = WebSocket.CONNECTING;
                self.onconnecting();
                if (!reconnectAttempt && !timedOut) {
                    if (self.debug || ReconnectingWebSocket.debugAll) {
                        console.debug('ReconnectingWebSocket', 'onclose', url);
                    }
                    self.onclose(event);
                }
                setTimeout(function() {
                           connect(true);
                           }, self.reconnectInterval);
            }
        };
        ws.onmessage = function(event) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onmessage', url, event.data);
            }
            self.onmessage(event);
        };
        ws.onerror = function(event) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'onerror', url, event);
            }
            self.onerror(event);
        };
    }
    connect(url);

    this.send = function(data) {
        if (ws) {
            if (self.debug || ReconnectingWebSocket.debugAll) {
                console.debug('ReconnectingWebSocket', 'send', url, data);
            }
            return ws.send(data);
        } else {
            throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';
        }
    };

    this.close = function() {
        forcedClose = true;
        if (ws) {
            ws.close();
        }
    };

    /**
     * Additional public API method to refresh the connection if still open (close, re-open).
     * For example, if the app suspects bad data / missed heart beats, it can try to refresh.
     */
    this.refresh = function() {
        if (ws) {
            ws.close();
        }
    };
}

/**
 * Setting this to true is the equivalent of setting all instances of ReconnectingWebSocket.debug to true.
 */
ReconnectingWebSocket.debugAll = false;

/*********************************************************************************************************/

/*
 * Reforce Websocket Communication
 *
 */

if("WebSocket" in window) {

    var ws = new ReconnectingWebSocket("%%WEBSOCKET_URL%%");

    var processCommand = function(cmd) {

        if(typeof Reveal != "undefined") {
            cmd == 'r' ? Reveal.right() : Reveal.left();
            return;
        }

        if(typeof impress != "undefined") {
            cmd == 'r' ? impress().next() : impress().prev();
            return;
        }
    };

    ws.onopen = function() {
        // Web Socket is connected
        // alert("websocket is open");

        // You can send data now
        // ws.send("Hey man, you got the time?");

        console.log('onOpen!');
    };

    ws.onmessage = function(evt) {
        // alert("received: " + evt.data);
        console.log('onMessage!');
        processCommand(evt.data);
    };

    ws.onclose = function() {
        console.log('onClose!');
    };

} else alert("Browser doesn't support WebSocket!");
<|endoftext|>


<commit_before>import {map} from 'rxjs/operators'
import {of} from 'rxjs'
import {sepalMap} from './map'
import _ from 'lodash'
import ee from '@google/earthengine'
import guid from 'guid'

export default class EarthEngineLayer {
    constructor({layerIndex, toggleable, label, description, bounds, mapId$, props, onInitialized, onProgress}) {
        this.layerIndex = layerIndex
        this.toggleable = toggleable
        this.label = label
        this.description = description
        this.bounds = bounds
        this.mapId$ = mapId$
        this.props = props
        this.onProgress = onProgress
        this.onInitialized = onInitialized
    }

    equals(o) {
        return _.isEqual(o && o.props, this.props)
    }

    addToMap(googleMap) {
        const layer = new ee.layers.ImageOverlay(
            new ee.layers.EarthEngineTileSource(
                toMapId(this.mapId, this.token, this.urlTemplate)
            )
        )

        // [HACK] When fitting bounds with no change to bounds, after Google Maps v3.33,
        // tiles were loaded then removed. GEE used same id for tiles at the same position.
        // This caused freshly loaded tiles to be immediately removed.
        // This workaround uses unique tile ids. Hopefully this doesn't lead to any memory leaks.
        layer.getUniqueTileId_ = () => guid()

        googleMap.overlayMapTypes.setAt(this.layerIndex, layer)

        const notifyOnProgress = () => {
            // Manually calculate stats, since GEE returns stats from multiple zoom-levels
            const tileStatuses = layer.tilesById.getValues()
                .filter(tile => tile.zoom === googleMap.getZoom())
                .map(tile => tile.getStatus())
            const Status = ee.layers.AbstractTile.Status

            const loading = tileStatuses.filter(status => status === Status.LOADING).length
                + tileStatuses.filter(status => status === Status.NEW).length
                + tileStatuses.filter(status => status === Status.THROTTLED).length
            const loaded = tileStatuses.filter(status => status === Status.LOADED).length
            const failed = tileStatuses.filter(status => status === Status.FAILED).length
                + tileStatuses.filter(status => status === Status.ABORTED).length

            const tileStats = {
                count: loading + loaded + failed,
                loading,
                failed,
                loaded
            }
            tileStats.complete = tileStats.count === tileStats.loaded + tileStats.failed

            if (this.onProgress && tileStats.count > 0)
                this.onProgress(tileStats)
            else
                setTimeout(notifyOnProgress, 100)
        }
        this.boundsChangedListener = sepalMap.onBoundsChanged(notifyOnProgress)
        notifyOnProgress()
        layer.addEventListener('tile-load', notifyOnProgress)
        layer.addEventListener('tile-fail', notifyOnProgress)
    }

    removeFromMap(googleMap) {
        sepalMap.removeListener(this.boundsChangedListener)
        // [HACK] Prevent flashing of removed layers, which happens when just setting layer to null
        googleMap.overlayMapTypes.insertAt(this.layerIndex, null)
        googleMap.overlayMapTypes.removeAt(this.layerIndex + 1)
    }

    hide(googleMap, hidden) {
        const layer = googleMap.overlayMapTypes.getAt(this.layerIndex)
        layer && layer.setOpacity(hidden ? 0 : 1)
    }

    initialize$() {
        if (this.mapId)
            return of(this)
        return this.mapId$.pipe(
            map(({response: {token, mapId, urlTemplate, visParams}}) => {
                this.token = token
                this.mapId = mapId
                this.urlTemplate = urlTemplate
                this.visParams = visParams
                this.onInitialized(visParams)
                return this
            })
        )
    }
}

// Creates a ee.data.RawMapId.
// https://github.com/google/earthengine-api/blob/1a3121aa7574ecf2d5432c047621081aed8e1b28/javascript/src/data.js#L2198
const toMapId = (mapid, token, urlTemplate) => {
    const formatTileUrl = (x, y, z) => {
        const width = Math.pow(2, z)
        x = x % width
        if (x < 0) {
            x += width
        }
        return urlTemplate
            .replace('{x}', x)
            .replace('{y}', y)
            .replace('{z}', z)
    }
    return {mapid, token, formatTileUrl}
}
<commit_msg>Made sure onInitialized callback is defined before calling it.<commit_after>import {map} from 'rxjs/operators'
import {of} from 'rxjs'
import {sepalMap} from './map'
import _ from 'lodash'
import ee from '@google/earthengine'
import guid from 'guid'

export default class EarthEngineLayer {
    constructor({layerIndex, toggleable, label, description, bounds, mapId$, props, onInitialized, onProgress}) {
        this.layerIndex = layerIndex
        this.toggleable = toggleable
        this.label = label
        this.description = description
        this.bounds = bounds
        this.mapId$ = mapId$
        this.props = props
        this.onProgress = onProgress
        this.onInitialized = onInitialized
    }

    equals(o) {
        return _.isEqual(o && o.props, this.props)
    }

    addToMap(googleMap) {
        const layer = new ee.layers.ImageOverlay(
            new ee.layers.EarthEngineTileSource(
                toMapId(this.mapId, this.token, this.urlTemplate)
            )
        )

        // [HACK] When fitting bounds with no change to bounds, after Google Maps v3.33,
        // tiles were loaded then removed. GEE used same id for tiles at the same position.
        // This caused freshly loaded tiles to be immediately removed.
        // This workaround uses unique tile ids. Hopefully this doesn't lead to any memory leaks.
        layer.getUniqueTileId_ = () => guid()

        googleMap.overlayMapTypes.setAt(this.layerIndex, layer)

        const notifyOnProgress = () => {
            // Manually calculate stats, since GEE returns stats from multiple zoom-levels
            const tileStatuses = layer.tilesById.getValues()
                .filter(tile => tile.zoom === googleMap.getZoom())
                .map(tile => tile.getStatus())
            const Status = ee.layers.AbstractTile.Status

            const loading = tileStatuses.filter(status => status === Status.LOADING).length
                + tileStatuses.filter(status => status === Status.NEW).length
                + tileStatuses.filter(status => status === Status.THROTTLED).length
            const loaded = tileStatuses.filter(status => status === Status.LOADED).length
            const failed = tileStatuses.filter(status => status === Status.FAILED).length
                + tileStatuses.filter(status => status === Status.ABORTED).length

            const tileStats = {
                count: loading + loaded + failed,
                loading,
                failed,
                loaded
            }
            tileStats.complete = tileStats.count === tileStats.loaded + tileStats.failed

            if (this.onProgress && tileStats.count > 0)
                this.onProgress(tileStats)
            else
                setTimeout(notifyOnProgress, 100)
        }
        this.boundsChangedListener = sepalMap.onBoundsChanged(notifyOnProgress)
        notifyOnProgress()
        layer.addEventListener('tile-load', notifyOnProgress)
        layer.addEventListener('tile-fail', notifyOnProgress)
    }

    removeFromMap(googleMap) {
        sepalMap.removeListener(this.boundsChangedListener)
        // [HACK] Prevent flashing of removed layers, which happens when just setting layer to null
        googleMap.overlayMapTypes.insertAt(this.layerIndex, null)
        googleMap.overlayMapTypes.removeAt(this.layerIndex + 1)
    }

    hide(googleMap, hidden) {
        const layer = googleMap.overlayMapTypes.getAt(this.layerIndex)
        layer && layer.setOpacity(hidden ? 0 : 1)
    }

    initialize$() {
        if (this.mapId)
            return of(this)
        return this.mapId$.pipe(
            map(({response: {token, mapId, urlTemplate, visParams}}) => {
                this.token = token
                this.mapId = mapId
                this.urlTemplate = urlTemplate
                this.visParams = visParams
                this.onInitialized && this.onInitialized(visParams)
                return this
            })
        )
    }
}

// Creates a ee.data.RawMapId.
// https://github.com/google/earthengine-api/blob/1a3121aa7574ecf2d5432c047621081aed8e1b28/javascript/src/data.js#L2198
const toMapId = (mapid, token, urlTemplate) => {
    const formatTileUrl = (x, y, z) => {
        const width = Math.pow(2, z)
        x = x % width
        if (x < 0) {
            x += width
        }
        return urlTemplate
            .replace('{x}', x)
            .replace('{y}', y)
            .replace('{z}', z)
    }
    return {mapid, token, formatTileUrl}
}
<|endoftext|>


<commit_before>/* Copyright 2015 Christine S. MacNeill

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by appli cable law or agreed to in writing
  , software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

var H = require('highland');
var udpInlet = require('../valve/udpInlet.js');
var pcapInlet = require('../valve/pcapInlet.js');
var udpSpigot = require('../spigot/udpSpigot.js');
var SDP = require('../model/SDP.js');
var dgram = require('dgram');

var audioSDP = `v=0
o=- 1443080730 1443080730 IN IP4 172.29.80.68
s=IP Studio Stream
t=0 0
m=audio 5000 RTP/AVP 96
c=IN IP4 232.226.253.166/32
a=source-filter:incl IN IP4 232.226.253.166 172.29.80.68
a=rtpmap:96 L24/48000/2
a=control:trackID=1
a=mediaclk:direct=1970351840 rate=48000
a=extmap:1 urn:x-ipstudio:rtp-hdrext:origin-timestamp
a=extmap:2 urn:ietf:params:rtp-hdrext:smpte-tc 1920@48000/25
a=extmap:3 urn:x-ipstudio:rtp-hdrext:flow-id
a=extmap:4 urn:x-ipstudio:rtp-hdrext:source-id
a=extmap:5 urn:x-ipstudio:rtp-hdrext:grain-flags
a=extmap:7 urn:x-ipstudio:rtp-hdrext:sync-timestamp
a=extmap:9 urn:x-ipstudio:rtp-hdrext:grain-duration
a=ts-refclk:ptp=IEEE1588-2008:ec-46-70-ff-fe-00-42-c4`

var mcastAddress = '224.1.1.1';
var netif = '192.168.0.12';
var port = 8000;

var pcapFile = '/Volumes/Ormiscraid/media/streampunk/examples/rtp-audio-l24-2chan.pcap';

var server = dgram.createSocket('udp4');

var udpSource = pcapInlet(pcapFile)
  .through(udpSpigot(server, mcastAddress, port, netif))
  .errors(function (e) { console.error(e); });

var udpSync = udpInlet(server, mcastAddress, port, netif)
  .errors(function (e) { console.error(e); });

udpSync.each(H.log);
udpSource.each(H.log);
<commit_msg>About to smoke test UDP send and receive. Take 2.<commit_after>/* Copyright 2015 Christine S. MacNeill

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by appli cable law or agreed to in writing
  , software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

var H = require('highland');
var udpInlet = require('../valve/udpInlet.js');
var pcapInlet = require('../valve/pcapInlet.js');
var udpSpigot = require('../spigot/udpSpigot.js');
var SDP = require('../model/SDP.js');
var dgram = require('dgram');

var audioSDP = `v=0
o=- 1443080730 1443080730 IN IP4 172.29.80.68
s=IP Studio Stream
t=0 0
m=audio 5000 RTP/AVP 96
c=IN IP4 232.226.253.166/32
a=source-filter:incl IN IP4 232.226.253.166 172.29.80.68
a=rtpmap:96 L24/48000/2
a=control:trackID=1
a=mediaclk:direct=1970351840 rate=48000
a=extmap:1 urn:x-ipstudio:rtp-hdrext:origin-timestamp
a=extmap:2 urn:ietf:params:rtp-hdrext:smpte-tc 1920@48000/25
a=extmap:3 urn:x-ipstudio:rtp-hdrext:flow-id
a=extmap:4 urn:x-ipstudio:rtp-hdrext:source-id
a=extmap:5 urn:x-ipstudio:rtp-hdrext:grain-flags
a=extmap:7 urn:x-ipstudio:rtp-hdrext:sync-timestamp
a=extmap:9 urn:x-ipstudio:rtp-hdrext:grain-duration
a=ts-refclk:ptp=IEEE1588-2008:ec-46-70-ff-fe-00-42-c4`

var mcastAddress = '224.1.1.1';
var netif = '192.168.0.16';
var port = 8000;

var pcapFile = '/Volumes/Ormiscraid/media/streampunk/examples/rtp-audio-l24-2chan.pcap';

var server = dgram.createSocket('udp4');

// var udpSource = pcapInlet(pcapFile)
//   .through(udpSpigot(server, mcastAddress, port, netif))
//   .errors(function (e) { console.error(e); });

var udpSync = udpInlet(server, mcastAddress, port, netif)
  .errors(function (e) { console.error(e); });

udpSync.each(H.log);
// udpSource.each(H.log);
<|endoftext|>


<commit_before>/*
 * Sozi - A presentation tool using the SVG standard
 *
 * Copyright (C) 2010-2011 Guillaume Savaton
 *
 * This program is dual licensed under the terms of the MIT license
 * or the GNU General Public License (GPL) version 3.
 * A copy of both licenses is provided in the doc/ folder of the
 * official release of Sozi.
 *
 * See http://sozi.baierouge.fr/wiki/en:license for details.
 */

var sozi = sozi || {};

(function () {
    var exports = sozi.animation = sozi.animation || {},
        window = this,
        TIME_STEP_MS = 40,
        animators = [],
        timer,
        requestAnimationFrame = window.mozRequestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            window.oRequestAnimationFrame;

    function start() {
        if (requestAnimationFrame) {
            requestAnimationFrame(loop);
        }
        else {
            timer = window.setInterval(function() {
                loop(Date.now());
            }, TIME_STEP_MS);
        }
    }

    function loop(timestamp) {
        var i;
        if (animators.length > 0) {
            if (requestAnimationFrame) {
                requestAnimationFrame(loop);
            }
            for (i = 0; i < animators.length; i += 1) {
                animators[i].step(timestamp)
            }
        }
        else {
            if (!requestAnimationFrame) {
                window.clearInterval(timer);
            }
        }
    }

    function addAnimator(animator) {
        animators.push(animator);
        if (animators.length === 1) {
            start();
        }
    }

    function removeAnimator(animator) {
        animators.splice(animators.indexOf(animator), 1);
    }

    exports.Animator = function (onStep, onDone) {
        this.onStep = onStep;
        this.onDone = onDone;

        this.durationMs = 0;
        this.data = {};
        this.initialTime = 0;
        this.started = false;
    };

    exports.Animator.prototype.start = function (durationMs, data) {
        this.durationMs = durationMs;
        this.data = data;

        this.initialTime = Date.now();
        this.onStep(0, this.data);

        if (!this.started) {
            this.started = true;
            addAnimator(this);
        }
    };

    exports.Animator.prototype.stop = function () {
        if (this.started) {
            removeAnimator(this);
            this.started = false;
        }
    };

    exports.Animator.prototype.step = function (timestamp) {
        var elapsedTime = timestamp - this.initialTime;
        if (elapsedTime >= this.durationMs) {
            this.stop();
            this.onStep(1, this.data);
            this.onDone();
        } else {
            this.onStep(elapsedTime / this.durationMs, this.data);
        }
    };

    exports.profiles = {
        "linear": function (x) {
            return x;
        },

        "accelerate": function (x) {
            return Math.pow(x, 3);
        },

        "strong-accelerate": function (x) {
            return Math.pow(x, 5);
        },

        "decelerate": function (x) {
            return 1 - Math.pow(1 - x, 3);
        },

        "strong-decelerate": function (x) {
            return 1 - Math.pow(1 - x, 5);
        },

        "accelerate-decelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = Math.pow(2 * xs, 3) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "strong-accelerate-decelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = Math.pow(2 * xs, 5) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "decelerate-accelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = (1 - Math.pow(1 - 2 * xs, 2)) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "strong-decelerate-accelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = (1 - Math.pow(1 - 2 * xs, 3)) / 2;
            return x <= 0.5 ? y : 1 - y;
        }
    };
}());

<commit_msg>Pass JSLint<commit_after>/*
 * Sozi - A presentation tool using the SVG standard
 *
 * Copyright (C) 2010-2011 Guillaume Savaton
 *
 * This program is dual licensed under the terms of the MIT license
 * or the GNU General Public License (GPL) version 3.
 * A copy of both licenses is provided in the doc/ folder of the
 * official release of Sozi.
 *
 * See http://sozi.baierouge.fr/wiki/en:license for details.
 */

var sozi = sozi || {};

(function () {
    var exports = sozi.animation = sozi.animation || {},
        window = this,
        TIME_STEP_MS = 40,
        animators = [],
        timer,
        requestAnimationFrame = window.mozRequestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            window.oRequestAnimationFrame;

    function loop(timestamp) {
        var i;
        if (animators.length > 0) {
            if (requestAnimationFrame) {
                requestAnimationFrame(loop);
            }
            for (i = 0; i < animators.length; i += 1) {
                animators[i].step(timestamp);
            }
        }
        else {
            if (!requestAnimationFrame) {
                window.clearInterval(timer);
            }
        }
    }

    function start() {
        if (requestAnimationFrame) {
            requestAnimationFrame(loop);
        }
        else {
            timer = window.setInterval(function () {
                loop(Date.now());
            }, TIME_STEP_MS);
        }
    }

    function addAnimator(animator) {
        animators.push(animator);
        if (animators.length === 1) {
            start();
        }
    }

    function removeAnimator(animator) {
        animators.splice(animators.indexOf(animator), 1);
    }

    exports.Animator = function (onStep, onDone) {
        this.onStep = onStep;
        this.onDone = onDone;

        this.durationMs = 0;
        this.data = {};
        this.initialTime = 0;
        this.started = false;
    };

    exports.Animator.prototype.start = function (durationMs, data) {
        this.durationMs = durationMs;
        this.data = data;

        this.initialTime = Date.now();
        this.onStep(0, this.data);

        if (!this.started) {
            this.started = true;
            addAnimator(this);
        }
    };

    exports.Animator.prototype.stop = function () {
        if (this.started) {
            removeAnimator(this);
            this.started = false;
        }
    };

    exports.Animator.prototype.step = function (timestamp) {
        var elapsedTime = timestamp - this.initialTime;
        if (elapsedTime >= this.durationMs) {
            this.stop();
            this.onStep(1, this.data);
            this.onDone();
        } else {
            this.onStep(elapsedTime / this.durationMs, this.data);
        }
    };

    exports.profiles = {
        "linear": function (x) {
            return x;
        },

        "accelerate": function (x) {
            return Math.pow(x, 3);
        },

        "strong-accelerate": function (x) {
            return Math.pow(x, 5);
        },

        "decelerate": function (x) {
            return 1 - Math.pow(1 - x, 3);
        },

        "strong-decelerate": function (x) {
            return 1 - Math.pow(1 - x, 5);
        },

        "accelerate-decelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = Math.pow(2 * xs, 3) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "strong-accelerate-decelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = Math.pow(2 * xs, 5) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "decelerate-accelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = (1 - Math.pow(1 - 2 * xs, 2)) / 2;
            return x <= 0.5 ? y : 1 - y;
        },

        "strong-decelerate-accelerate": function (x) {
            var xs = x <= 0.5 ? x : 1 - x,
                y = (1 - Math.pow(1 - 2 * xs, 3)) / 2;
            return x <= 0.5 ? y : 1 - y;
        }
    };
}());

<|endoftext|>


<commit_before>/**
 * mlpushmenu.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
;( function( window ) {

	'use strict';

	function extend( a, b ) {
		for( var key in b ) {
			if( b.hasOwnProperty( key ) ) {
				a[key] = b[key];
			}
		}
		return a;
	}

	// taken from https://github.com/inuyaksa/jquery.nicescroll/blob/master/jquery.nicescroll.js
	function hasParent( e, id ) {
		if (!e) return false;
		var el = e.target||e.srcElement||e||false;
		while (el && el.id != id) {
			el = el.parentNode||false;
		}
		return (el!==false);
	}

	// returns the depth of the element "e" relative to element with id=id
	// for this calculation only parents with classname = waypoint are considered
	function getLevelDepth( e, id, waypoint, cnt ) {
		cnt = cnt || 0;
		if ( e.id.indexOf( id ) >= 0 ) return cnt;
		if( classie.has( e, waypoint ) ) {
			++cnt;
		}
		return e.parentNode && getLevelDepth( e.parentNode, id, waypoint, cnt );
	}

	// http://coveroverflow.com/a/11381730/989439
	function mobilecheck() {
		var check = false;
		(function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
		return check;
	}

	// returns the closest element to 'e' that has class "classname"
	function closest( e, classname ) {
		if( classie.has( e, classname ) ) {
			return e;
		}
		return e.parentNode && closest( e.parentNode, classname );
	}

	function mlPushMenu( el, trigger, options ) {
		this.el = el;
		this.trigger = trigger;
		this.options = extend( this.defaults, options );
		// support 3d transforms
		this.support = Modernizr.csstransforms3d;
		if( this.support ) {
			this._init();
		}
	}

	mlPushMenu.prototype = {
		defaults : {
			// overlap: there will be a gap between open levels
			// cover: the open levels will be on top of any previous open level
			type : 'overlap', // overlap || cover
			// space between each overlaped level
			levelSpacing : 40,
			// classname for the element (if any) that when clicked closes the current level
			backClass : 'mp-back'
		},
		_init : function() {
			// if menu is open or not
			this.open = false;
			// level depth
			this.level = 0;
			// the moving wrapper
			this.wrapper = document.getElementById( 'mp-pusher' );
			// the mp-level elements
			this.levels = Array.prototype.slice.call( this.el.querySelectorAll( 'div.mp-level' ) );
			// save the depth of each of these mp-level elements
			var self = this;
			this.levels.forEach( function( el, i ) { el.setAttribute( 'data-level', getLevelDepth( el, self.el.id, 'mp-level' ) ); } );
			// the menu items
			this.menuItems = Array.prototype.slice.call( this.el.querySelectorAll( 'li' ) );
			// if type == "cover" these will serve as hooks to move back to the previous level
			this.levelBack = Array.prototype.slice.call( this.el.querySelectorAll( '.' + this.options.backClass ) );
			// event type (if mobile use touch events)
			this.eventtype = mobilecheck() ? 'touchstart' : 'click';
			// add the class mp-overlap or mp-cover to the main element depending on options.type
			classie.add( this.el, 'mp-' + this.options.type );
			// initialize / bind the necessary events
			this._initEvents();
		},
		_initEvents : function() {
			var self = this;

			// the menu should close if clicking somewhere on the body
			var bodyClickFn = function( el ) {
				self._resetMenu();
				el.removeEventListener( self.eventtype, bodyClickFn );
			};

			// open (or close) the menu
			this.trigger.addEventListener( this.eventtype, function( ev ) {
				ev.stopPropagation();
				ev.preventDefault();
				if( self.open ) {
					self._resetMenu();
				}
				else {
					self._openMenu();
					// the menu should close if clicking somewhere on the body (excluding clicks on the menu)
					document.addEventListener( self.eventtype, function( ev ) {
						if( self.open && !hasParent( ev.target, self.el.id ) ) {
							bodyClickFn( this );
						}
					} );
				}
			} );

			// opening a sub level menu
			this.menuItems.forEach( function( el, i ) {
				// check if it has a sub level
				var subLevel = el.querySelector( 'div.mp-level' );
				if( subLevel ) {
					el.querySelector( 'a' ).addEventListener( self.eventtype, function( ev ) {
						ev.preventDefault();
						var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
						if( self.level <= level ) {
							ev.stopPropagation();
							classie.add( closest( el, 'mp-level' ), 'mp-level-overlay' );
							self._openMenu( subLevel );
						}
					} );
				}
			} );

			// closing the sub levels :
			// by clicking on the visible part of the level element
			this.levels.forEach( function( el, i ) {
				el.addEventListener( self.eventtype, function( ev ) {
					ev.stopPropagation();
					var level = el.getAttribute( 'data-level' );
					if( self.level > level ) {
						self.level = level;
						self._closeMenu();
					}
				} );
			} );

			// by clicking on a specific element
			this.levelBack.forEach( function( el, i ) {
				el.addEventListener( self.eventtype, function( ev ) {
					ev.preventDefault();
					var level = closest( el, 'mp-level' ).getAttribute( 'data-level' );
					if( self.level <= level ) {
						ev.stopPropagation();
						self.level = closest( el, 'mp-level' ).getAttribute( 'data-level' ) - 1;
						self.level === 0 ? self._resetMenu() : self._closeMenu();
					}
				} );
			} );
		},
		_openMenu : function( subLevel ) {
			// increment level depth
			++this.level;

			// move the main wrapper
			var levelFactor = ( this.level - 1 ) * this.options.levelSpacing,
				translateVal = this.options.type === 'overlap' ? this.el.offsetWidth + levelFactor : this.el.offsetWidth;

			this._setTransform( 'translate3d(' + translateVal + 'px,0,0)' );

			if( subLevel ) {
				// reset transform for sublevel
				this._setTransform( '', subLevel );
				// need to reset the translate value for the level menus that have the same level depth and are not open
				for( var i = 0, len = this.levels.length; i < len; ++i ) {
					var levelEl = this.levels[i];
					if( levelEl != subLevel && !classie.has( levelEl, 'mp-level-open' ) ) {
						this._setTransform( 'translate3d(-100%,0,0) translate3d(' + -1*levelFactor + 'px,0,0)', levelEl );
					}
				}
			}
			// add class mp-pushed to main wrapper if opening the first time
			if( this.level === 1 ) {
				classie.add( this.wrapper, 'mp-pushed' );
				this.open = true;
			}
			// add class mp-level-open to the opening level element
			classie.add( subLevel || this.levels[0], 'mp-level-open' );
		},
		// close the menu
		_resetMenu : function() {
			this._setTransform('translate3d(0,0,0)');
			this.level = 0;
			// remove class mp-pushed from main wrapper
			classie.remove( this.wrapper, 'mp-pushed' );
			this._toggleLevels();
			this.open = false;
		},
		// close sub menus
		_closeMenu : function() {
			var translateVal = this.options.type === 'overlap' ? this.el.offsetWidth + ( this.level - 1 ) * this.options.levelSpacing : this.el.offsetWidth;
			this._setTransform( 'translate3d(' + translateVal + 'px,0,0)' );
			this._toggleLevels();
		},
		// translate the el
		_setTransform : function( val, el ) {
			el = el || this.wrapper;
			el.style.WebkitTransform = val;
			el.style.MozTransform = val;
			el.style.transform = val;
		},
		// removes classes mp-level-open from closing levels
		_toggleLevels : function() {
			for( var i = 0, len = this.levels.length; i < len; ++i ) {
				var levelEl = this.levels[i];
				if( levelEl.getAttribute( 'data-level' ) >= this.level + 1 ) {
					classie.remove( levelEl, 'mp-level-open' );
					classie.remove( levelEl, 'mp-level-overlay' );
				}
				else if( Number( levelEl.getAttribute( 'data-level' ) ) == this.level ) {
					classie.remove( levelEl, 'mp-level-overlay' );
				}
			}
		}
	}

	// add to global namespace
	window.mlPushMenu = mlPushMenu;

} )( window );<commit_msg>已删除 source/js/mlpushmenu.js<commit_after><|endoftext|>