<commit_before>
/*
The MIT License (MIT)

Copyright (c) 2014 Rob Christian

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.
*/

/*

Semi-colons are just FUD. If your minifier can't handle this code, switch to one that is JS-compliant.

*/

;(function(){

  /*  Private Class Data  */

  var DEFINE = Object.defineProperty
  var ID_GETTER_KEY = {}

  var _bindables = []
  var _events = new MicroEvent()
  var _ct = {
    setter_cb: function(id,val){ _events.trigger(id,val) }
  , send_id: function(){}
  }

  /*  Bindable Classes  */

  function Bindable(data){
    if (typeOf(data) === 'Array')
      return new BindableArray(data)
    else if (familyOf(data) === 'complex')
      return new BindableObject(data)
  }

  function BindableObject(data){
    DEFINE(this, '_new_property_', { enumerable:false, configurable:false,
      set:function(keyval){ addProperty.apply(this, keyval) }
    })
    for (var prop in data) {
      if (data.hasOwnProperty(prop)) this._new_property_ = [prop, data[prop]]
    }
  }

  function BindableArray(){
    var args = Array.prototype.slice.apply(arguments)[0]
    var self = []

    DEFINE(self, '_new_property_', { enumerable:false, configurable:false,
      set:function(keyval){ addProperty.apply(self, keyval) }
    })
    for (var i in args) {
      if (args.hasOwnProperty(i)) self._new_property_ = [i, args[i]]
    }

    return self
  }

  function addProperty(key, val){
    var _val = undefined
    var _id = Math.random().toString().split('.')[1]

    DEFINE(this, key, {
      enumerable: true
    , get: function(){ return _val }
    , set: function(value){
        if (value === ID_GETTER_KEY) { _ct.send_id(_id) }
        else { _val = value; _ct.setter_cb(_id, value) }
      }
    })
    if (familyOf(val) === 'complex') val = new Bindable(val)
    this[key] = val
  }

  /* Takes a form DOM object and a Binding object, and does the rest for you. */

  function addForm(form, container){
    var bindable = container.bindable

    ;[].forEach.call(form.querySelectorAll('input'), function(field){

      if (field.name in bindable) {
        CrossTalk.fieldManager(function(input_handler, output_handler){

          field.addEventListener('input', function(ev){
            var do_it = function(){ bindable[field.name] = ev.target.value }
            input_handler( do_it )
          })

          container.bind(bindable, field.name, function(val){
            var do_it = function(){ field.value = val }
            output_handler( do_it )
          })

        })

        field.value = bindable[field.name]
      }

    })
  }

  /* Inverts control: Prevents inputs from receiving updates while they are the sender. */

  function fieldManager(receive_handlers){
    var _sent_by_me = false

    function input_handler(do_it){
      _sent_by_me = true
      do_it()
    }
    function output_handler(do_it){
      _sent_by_me ? _sent_by_me = false : do_it()
    }
    receive_handlers( input_handler, output_handler )
  }

  /* Recursively constructs a copy of the input object, having getter/setter pairs of every ownProperty. */

  function BindableContainer(data){
    var _data
    if (familyOf(data) !== 'complex') return null

    _data = new Bindable(data)

    this.bind = bind
    this.unbind = unbind
    this.recompute = function(data){
      if (familyOf(data) === 'complex')
        _data = new Bindable(data)
      return this
    }
    DEFINE(this, 'bindable', {get:function(){return _data}, enumerable:true, configurable:false})

    _bindables.push(_data)
  }
  function bind(parent, property, setter_cb){
    CrossTalk.takeId(function(id){ _events.bind(id, setter_cb) })
    parent[property] = ID_GETTER_KEY
  }
  function unbind(property, setter_cb){
    _events.unbind(setter_cb)
  }

  /*  HELPERS  */

  function familyOf(thing){
    if (typeOf(thing)) {
      return {
        Date: 'simple'
      , String: 'simple'
      , Number: 'simple'
      , Boolean: 'simple'
      , Function: 'simple'
      , Array: 'complex'
      , Object: 'complex'
      }[typeOf(thing)] || 'complex'
    } else {
      return false
    }
  }

  function typeOf(thing){
    return (thing != null && !Number.isNaN(thing) && thing.constructor) ? thing.constructor.name : '' + thing
  }

  function each(obj, cb){
    // if (typeOf(obj) === 'BindableObject' || typeOf(obj) === 'BindableArray')
    //   obj = obj

    for (var prop in obj)
      cb(prop, obj[prop])
  }

  var CrossTalk = {
    Binding: BindableContainer
  , fieldManager: fieldManager
  , addForm: addForm
  , takeId: function(cb){ _ct.send_id = cb }
  }
  DEFINE(CrossTalk, 'bindables', {get:function(){return _bindables}, enumerable: true})
  DEFINE(CrossTalk, 'ID_GETTER_KEY', {value:ID_GETTER_KEY, writeable:false})

  if (typeof module !== 'undefined' && module.hasOwnProperty('exports')) {
    module.exports = CrossTalk
  } else {
    window.CrossTalk = CrossTalk
    window.familyOf = familyOf
    window.typeOf = typeOf
    window.Bindable = Bindable
  }

})()
<commit_msg>Working on making array methods work correctly.<commit_after>
/*
The MIT License (MIT)

Copyright (c) 2014 Rob Christian

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.
*/

/*

Semi-colons are just FUD. If your minifier can't handle this code, switch to one that is JS-compliant.

*/

;(function(){

  /*  Private Class Data  */

  var DEFINE = Object.defineProperty
  var ID_GETTER_KEY = {}

  var _bindables = []
  var _events = new MicroEvent()
  var _ct = {
    setter_cb: function(id,val){ _events.trigger(id,val) }
  , send_id: function(){}
  }

  /*  Bindable Classes  */

  function Bindable(data){
    if (typeOf(data) === 'Array')
      return new BindableArray(data)
    else if (familyOf(data) === 'complex')
      return new BindableObject(data)
  }
  function bind(parent, property, setter_cb){
    CrossTalk.takeId(function(id){ _events.bind(id, setter_cb) })
    parent[property] = ID_GETTER_KEY
  }
  function unbind(property, setter_cb){
    _events.unbind(setter_cb)
  }
  function recompute(data){
    if (familyOf(data) === 'complex')
      this.constructor(data)
    return this
  }

  function BindableObject(data){
    Object.keys(data).map(function(prop){
      this._new_property_ = [prop, data[prop]]
    }.bind(this))
  }
  DEFINE(BindableObject.prototype, 'bind', { enumerable:false, configurable:false, value:bind })
  DEFINE(BindableObject.prototype, 'unbind', { enumerable:false, configurable:false, value:unbind })
  DEFINE(BindableObject.prototype, 'recompute', { enumerable:false, configurable:false, value:recompute })
  DEFINE(BindableObject.prototype, '_new_property_', { enumerable:false, configurable:false,
    set:function(keyval){ addProperty.apply(this, keyval) }
  })

  function BindableArray(array){
    var self = []

    DEFINE(self, 'bind', { enumerable:false, configurable:false, value:bind })
    DEFINE(self, 'unbind', { enumerable:false, configurable:false, value:unbind })
    DEFINE(self, 'recompute', { enumerable:false, configurable:false, value:recompute })
    DEFINE(self, '_new_property_', { enumerable:false, configurable:false,
      set:function(keyval){ addProperty.apply(self, keyval) }
    })
    DEFINE(self, 'push', { enumerable:false, configurable:false,
      value:function(v){ self._new_property_ = [self.length, v] }
    })
    DEFINE(self, 'pop', { enumerable:false, configurable:false,
      value:function(){ var r = self[self.length-1]; self.length = self.length-1; return r }
    })
    DEFINE(self, 'concat', { enumerable:false, configurable:false,
      value:function(arr){
        if (arr && arr.length) {
          Object.keys(arr).map(function(key){
            self._new_property_ = [self.length, arr[key]]
          })
        }
      }
    })
    Object.keys(array).map(function(key){
      self._new_property_ = [key, array[key]]
    })

    return self
  }

  function addProperty(key, val){
    var _val = undefined
    var _id = Math.random().toString().split('.')[1]

    DEFINE(this, key, {
      enumerable: true
    , configurable: true
    , get: function(){ return _val }
    , set: function(value){
        if (value === ID_GETTER_KEY) {
          _ct.send_id(_id)
        }
        else if (familyOf(value) === 'complex') {
          _val = new Bindable(value)
        }
        else {
          _val = value
        }
        _ct.setter_cb(_id, _val)
      }
    })
    this[key] = val
  }

  /* Takes a form DOM object and a Binding object, and does the rest for you. */

  function bindForm(form, container){
    var bindable = container.bindable

    ;[].forEach.call(form.querySelectorAll('input'), function(field){

      if (field.name in bindable) {
        CrossTalk.fieldManager(function(input_handler, output_handler){

          field.addEventListener('input', function(ev){
            var do_it = function(){ bindable[field.name] = ev.target.value }
            input_handler( do_it )
          })

          container.bind(bindable, field.name, function(val){
            var do_it = function(){ field.value = val }
            output_handler( do_it )
          })

        })

        field.value = bindable[field.name]
      }

    })
  }

  /* Inverts control: Prevents inputs from receiving updates while they are the sender. */

  function fieldManager(receive_handlers){
    var _sent_by_me = false

    function input_handler(do_it){
      _sent_by_me = true
      do_it()
    }
    function output_handler(do_it){
      _sent_by_me ? _sent_by_me = false : do_it()
    }
    receive_handlers( input_handler, output_handler )
  }

  /* Our entry point for creating bindable objects, keeps a reference to the object created. */

  function NewBindable(data){
    var bindable = new Bindable(data)
    _bindables.push(bindable)
    return bindable
  }

  /*  HELPERS  */

  function familyOf(thing){
    if (typeOf(thing)) {
      return {
        Date: 'simple'
      , String: 'simple'
      , Number: 'simple'
      , Boolean: 'simple'
      , Function: 'simple'
      , Array: 'complex'
      , Object: 'complex'
      }[typeOf(thing)] || 'complex'
    } else {
      return false
    }
  }

  function typeOf(thing){
    return (thing != null && !Number.isNaN(thing) && thing.constructor) ? thing.constructor.name : '' + thing
  }

  function each(obj, cb){
    // if (typeOf(obj) === 'BindableObject' || typeOf(obj) === 'BindableArray')
    //   obj = obj

    for (var prop in obj)
      cb(prop, obj[prop])
  }

  var CrossTalk = {
    Binding: NewBindable
  , fieldManager: fieldManager
  , bindForm: bindForm
  , takeId: function(cb){ _ct.send_id = cb }
  }
  DEFINE(CrossTalk, 'bindables', {get:function(){return _bindables}, enumerable: true})
  DEFINE(CrossTalk, 'ID_GETTER_KEY', {value:ID_GETTER_KEY, writeable:false})

  if (typeof module !== 'undefined' && module.hasOwnProperty('exports')) {
    module.exports = CrossTalk
  } else {
    window.CrossTalk = CrossTalk
    window.familyOf = familyOf
    window.typeOf = typeOf
    window.Bindable = Bindable
  }

})()
<|endoftext|>


<commit_before>// Core of fnfnen.
// Variables  {{{1

var DUMMY_SINCE_ID = 1;
var MAX_COUNT = 200;
var MAX_TWEET_CONTENT = 140;
var TWITTER_API_URI = 'http://api.twitter.com/1/';
var TWITTER_UI_URI = 'http://twitter.com/';
var UPDATE_INTERVAL = 5 * 60 * 1000;  // in milliseconds

var g_parameters = {'automatic_update': true};
var g_since_id = null;
var g_tweet_id_to_reply = null;
var g_update_timer = null;
var g_user = null;

// Code  {{{1
function after_post()  //{{{2
{
  $('#tweet_box').val('');

  g_tweet_id_to_reply = null;
  $('#in_reply_to_status_id').remove();

  return;
}

function authenticate()  //{{{2
{
  call_twitter_api(TWITTER_UI_URI,
                   'account/verify_credentials',
                   {'callback': 'callback_authenticate'});
  return;
}

function callback_authenticate(d)
{
  if (d.error)
    return alert(d.error);

  g_user = d;

  update();
  return;
}

function before_post()  //{{{2
{
  // Update timeline manually.
  if ($('#tweet_box').val() == '') {
    update();
    return false;
  }

  if (g_tweet_id_to_reply) {
    var node_reply_id = create_element('input');
    node_reply_id.attr('id', 'in_reply_to_status_id');
    node_reply_id.attr('name', 'in_reply_to_status_id');
    node_reply_id.attr('type', 'hidden');
    node_reply_id.val(g_tweet_id_to_reply);
    $('#post_form').append(node_reply_id);
  }

  // FIXME: Disable or warn too long tweet.
  return true;
}

call_twitter_api = (function(){  //{{{2
  var s_seq = (new Date).getTime();  // To avoid browser-side caching.
  var s_lcds_nodes = {};  // {api_name: node_script, ...}

  return function(base_uri, api_name, _parameters) {
    parameters = $.extend(false, _parameters, {'seq': s_seq++});

    var ps = [];
    for (var key in parameters)
      ps.push(key + '=' + parameters[key]);

    s_lcds_nodes[api_name] = load_cross_domain_script(
      base_uri + api_name + '.json' + '?' + ps.join('&'),
      s_lcds_nodes[api_name]
   );
  }
})();

function count_tweet_content(e)  //{{{2
{
  var remain = MAX_TWEET_CONTENT - $('#tweet_box').val().length;

  $('#tweet_content_counter').text(remain);

  $('#tweet_content_counter').removeClass();
  if (remain < 0)
    $('#tweet_content_counter').addClass('much-content');
  else if (remain == 0)
    $('#tweet_content_counter').addClass('full-content');
  else if (remain < MAX_TWEET_CONTENT)
    $('#tweet_content_counter').addClass('some-content');
  else if (remain == MAX_TWEET_CONTENT)
    $('#tweet_content_counter').addClass('no-content');
  else
    ;

  return true;
}

function create_element(element_name)  //{{{2
{
  return $(document.createElement(element_name));
}

function favorite_symbol(favorite_p)  //{{{2
{
  return (favorite_p
          ? '★'  // black (filled) star
          : '☆'  // white (empty) star
          );
}

function html_from_tweet(tweet)  //{{{2
{
  // FIXME: Add a button to retweet a tweet.
  // FIXME: Expand abbreviated URIs in a tweet.
  // FIXME: Make links for hashtags in a tweet.
  return (''
          /* user icon */
          + ''
          + ''
          + ''
          /* screen name */
          + ''
          + tweet.user.screen_name
          + ''
          /* text */
          + ''
          + make_links_in_text(tweet.text)
          + ''
          /* posted time */
          + ''
          + human_readable_format_from_date(new Date(tweet.created_at))
          + ''
          /* button to reply */
          + ''
          + '↵'  // Carriage return symbol
          + ''
          /* button to show the conversation */
          + (tweet.in_reply_to_status_id
             ? (''
                + ''
                + '♻'  // Black universal recycling symbol
                + '')
             : '')
          /* button to toggle favorite */
          + ''
          + favorite_symbol(tweet.favorited)
          + ''
         );
}

function human_readable_format_from_date(date)  //{{{2
{
  return (date.getFullYear()
          + '-' + pad(date.getMonth() + 1)
          + '-' + pad(date.getDate())
          + ' ' + pad(date.getHours())
          + ':' + pad(date.getMinutes())
          + ':' + pad(date.getSeconds()));
}

function pad(n)
{
  return n < 10 ? '0' + n : n;
}

function initialize_parameters()  //{{{2
{
  var ss = window.location.href.split('?', 2);
  var parameters = (ss[1] ? ss[1] : '').split('&');
  parameters = ((1 <= parameters.length) && (parameters[0] != '')
                ? parameters
                : []);

  for (var i in parameters) {
    var key_value = parameters[i].split('=', 2);
    var key = decodeURIComponent(key_value[0]);
    var value = eval(decodeURIComponent(key_value[1]));  // FIXME: eval?

    g_parameters[key] = value;
  }
  return;
}

function load_cross_domain_script(uri, node)  //{{{2
{
  if (node && node.parentNode)
    node.parentNode.removeChild(node);

  node = document.createElement("script");
  node.src = uri;
  node.type = "text/javascript";
  document.body.appendChild(node);

  return node;
}

function make_links_in_text(text)  //{{{2
{
  // FIXME: Regular expression for URI.
  return text.replace(
    /https?:\/\/[\w!#$%&'*+,.\/:;=?@~-]+|@(\w+)/g,
    function(matched_string, screen_name){
      if (screen_name) {
        return (''
                + matched_string
                + '');
      } else {
        return (''
                + matched_string
                + '');
      }
    }
  );
}

function scroll(y_coordinate)  //{{{2
{
  scrollTo(0, y_coordinate);
  return;
}

function set_up_to_reply(screen_name, tweet_id)  //{{{2
{
  var active_column = $('#column_home');  // FIXME: Use the active column.

  g_tweet_id_to_reply = tweet_id;
  $('#tweet_box').val('@' + screen_name + ' ' + $('#tweet_box').val());
  $('#tweet_box').focus();

  scroll(active_column.attr('scrollHeight'));
  return;
}

function show_conversation(tweet_id)  //{{{2
{
  // FIXME: NIY
  return;
}

function show_tweets(d, node_column)  //{{{2
{
  // d = [{newest-tweet}, ..., {oldest-tweet}]
  if (d.length == 0)
    return 0;

  var node_tweet_hub = create_element('div');
  var node_dummy_tweet = create_element('div');

  node_tweet_hub.append(node_dummy_tweet);
  node_tweet_hub.addClass('tweet-hub');

  for (var i in d) {
    var node_tweet = create_element('div');
    node_tweet.attr('id', node_column.attr('id') + '-' + d[i].id);
    node_tweet.data('json', d[i]);
    node_tweet.html(html_from_tweet(d[i]));

    node_tweet.addClass('tweet');
    if (tweet_mention_p(d[i]))
      node_tweet.addClass('mention');
    if (tweet_mine_p(d[i]))
      node_tweet.addClass('mine');
    // FIXME: node_tweet.addClass('censored censored-{kind}');

    node_tweet_hub.prepend(node_tweet);
  }

  node_dummy_tweet.remove();

  node_column.append(node_tweet_hub);

  // Scroll to the head of the latest tweet hub.
  // FIXME: Customize behavior on this autoscroll.
  scroll(node_column.attr('scrollHeight')
         - node_tweet_hub.attr('scrollHeight'));
  return d.length;
}

function toggle_favorite(tweet)  //{{{2
{
  // FIXME: NIY
  alert(tweet);
  return;
}

function tweet_mention_p(tweet)  //{{{2
{
  return tweet.text.match(new RegExp('@' + g_user.screen_name + '\\b', 'i'));
}

function tweet_mine_p(tweet)  //{{{2
{
  return tweet.user.id == g_user.id;
}

function update()  //{{{2
{
  if (!g_user)
    return authenticate();

  call_twitter_api(TWITTER_API_URI,
                   'statuses/home_timeline',
                   {'callback': 'callback_update',
                    'count': MAX_COUNT,
                    'since_id': g_since_id || DUMMY_SINCE_ID});
  return;
}

function callback_update(d)
{
  $('#i_last_updated_time').text('Last updated: ' + new Date().toString());

  if (d.error)
  {
    $('#i_error_message').text(d.error);
    alert(d.error);
    return;
  }

  if (g_since_id) {
    for (var i = 0; i < d.length; i++) {
      if (d[i].id <= g_since_id)
        d.splice(i--, 1);
    }
  }

  var NEWEST_TWEET_INDEX = 0;
  g_since_id = d[NEWEST_TWEET_INDEX].id;

  show_tweets(d, $("#column_home"));
  return;
}

// Main  {{{1

$(document).ready(function(){
  // Misc.
  initialize_parameters();
  $('#column_home').empty();
  $('#i_error_message').empty();
  $('#tweet_box').val('');

  // To post.
    // Add a secret iframe to hide interaction with Twitter.
  var node_iframe = create_element('iframe');
  node_iframe.attr('id', 'post_iframe');
  node_iframe.attr('name', 'xpost');
  node_iframe.attr('src', 'about:blank');
  node_iframe.css('display', 'none');
  $('body').append(node_iframe);
  $('#post_form').attr('target', 'xpost');
    // Event handlers.
  $('#post_form').submit(before_post);
  $('#post_iframe').load(after_post);
  $('#tweet_box').keyup(count_tweet_content);
  $('#tweet_box').focus(function(){
                          $('#tweet_content_counter').css('display', 'inline');
                        });
  $('#tweet_box').blur(function(){
                         $('#tweet_content_counter').css('display', 'none');
                       });
  $('#tweet_box').blur();

  // To update.
  if (g_parameters['automatic_update']) {
    g_update_timer = setInterval(update, UPDATE_INTERVAL);
    update();
  }
});

// __END__  {{{1
// vim: expandtab shiftwidth=2 softtabstop=2
// vim: foldmethod=marker
<commit_msg>Use @class instead of @id to record tweet id<commit_after>// Core of fnfnen.
// Variables  {{{1

var DUMMY_SINCE_ID = 1;
var MAX_COUNT = 200;
var MAX_TWEET_CONTENT = 140;
var TWITTER_API_URI = 'http://api.twitter.com/1/';
var TWITTER_UI_URI = 'http://twitter.com/';
var UPDATE_INTERVAL = 5 * 60 * 1000;  // in milliseconds

var g_parameters = {'automatic_update': true};
var g_since_id = null;
var g_tweet_id_to_reply = null;
var g_update_timer = null;
var g_user = null;

// Code  {{{1
function after_post()  //{{{2
{
  $('#tweet_box').val('');

  g_tweet_id_to_reply = null;
  $('#in_reply_to_status_id').remove();

  return;
}

function authenticate()  //{{{2
{
  call_twitter_api(TWITTER_UI_URI,
                   'account/verify_credentials',
                   {'callback': 'callback_authenticate'});
  return;
}

function callback_authenticate(d)
{
  if (d.error)
    return alert(d.error);

  g_user = d;

  update();
  return;
}

function before_post()  //{{{2
{
  // Update timeline manually.
  if ($('#tweet_box').val() == '') {
    update();
    return false;
  }

  if (g_tweet_id_to_reply) {
    var node_reply_id = create_element('input');
    node_reply_id.attr('id', 'in_reply_to_status_id');
    node_reply_id.attr('name', 'in_reply_to_status_id');
    node_reply_id.attr('type', 'hidden');
    node_reply_id.val(g_tweet_id_to_reply);
    $('#post_form').append(node_reply_id);
  }

  // FIXME: Disable or warn too long tweet.
  return true;
}

call_twitter_api = (function(){  //{{{2
  var s_seq = (new Date).getTime();  // To avoid browser-side caching.
  var s_lcds_nodes = {};  // {api_name: node_script, ...}

  return function(base_uri, api_name, _parameters) {
    parameters = $.extend(false, _parameters, {'seq': s_seq++});

    var ps = [];
    for (var key in parameters)
      ps.push(key + '=' + parameters[key]);

    s_lcds_nodes[api_name] = load_cross_domain_script(
      base_uri + api_name + '.json' + '?' + ps.join('&'),
      s_lcds_nodes[api_name]
   );
  }
})();

function count_tweet_content(e)  //{{{2
{
  var remain = MAX_TWEET_CONTENT - $('#tweet_box').val().length;

  $('#tweet_content_counter').text(remain);

  $('#tweet_content_counter').removeClass();
  if (remain < 0)
    $('#tweet_content_counter').addClass('much-content');
  else if (remain == 0)
    $('#tweet_content_counter').addClass('full-content');
  else if (remain < MAX_TWEET_CONTENT)
    $('#tweet_content_counter').addClass('some-content');
  else if (remain == MAX_TWEET_CONTENT)
    $('#tweet_content_counter').addClass('no-content');
  else
    ;

  return true;
}

function create_element(element_name)  //{{{2
{
  return $(document.createElement(element_name));
}

function favorite_symbol(favorite_p)  //{{{2
{
  return (favorite_p
          ? '★'  // black (filled) star
          : '☆'  // white (empty) star
          );
}

function html_from_tweet(tweet)  //{{{2
{
  // FIXME: Add a button to retweet a tweet.
  // FIXME: Expand abbreviated URIs in a tweet.
  // FIXME: Make links for hashtags in a tweet.
  return (''
          /* user icon */
          + ''
          + ''
          + ''
          /* screen name */
          + ''
          + tweet.user.screen_name
          + ''
          /* text */
          + ''
          + make_links_in_text(tweet.text)
          + ''
          /* posted time */
          + ''
          + human_readable_format_from_date(new Date(tweet.created_at))
          + ''
          /* button to reply */
          + ''
          + '↵'  // Carriage return symbol
          + ''
          /* button to show the conversation */
          + (tweet.in_reply_to_status_id
             ? (''
                + ''
                + '♻'  // Black universal recycling symbol
                + '')
             : '')
          /* button to toggle favorite */
          + ''
          + favorite_symbol(tweet.favorited)
          + ''
         );
}

function human_readable_format_from_date(date)  //{{{2
{
  return (date.getFullYear()
          + '-' + pad(date.getMonth() + 1)
          + '-' + pad(date.getDate())
          + ' ' + pad(date.getHours())
          + ':' + pad(date.getMinutes())
          + ':' + pad(date.getSeconds()));
}

function pad(n)
{
  return n < 10 ? '0' + n : n;
}

function initialize_parameters()  //{{{2
{
  var ss = window.location.href.split('?', 2);
  var parameters = (ss[1] ? ss[1] : '').split('&');
  parameters = ((1 <= parameters.length) && (parameters[0] != '')
                ? parameters
                : []);

  for (var i in parameters) {
    var key_value = parameters[i].split('=', 2);
    var key = decodeURIComponent(key_value[0]);
    var value = eval(decodeURIComponent(key_value[1]));  // FIXME: eval?

    g_parameters[key] = value;
  }
  return;
}

function load_cross_domain_script(uri, node)  //{{{2
{
  if (node && node.parentNode)
    node.parentNode.removeChild(node);

  node = document.createElement("script");
  node.src = uri;
  node.type = "text/javascript";
  document.body.appendChild(node);

  return node;
}

function make_links_in_text(text)  //{{{2
{
  // FIXME: Regular expression for URI.
  return text.replace(
    /https?:\/\/[\w!#$%&'*+,.\/:;=?@~-]+|@(\w+)/g,
    function(matched_string, screen_name){
      if (screen_name) {
        return (''
                + matched_string
                + '');
      } else {
        return (''
                + matched_string
                + '');
      }
    }
  );
}

function scroll(y_coordinate)  //{{{2
{
  scrollTo(0, y_coordinate);
  return;
}

function set_up_to_reply(screen_name, tweet_id)  //{{{2
{
  var active_column = $('#column_home');  // FIXME: Use the active column.

  g_tweet_id_to_reply = tweet_id;
  $('#tweet_box').val('@' + screen_name + ' ' + $('#tweet_box').val());
  $('#tweet_box').focus();

  scroll(active_column.attr('scrollHeight'));
  return;
}

function show_conversation(tweet_id)  //{{{2
{
  // FIXME: NIY
  return;
}

function show_tweets(d, node_column)  //{{{2
{
  // d = [{newest-tweet}, ..., {oldest-tweet}]
  if (d.length == 0)
    return 0;

  var node_tweet_hub = create_element('div');
  var node_dummy_tweet = create_element('div');

  node_tweet_hub.append(node_dummy_tweet);
  node_tweet_hub.addClass('tweet-hub');

  for (var i in d) {
    var node_tweet = create_element('div');
    node_tweet.data('json', d[i]);
    node_tweet.html(html_from_tweet(d[i]));

    node_tweet.addClass('tweet');
    node_tweet.addClass('tweet_id_' + d[i].id);
    if (tweet_mention_p(d[i]))
      node_tweet.addClass('mention');
    if (tweet_mine_p(d[i]))
      node_tweet.addClass('mine');
    // FIXME: node_tweet.addClass('censored censored-{kind}');

    node_tweet_hub.prepend(node_tweet);
  }

  node_dummy_tweet.remove();

  node_column.append(node_tweet_hub);

  // Scroll to the head of the latest tweet hub.
  // FIXME: Customize behavior on this autoscroll.
  scroll(node_column.attr('scrollHeight')
         - node_tweet_hub.attr('scrollHeight'));
  return d.length;
}

function toggle_favorite(tweet)  //{{{2
{
  // FIXME: NIY
  alert(tweet);
  return;
}

function tweet_mention_p(tweet)  //{{{2
{
  return tweet.text.match(new RegExp('@' + g_user.screen_name + '\\b', 'i'));
}

function tweet_mine_p(tweet)  //{{{2
{
  return tweet.user.id == g_user.id;
}

function update()  //{{{2
{
  if (!g_user)
    return authenticate();

  call_twitter_api(TWITTER_API_URI,
                   'statuses/home_timeline',
                   {'callback': 'callback_update',
                    'count': MAX_COUNT,
                    'since_id': g_since_id || DUMMY_SINCE_ID});
  return;
}

function callback_update(d)
{
  $('#i_last_updated_time').text('Last updated: ' + new Date().toString());

  if (d.error)
  {
    $('#i_error_message').text(d.error);
    alert(d.error);
    return;
  }

  if (g_since_id) {
    for (var i = 0; i < d.length; i++) {
      if (d[i].id <= g_since_id)
        d.splice(i--, 1);
    }
  }

  var NEWEST_TWEET_INDEX = 0;
  g_since_id = d[NEWEST_TWEET_INDEX].id;

  show_tweets(d, $("#column_home"));
  return;
}

// Main  {{{1

$(document).ready(function(){
  // Misc.
  initialize_parameters();
  $('#column_home').empty();
  $('#i_error_message').empty();
  $('#tweet_box').val('');

  // To post.
    // Add a secret iframe to hide interaction with Twitter.
  var node_iframe = create_element('iframe');
  node_iframe.attr('id', 'post_iframe');
  node_iframe.attr('name', 'xpost');
  node_iframe.attr('src', 'about:blank');
  node_iframe.css('display', 'none');
  $('body').append(node_iframe);
  $('#post_form').attr('target', 'xpost');
    // Event handlers.
  $('#post_form').submit(before_post);
  $('#post_iframe').load(after_post);
  $('#tweet_box').keyup(count_tweet_content);
  $('#tweet_box').focus(function(){
                          $('#tweet_content_counter').css('display', 'inline');
                        });
  $('#tweet_box').blur(function(){
                         $('#tweet_content_counter').css('display', 'none');
                       });
  $('#tweet_box').blur();

  // To update.
  if (g_parameters['automatic_update']) {
    g_update_timer = setInterval(update, UPDATE_INTERVAL);
    update();
  }
});

// __END__  {{{1
// vim: expandtab shiftwidth=2 softtabstop=2
// vim: foldmethod=marker
<|endoftext|>


<commit_before>// used tutorial here: http://www.w3schools.com/howto/howto_js_dropdown.asp

// when the user clicks the button for the dropdown menu to appear/disappear
function dropit(){
  document.getElementById("dropOptions").classList.toggle("show");
}

// close the dropdown menu if the user clicks outside it
window.onclick = function(e){
  if(!e.target.matches('.dropdownButton')){
    var items = document.getElementsByClassName("dropdown-content");
    for(i=0;i<items.length;i++){
      var openDropdown = items[i];
      if(openDropdown.classList.contains('show')){
        openDropdown.classList.remove('show');
      }
    }
  }
}
<commit_msg>languageSelect<commit_after>// used tutorial here: http://www.w3schools.com/howto/howto_js_dropdown.asp

// when the user clicks the button for the dropdown menu to appear/disappear
function dropit(){
  document.getElementById("dropOptions").classList.toggle("show");
}

// close the dropdown menu if the user clicks outside it
window.onclick = function(e){
  if(!e.target.matches('.dropdownButton')){
    var items = document.getElementsByClassName("dropdown-content");
    for(i=0;i<items.length;i++){
      var openDropdown = items[i];
      if(openDropdown.classList.contains('show')){
        openDropdown.classList.remove('show');
      }
    }
  }
}

// when the user selects an option from the dropdown menu
function languageSelect(l){
  document.getElementById('dropButton').innerHTML = l; // set the button text to the selected option
}
<|endoftext|>


<commit_before><commit_msg>remove empty file<commit_after><|endoftext|>


<commit_before>var map = new UFOs(document);
var years = {};
var year;
var selector = document.getElementById("labelheader");
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];

var index = -1;

var last_added = 0;
$.getJSON("used_data/years.json",function(data){
    years = data;
    setTimeout(update,3000);
});
function update(){
  index++;
  if(index > years.length -1){
    index = 0;
  }
  year = years[index];
  selector.innerHTML = "UFO sightings in "+months[parseInt(year.slice(-4).substring(0,2))]+ " "+year.slice(-2)+", " + year.substring(0,4);

  $.getJSON("used_data/"+year+".json",function(data){
      var tdata;
      for(var i = 0; i < data.length; i++)
      {
            tdata = data[i];
            if(tdata != undefined){
              var x = tdata[2];
              var y=  tdata[3];
              var xi = x, yi = y;
              //console.log(x);
              y +=81.5;
              y/=-145.68+81.5;
              x-=26.45;
              x/=60.55-28.5;
              if(x < 1 && x > 0 && y < 1 && y > 0){
                map.addUFOPercent(x,y);
          }
        }
      }

  });
}
$(window).resize(function(){
  map.resize();
});
<commit_msg>Daily is now functioning as it should be<commit_after>var map = new UFOs(document);
var years = {};
var year;
var selector = document.getElementById("labelheader");
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];

var index = -1;

var last_added = 0;
$.getJSON("used_data/years.json",function(data){
    years = data;
    setTimeout(update,3000);
});
function update(){
  index++;
  if(index > years.length -1){
    index = 0;
  }
  year = years[index];
  selector.innerHTML = "UFO sightings in "+months[parseInt(year.slice(-4).substring(0,2))]+ " "+year.slice(-2)+", " + year.substring(0,4);
  last_added++;

  $.getJSON("used_data/"+year+".json",function(data){
      var tdata;
      var added = false;

      for(var i = 0; i < data.length; i++)
      {
            added = true;
            last_added = 0;
            tdata = data[i];
            if(tdata != undefined){
              var x = tdata[2];
              var y=  tdata[3];
              var xi = x, yi = y;
              //console.log(x);
              y +=81.5;
              y/=-145.68+81.5;
              x-=26.45;
              x/=60.55-28.5;
              if(x < 1 && x > 0 && y < 1 && y > 0){
                map.addUFOPercent(x,y);
          }
        }
      }

  });
  var time = 500-Math.pow(2,last_added);
  if(time < 100){
    time = 50;
  }
  setTimeout(update,time);
}
$(window).resize(function(){
  map.resize();
});
<|endoftext|>


<commit_before>/**
 * Imports
 */

import {Button, Modal, ModalHeader, ModalFooter, ModalBody} from 'vdux-containers'
import WinGraphic from 'components/WinGraphic'
import {component, element} from 'vdux'
import {Block, Text, Icon} from 'vdux-ui'

/**
 * <Modal Message/>
 */

export default component({
  render ({props, context, children}) {
    const {closeModal} = context
    const {
      header,
      headerColor = 'blue',
      noFooter,
      body,
      fullscreen,
      footer,
      type,
      dismiss = closeModal,
      onSubmit = () => {},
      ...restProps
    } = props

    const fullScreenProps = {
      w: '100%',
      h: '100%',
      m: '0',
      top: '0',
      pt: props.headerBg ? 0 : 40
    }

    const headerBg = props.headerBg || 'transparent'

    const displayProps = fullscreen
      ? {...fullScreenProps, ...restProps}
      : restProps

    return (
      <Modal
        overlayProps={{fixed: true, top: 0, left: 0}}
        onDismiss={dismiss}
        onKeyup={{esc: dismiss}}
        {...displayProps}>
        <ModalHeader
          background={headerBg}
          column
          align='center center'
          color={type === 'error' ? 'error' : headerColor}
          p='l'
          mb='s'
          fs='l'>
          {
            type === 'win' && <WinGraphic />
          }
          <Block>{header}</Block>
        </ModalHeader>
        <ModalBody flex bgColor={props.bgColor || 'white'} pb='l'>
          <Text fontWeight='300' fs='m' fontFamily='ornate' color='#333'>{body}</Text>
        </ModalBody>
        {!noFooter && (
          <ModalFooter bgColor='#666' p='12px'>
            {footer || <Button fs='s' px='l' py='s' bgColor={type === 'error' ? 'error' : 'blue'} onClick={[dismiss, closeModal]}>OK</Button>}
          </ModalFooter>
        )}
        {children}
        {
          fullscreen &&
            <Button absolute top right m='16' fs='xl' color='#999' hoverProps={{color: '#666'}} onClick={[dismiss, onSubmit]} icon='close'/>
        }
      </Modal>
    )
  }
})
<commit_msg>small modal message style mistake fix<commit_after>/**
 * Imports
 */

import {Button, Modal, ModalHeader, ModalFooter, ModalBody} from 'vdux-containers'
import WinGraphic from 'components/WinGraphic'
import {component, element} from 'vdux'
import {Block, Text, Icon} from 'vdux-ui'

/**
 * <Modal Message/>
 */

export default component({
  render ({props, context, children}) {
    const {closeModal} = context
    const {
      header,
      headerColor = 'blue',
      noFooter,
      body,
      fullscreen,
      footer,
      type,
      dismiss = closeModal,
      onSubmit = () => {},
      ...restProps
    } = props

    const fullScreenProps = {
      w: '100%',
      h: '100%',
      m: '0',
      top: '0',
      pt: props.headerBg ? 0 : 40
    }

    const headerBg = props.headerBg || 'transparent'

    const displayProps = fullscreen
      ? {...fullScreenProps, ...restProps}
      : restProps

    return (
      <Modal
        overlayProps={{fixed: true, top: 0, left: 0}}
        onDismiss={dismiss}
        onKeyup={{esc: dismiss}}
        {...displayProps}>
        <ModalHeader
          background={headerBg}
          column
          align='center center'
          color={type === 'error' ? 'error' : headerColor}
          p='l'
          mb='s'
          fs='l'>
          {
            type === 'win' && <WinGraphic />
          }
          <Block>{header}</Block>
        </ModalHeader>
        <ModalBody flex bgColor={props.bgColor || 'white'}>
          <Text fontWeight='300' fs='m' fontFamily='ornate' color='#333'>{body}</Text>
        </ModalBody>
        {!noFooter && (
          <ModalFooter bgColor='#666' p='12px' mt='l'>
            {footer || <Button fs='s' px='l' py='s' bgColor={type === 'error' ? 'error' : 'blue'} onClick={[dismiss, closeModal]}>OK</Button>}
          </ModalFooter>
        )}
        {children}
        {
          fullscreen &&
            <Button absolute top right m='16' fs='xl' color='#999' hoverProps={{color: '#666'}} onClick={[dismiss, onSubmit]} icon='close'/>
        }
      </Modal>
    )
  }
})
<|endoftext|>


<commit_before>'use strict';
/*eslint-disable no-undef*/
var visitors = require('./vendor/fbtransform/visitors');
var transform = require('jstransform').transform;
var typesSyntax = require('jstransform/visitors/type-syntax');
var Buffer = require('buffer').Buffer;

module.exports = {
  transform: function(input, options) {
    var output = innerTransform(input, options);
    var result = output.code;
    if (options && options.sourceMap) {
      var map = inlineSourceMap(
        output.sourceMap,
        input,
        options.sourceFilename
      );
      result += '\n' + map;
    }
    return result;
  },
  transformWithDetails: function(input, options) {
    var output = innerTransform(input, options);
    var result = {};
    result.code = output.code;
    if (options && options.sourceMap) {
      result.sourceMap = output.sourceMap.toJSON();
    }
    return result;
  }
};

function innerTransform(input, options) {
  options = options || {};

  var visitorSets = ['react'];
  if (options.harmony) {
    visitorSets.push('harmony');
  }
  if (options.stripTypes) {
    // Stripping types needs to happen before the other transforms
    // unfortunately, due to bad interactions. For example,
    // es6-rest-param-visitors conflict with stripping rest param type
    // annotation
    input = transform(typesSyntax.visitorList, input, options).code;
  }

  var visitorList = visitors.getVisitorsBySet(visitorSets);
  return transform(visitorList, input, options);
}

function inlineSourceMap(sourceMap, sourceCode, sourceFilename) {
  var json = sourceMap.toJSON();
  json.sources = [sourceFilename];
  json.sourcesContent = [sourceCode];
  var base64 = Buffer(JSON.stringify(json)).toString('base64');
  return '//# sourceMappingURL=data:application/json;base64,' +
         base64;
}
<commit_msg>fix sourcemap filenames when using transformWithDetails. Fixes #3140<commit_after>'use strict';
/*eslint-disable no-undef*/
var visitors = require('./vendor/fbtransform/visitors');
var transform = require('jstransform').transform;
var typesSyntax = require('jstransform/visitors/type-syntax');
var Buffer = require('buffer').Buffer;

module.exports = {
  transform: function(input, options) {
    var output = innerTransform(input, options);
    var result = output.code;
    if (options && options.sourceMap) {
      var map = inlineSourceMap(
        output.sourceMap,
        input,
        options.sourceFilename
      );
      result += '\n' + map;
    }
    return result;
  },
  transformWithDetails: function(input, options) {
    var output = innerTransform(input, options);
    var result = {};
    result.code = output.code;
    if (options && options.sourceMap) {
      result.sourceMap = output.sourceMap.toJSON();
    }
    if (options && options.sourceFilename) {
      result.sourceMap.sources = [options.sourceFilename];
    }
    return result;
  }
};

function innerTransform(input, options) {
  options = options || {};

  var visitorSets = ['react'];
  if (options.harmony) {
    visitorSets.push('harmony');
  }
  if (options.stripTypes) {
    // Stripping types needs to happen before the other transforms
    // unfortunately, due to bad interactions. For example,
    // es6-rest-param-visitors conflict with stripping rest param type
    // annotation
    input = transform(typesSyntax.visitorList, input, options).code;
  }

  var visitorList = visitors.getVisitorsBySet(visitorSets);
  if (options.sourceFilename) {
    options.filename = options.sourceFilename;
  }
  return transform(visitorList, input, options);
}

function inlineSourceMap(sourceMap, sourceCode, sourceFilename) {
  var json = sourceMap.toJSON();
  json.sources = [sourceFilename];
  json.sourcesContent = [sourceCode];
  var base64 = Buffer(JSON.stringify(json)).toString('base64');
  return '//# sourceMappingURL=data:application/json;base64,' +
         base64;
}
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'

import FormNavigationButtons from './form-navigation-buttons'
import { PageHeading, StackedPaneContainer } from './styled'

/**
 * This component handles the flow between screens for new OTP user accounts.
 */
const StackedPaneDisplay = ({ onCancel, paneSequence, title }) => (
  <>
    {title && <PageHeading>{title}</PageHeading>}
    {
      paneSequence.map(({ pane: Pane, props, title }, index) => (
        <StackedPaneContainer key={index}>

{title}

<Pane {...props} />

        </StackedPaneContainer>
      ))
    }

    <FormNavigationButtons
      backButton={{
        onClick: onCancel,
        text: 'Cancel'
      }}
      okayButton={{
        text: 'Save Preferences',
        type: 'submit'
      }}
    />
  </>
)

StackedPaneDisplay.propTypes = {
  onCancel: PropTypes.func.isRequired,
  paneSequence: PropTypes.array.isRequired
}

export default StackedPaneDisplay
<commit_msg>refactor(StackedPaneDisplay): Experiment with Save button on top.<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import { Button } from 'react-bootstrap'

import FormNavigationButtons from './form-navigation-buttons'
import { PageHeading, StackedPaneContainer } from './styled'

/**
 * This component handles the flow between screens for new OTP user accounts.
 */
const StackedPaneDisplay = ({ onCancel, paneSequence, title }) => (
  <>
    {title && (
      <PageHeading>
        <Button bsStyle='primary' className='pull-right' type='submit'>Save</Button>
        {title}
      </PageHeading>
    )}
    {
      paneSequence.map(({ pane: Pane, props, title }, index) => (
        <StackedPaneContainer key={index}>

{title}

<Pane {...props} />

        </StackedPaneContainer>
      ))
    }

    <FormNavigationButtons
      backButton={{
        onClick: onCancel,
        text: 'Cancel'
      }}
      okayButton={{
        text: 'Save',
        type: 'submit'
      }}
    />
  </>
)

StackedPaneDisplay.propTypes = {
  onCancel: PropTypes.func.isRequired,
  paneSequence: PropTypes.array.isRequired
}

export default StackedPaneDisplay
<|endoftext|>


<commit_before>//创建一个命名空间
var Xut = {};

Xut.CoreObject = function(){};

//实现继承
Xut.CoreObject.extend = function(props){
  var init, subObj;

  props = props || {};
  // 使用init创建构造函数
  // 如果没有提供init方法，则取父类的init，如果父类也没有，则用一个空方法代替

  init = props['init'] || props.init || this.prototype['init'] || this.prototype.init || function(){};
  // 使用一个闭包来避免循环引用的问题

  subObj = function(){
    init.apply(this, arguments);
  };

  // 继承父类的原型
  subObj.prototype = Xut.obj.create(this.prototype);
  // 重置构造函数
  subObj.prototype.constructor = subObj;

  // 使得子类也可以被继承
  subObj.extend = Xut.CoreObject.extend;

  // 把props上的属性和方法都加到subObj的原型上去
  for (var name in props) {
    if (props.hasOwnProperty(name)) {
      subObj.prototype[name] = props[name];
    }
  }

  return subObj;
};

/**
 * Object functions container
 * @type {Object}
 * @private
 */
Xut.obj = {};

/**
 * Object.create shim for prototypal inheritance
 *
 * https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create
 *
 * @function
 * @param  {Object}   obj Object to use as prototype
 * @private
 */
Xut.obj.create = Object.create || function(obj){
  //Create a new function called 'F' which is just an empty object.
  function F() {}

  //the prototype of the 'F' function should point to the
  //parameter of the anonymous function.
  F.prototype = obj;

  //create a new constructor function based off of the 'F' function.
  return new F();
};

<commit_msg>modified core.js<commit_after>//创建一个命名空间
var Xut = {};

Xut.CoreObject = function(){};

//实现继承
Xut.CoreObject.extend = function(props){
  var init, subObj;

  props = props || {};
  // 使用init创建构造函数
  // 如果没有提供init方法，则取父类的init，如果父类也没有，则用一个空方法代替

  init = props['init'] || props.init || this.prototype['init'] || this.prototype.init || function(){};
  // 使用一个闭包来避免循环引用的问题

  subObj = function(){
    init.apply(this, arguments);
  };

  // 继承父类的原型
  subObj.prototype = Xut.obj.create(this.prototype);
  // 重置构造函数
  subObj.prototype.constructor = subObj;

  // 使得子类也可以被继承
  subObj.extend = Xut.CoreObject.extend;

  // 把props上的属性和方法都加到subObj的原型上去
  for (var name in props) {
    if (props.hasOwnProperty(name)) {
      //替换父类的同名属性和方法
      subObj.prototype[name] = props[name];
    }
  }

  return subObj;
};

/**
 * Object functions container
 * @type {Object}
 * @private
 */
Xut.obj = {};

/**
 * Object.create shim for prototypal inheritance
 *
 * https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create
 *
 * @function
 * @param  {Object}   obj Object to use as prototype
 * @private
 */
Xut.obj.create = Object.create || function(obj){
  //Create a new function called 'F' which is just an empty object.
  function F() {}

  //the prototype of the 'F' function should point to the
  //parameter of the anonymous function.
  F.prototype = obj;

  //create a new constructor function based off of the 'F' function.
  return new F();
};

<|endoftext|>


<commit_before>var wavesurfer = Object.create(WaveSurfer);

wavesurfer.init({
  container: '#waveform',
  waveColor: 'red',
  progressColor: 'purple'
});

wavesurfer.on('ready', function () {
    var spectrogram = Object.create(WaveSurfer.Spectrogram);

    var colorFunc = function(colorValue) {
      if (colorValue < 90) {
        return 'rgb(255, 255, 255)';
      } else if (colorValue < 150) {
        return 'rgb(255, 0, 0)';
      } else if (colorValue < 185) {
        return 'rgb(255, 0, 255)';
      } else {
        return 'rgb(51, 153, 255)';
      }
    }

    spectrogram.init({
        wavesurfer: wavesurfer,
        container: "#wave-spectrogram",
        getFrequencyRGB: colorFunc
    });
});

wavesurfer.load('song.wav');
<commit_msg>switch back to traffic sound<commit_after>var wavesurfer = Object.create(WaveSurfer);

wavesurfer.init({
  container: '#waveform',
  waveColor: 'red',
  progressColor: 'purple'
});

wavesurfer.on('ready', function () {
    var spectrogram = Object.create(WaveSurfer.Spectrogram);

    var colorFunc = function(colorValue) {
      if (colorValue < 90) {
        return 'rgb(255, 255, 255)';
      } else if (colorValue < 150) {
        return 'rgb(255, 0, 0)';
      } else if (colorValue < 185) {
        return 'rgb(255, 0, 255)';
      } else {
        return 'rgb(51, 153, 255)';
      }
    }

    spectrogram.init({
        wavesurfer: wavesurfer,
        container: "#wave-spectrogram",
        getFrequencyRGB: colorFunc
    });
});

wavesurfer.load('traffic.wav');
<|endoftext|>


<commit_before>
var Promise = require('bluebird').Promise;
var _ = require('./../../core/underscore.js');
var SearchSupport = require('./../../core/search/search-support.js');
var TemplateCriteria = require('./domain/template-criteria.js');

module.exports = Templates;

/**
 * The service that works with template
 *
 * @param rest the REST client
 * @constructor
 */
function Templates (dataCenterService, serverClient) {
    var self = this;

    function init () {
        SearchSupport.call(self);
    }

    /**
     * Search template
     * @param {TemplateSearchCriteria} criteria
     *
     * @memberof Templates
     */
    self.find = function () {
        var criteria = self._searchCriteriaFrom(arguments);

        //TODO maybe obsolete?
        if (criteria.dataCenterIds) {
            return findByDataCenterIds(criteria);
        }

        return dataCenterService.find(TemplateCriteria.extractDataCenterCriteria(criteria))
            //filter by data center
            .then(function(dataCenters) {
                return findByDataCenterIds({
                    dataCenters: _.asArray(dataCenters)
                });
            })
            .then(function(templates) {
                if (!templates || templates.length === 0) {
                    return [];
                }
                return _.filter(templates, new TemplateCriteria(criteria).predicate().fn);
            });
    };

    function findByDataCenterIds(criteria) {
        var dataCenters = criteria.dataCenters || [];
        if (criteria.dataCenterIds) {
            _.each(_.asArray(criteria.dataCenterIds), function(dataCenterId) {
                dataCenters.push({id: dataCenterId});
            });
        }
        return _.chain([dataCenters])
            .flatten()
            .map(function (dataCenter) {
                return Promise.props({
                    dataCenter: dataCenter,
                    capabilities: dataCenterService.getDeploymentCapabilities(dataCenter.id)
                });
            })
            .arrayPromise()
            .then(function (list) {
                _.each(list, function(res) {
                    _.each(res.capabilities.templates, function(t) {
                        t.dataCenter = res.dataCenter;
                    });
                });
                return _.pluck(_.pluck(list, 'capabilities'), 'templates');
            })
            .then(_.flatten)
            .value();
    }

    self.findAvailableServerImports = function () {
        return dataCenterService
            .findSingle(self._searchCriteriaFrom(arguments))
            .then(_.property('id'))
            .then(serverClient.findAvailableServerImports);
    };

    self._dataCenterService = function() {
        return dataCenterService;
    };

    init ();
}
<commit_msg> #65 Design, Development and Prototyping of SDK architecture<commit_after>
var Promise = require('bluebird').Promise;
var _ = require('./../../core/underscore.js');
var SearchSupport = require('./../../core/search/search-support.js');
var TemplateCriteria = require('./domain/template-criteria.js');

module.exports = Templates;

/**
 * The service that works with template
 *
 * @constructor
 */
function Templates (dataCenterService, serverClient) {
    var self = this;

    function init () {
        SearchSupport.call(self);
    }

    /**
     * Search template
     * @param {TemplateSearchCriteria} criteria
     *
     * @memberof Templates
     */
    self.find = function () {
        var criteria = self._searchCriteriaFrom(arguments);

        //TODO maybe obsolete?
        if (criteria.dataCenterIds) {
            return findByDataCenterIds(criteria);
        }

        return dataCenterService.find(TemplateCriteria.extractDataCenterCriteria(criteria))
            //filter by data center
            .then(function(dataCenters) {
                return findByDataCenterIds({
                    dataCenters: _.asArray(dataCenters)
                });
            })
            .then(function(templates) {
                if (!templates || templates.length === 0) {
                    return [];
                }
                return _.filter(templates, new TemplateCriteria(criteria).predicate().fn);
            });
    };

    function findByDataCenterIds(criteria) {
        var dataCenters = criteria.dataCenters || [];
        if (criteria.dataCenterIds) {
            _.each(_.asArray(criteria.dataCenterIds), function(dataCenterId) {
                dataCenters.push({id: dataCenterId});
            });
        }
        return _.chain([dataCenters])
            .flatten()
            .map(function (dataCenter) {
                return Promise.props({
                    dataCenter: dataCenter,
                    capabilities: dataCenterService.getDeploymentCapabilities(dataCenter.id)
                });
            })
            .arrayPromise()
            .then(function (list) {
                _.each(list, function(res) {
                    _.each(res.capabilities.templates, function(t) {
                        t.dataCenter = res.dataCenter;
                    });
                });
                return _.pluck(_.pluck(list, 'capabilities'), 'templates');
            })
            .then(_.flatten)
            .value();
    }

    self.findAvailableServerImports = function () {
        return dataCenterService
            .findSingle(self._searchCriteriaFrom(arguments))
            .then(_.property('id'))
            .then(serverClient.findAvailableServerImports);
    };

    self._dataCenterService = function() {
        return dataCenterService;
    };

    init ();
}
<|endoftext|>


<commit_before>"use strinct";

var request = require("request");
var N3 = require("n3");

var geolod = new Promise(function(resolve, reject) {
  var query = [
    "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
    "PREFIX geonlp: <http://geonlp.org/ontology/1.0#>",
    "SELECT DISTINCT ?s ?o WHERE { ?s rdfs:seeAlso ?o ; geonlp:code ?code }"
  ];
  request.get({
    url: 'http://geolod.ex.nii.ac.jp/sparql?output=json&query=' + encodeURIComponent(query.join(" ")),
    json: true
  }, function(error, response, json) {
    var map = {};
    json.results.bindings.forEach(function(a) {
      var key = a.o.value;
      var val = a.s.value;
      map[key] = val;
    });
    resolve(map);
  });
});

var dbpedia = new Promise(function(resolve, reject) {
  request.get({
    url: 'http://raw.githubusercontent.com/indigo-lab/geonamesjp_vs_dbpedia/master/2015-07-17.ttl'
  }, function(error, response, txt) {
    var map = {};
    N3.Parser().parse(txt, function(error, triple, prefixes) {
      if (triple && triple.predicate == "http://www.w3.org/2002/07/owl#sameAs") {
        var key = triple.object;
        var val = triple.subject;
        map[key] = val;
      }
      resolve(map);
    });
  });
});

Promise.all([geolod, dbpedia]).then(function(a) {
  var dbpedia2geolod = a[0];
  var dbpedia2gnjp = a[1];

  for (var dbpedia in dbpedia2geolod) {
    var gnjp = dbpedia2gnjp[dbpedia];
    var geolod = dbpedia2geolod[dbpedia];
    if (gnjp)
      console.log("<" + gnjp + "> <http://www.w3.org/2002/07/owl#sameAs> <" + geolod + "> .");
  }

  for (var dbpedia in dbpedia2gnjp) {
    var gnjp = dbpedia2gnjp[dbpedia];
    var geolod = dbpedia2geolod[dbpedia];
    if (!geolod)
      console.error("<" + gnjp + "> <http://www.w3.org/2002/07/owl#sameAs> <" + dbpedia + "> .");
  }

});
<commit_msg>Change linkset predicate<commit_after>"use strinct";

var request = require("request");
var N3 = require("n3");

var geolod = new Promise(function(resolve, reject) {
  var query = [
    "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>",
    "PREFIX geonlp: <http://geonlp.org/ontology/1.0#>",
    "SELECT DISTINCT ?s ?o WHERE { ?s rdfs:seeAlso ?o ; geonlp:code ?code }"
  ];
  request.get({
    url: 'http://geolod.ex.nii.ac.jp/sparql?output=json&query=' + encodeURIComponent(query.join(" ")),
    json: true
  }, function(error, response, json) {
    var map = {};
    json.results.bindings.forEach(function(a) {
      var key = a.o.value;
      var val = a.s.value;
      map[key] = val;
    });
    resolve(map);
  });
});

var dbpedia = new Promise(function(resolve, reject) {
  request.get({
    url: 'http://raw.githubusercontent.com/indigo-lab/geonamesjp_vs_dbpedia/master/2015-07-17.ttl'
  }, function(error, response, txt) {
    var map = {};
    N3.Parser().parse(txt, function(error, triple, prefixes) {
      if (triple && triple.predicate == "http://www.w3.org/2002/07/owl#sameAs") {
        var key = triple.object;
        var val = triple.subject;
        map[key] = val;
      }
      resolve(map);
    });
  });
});

Promise.all([geolod, dbpedia]).then(function(a) {
  var dbpedia2geolod = a[0];
  var dbpedia2gnjp = a[1];

  for (var dbpedia in dbpedia2geolod) {
    var gnjp = dbpedia2gnjp[dbpedia];
    var geolod = dbpedia2geolod[dbpedia];
    if (gnjp)
      console.log("<" + gnjp + "> <https://www.w3.org/2000/01/rdf-schema#seeAlso> <" + geolod + "> .");
  }

  for (var dbpedia in dbpedia2gnjp) {
    var gnjp = dbpedia2gnjp[dbpedia];
    var geolod = dbpedia2geolod[dbpedia];
    if (!geolod)
      console.error("<" + gnjp + "> <http://www.w3.org/2002/07/owl#sameAs> <" + dbpedia + "> .");
  }

});
<|endoftext|>


<commit_before>var TeamCityFormatter = function(options) {
  var util = require('util');
  var Cucumber = require('../../cucumber');
  var _ = require('underscore');
  if (!options) {
    options = {};
  }
  var TEST_IGNORED = '##teamcity[testIgnored name=\'%s\' message=\'PENDING\']';
  var SUITE_START    = '##teamcity[testSuiteStarted name=\'%s\']';
  var SUITE_END       = '##teamcity[testSuiteFinished name=\'%s\']';
  var TEST_START     = '##teamcity[testStarted name=\'%s\']';
  var TEST_FAILED    = '##teamcity[testFailed name=\'%s\' message=\'FAILED\']';
  var TEST_END        = '##teamcity[testFinished name=\'%s\' duration=\'%s\']';

  var self = Cucumber.Listener.Formatter(options);
  var summaryFormatter = Cucumber.Listener.SummaryFormatter({
    coffeeScriptSnippets: options.coffeeScriptSnippets,
    logToConsole: true
  });

  var parentHear = self.hear;
  self.hear = function hear(event, callback) {
    summaryFormatter.hear(event, function () {
      parentHear(event, callback);
    });
  };

  var featureNames = [];

  self.handleBeforeStepEvent = function handleBeforeStepEvent(event, callback) {
    callback();
  };

  self.handleAfterStepEvent = function handleAfterStepEvent(event, callback) {
    callback();
  };

  self.handleBeforeFeatureEvent = function handleBeforeFeatureEvent(event, callback) {
    var feature = event.getPayloadItem('feature');
    featureNames.push(feature.getName());
    self.log(formatString(SUITE_START, feature.getName()));
    callback();
  };

  self.handleAfterFeatureEvent = function handleAfterFeaturesEvent(event, callback) {
    var featureName = featureNames.pop();
    self.log(formatString(SUITE_END, featureName));
    callback();
  };

  self.handleBeforeScenarioEvent = function handleBeforeScenarioEvent(event, callback) {
    var scenario = event.getPayloadItem('scenario');
    self.log(formatString(TEST_START, 'Scenario: ' + scenario.getName()));
    callback();
  };

  self.handleAfterScenarioEvent = function handleAfterScenarioEvent(event, callback) {
    var scenario = event.getPayloadItem('scenario');
    self.log(formatString(TEST_END, 'Scenario: ' + scenario.getName()));
    callback();
  };

  self.handleStepResultEvent = function handleStepResult(event, callback) {
    var stepResult = event.getPayloadItem('stepResult');
    var step = stepResult.getStep();
    var stepName = step.getKeyword() + step.getName();
    if (stepResult.isSuccessful()) {
      /*jshint noempty:false*/
      // Do nothing - ending the test without an error indicates success.
    }
    else if (stepResult.isPending()) {
      self.log(formatString(TEST_IGNORED, step.getName()));
    }
    else if (stepResult.isSkipped()) {
      self.log(formatString(TEST_IGNORED, stepName));
    }
    else if (stepResult.isUndefined()) {
      self.log(formatString(TEST_FAILED, stepName));
    }
    else {
      var failure = stepResult.getFailureException();
      var failureDescription = failure.stack || failure;
      // fix selenium-webdriver error message
      failureDescription = failureDescription.replace(/\n*\s*at <anonymous>/g,'');
      failedTestMessage = '##teamcity[testFailed name=\'%s\' message=\'FAILED: '+ failureDescription +'\']';
      self.log(formatString(failedTestMessage, stepName));
    }
    callback();
  };

  function formatString() {
    var formattedArguments = [];
    var args = Array.prototype.slice.call(arguments, 0);
    // Format all arguments for TC display (it escapes using the pipe char).
    var tcCommand = args.shift();
    _.each(args, function(param) {
      formattedArguments.push(param.replace('\'', '|\''));
    });
    formattedArguments.unshift(tcCommand);
    return util.format.apply(util, formattedArguments) + '\n';
  }

  return self;
};
module.exports = TeamCityFormatter;<commit_msg>update teamcity formatter<commit_after>var TeamCityFormatter = function(options) {
  var util = require('util');
  var Cucumber = require('../../cucumber');
  var _ = require('underscore');
  if (!options) {
    options = {};
  }
  var TEST_IGNORED = '##teamcity[testIgnored name=\'%s\' message=\'PENDING\']';
  var SUITE_START    = '##teamcity[testSuiteStarted name=\'%s\']';
  var SUITE_END       = '##teamcity[testSuiteFinished name=\'%s\']';
  var TEST_START     = '##teamcity[testStarted name=\'%s\']';
  var TEST_FAILED    = '##teamcity[testFailed name=\'%s\' message=\'FAILED\']';
  var TEST_END        = '##teamcity[testFinished name=\'%s\' duration=\'%s\']';

  var self = Cucumber.Listener.Formatter(options);
  var summaryFormatter = Cucumber.Listener.SummaryFormatter({
    coffeeScriptSnippets: options.coffeeScriptSnippets,
    logToConsole: true
  });

  var parentHear = self.hear;
  self.hear = function hear(event, callback) {
    summaryFormatter.hear(event, function () {
      parentHear(event, callback);
    });
  };

  var featureNames = [];

  self.handleBeforeStepEvent = function handleBeforeStepEvent(event, callback) {
    callback();
  };

  self.handleAfterStepEvent = function handleAfterStepEvent(event, callback) {
    callback();
  };

  self.handleBeforeFeatureEvent = function handleBeforeFeatureEvent(event, callback) {
    var feature = event.getPayloadItem('feature');
    featureNames.push(feature.getName());
    self.log(formatString(SUITE_START, feature.getName()));
    callback();
  };

  self.handleAfterFeatureEvent = function handleAfterFeaturesEvent(event, callback) {
    var featureName = featureNames.pop();
    self.log(formatString(SUITE_END, featureName));
    callback();
  };

  self.handleBeforeScenarioEvent = function handleBeforeScenarioEvent(event, callback) {
    var scenario = event.getPayloadItem('scenario');
    self.log(formatString(TEST_START, 'Scenario: ' + scenario.getName()));
    callback();
  };

  self.handleAfterScenarioEvent = function handleAfterScenarioEvent(event, callback) {
    var scenario = event.getPayloadItem('scenario');
    self.log(formatString(TEST_END, 'Scenario: ' + scenario.getName()));
    callback();
  };

  self.handleStepResultEvent = function handleStepResult(event, callback) {
    var stepResult = event.getPayloadItem('stepResult');
    var step = stepResult.getStep();
    var stepName = step.getKeyword() + step.getName();
    if (stepResult.isSuccessful()) {
      /*jshint noempty:false*/
      // Do nothing - ending the test without an error indicates success.
    }
    else if (stepResult.isPending()) {
      self.log(formatString(TEST_IGNORED, step.getName()));
    }
    else if (stepResult.isSkipped()) {
      self.log(formatString(TEST_IGNORED, stepName));
    }
    else if (stepResult.isUndefined()) {
      self.log(formatString(TEST_FAILED, stepName));
    }
    else {
      var failure = stepResult.getFailureException();
      var failureDescription = failure.stack || failure;
      // fix selenium-webdriver error message
      failureDescription = failureDescription.replace(/\n*\s*at <anonymous>/g,'');
      failedTestMessage = '##teamcity[testFailed name=\'%s\' message=\'FAILED: '+ failureDescription +'\']';
      self.log(formatString(failedTestMessage, stepName));
    }
    callback();
  };

  function formatString() {
    var formattedArguments = [];
    var args = Array.prototype.slice.call(arguments, 0);
    // Format all arguments for TC display (it escapes using the pipe char).
    var tcCommand = args.shift();
    _.each(args, function(param) {
      formattedArguments.push(escapeTeamcityString(param));
    });
    formattedArguments.unshift(tcCommand);
    return util.format.apply(util, formattedArguments) + '\n';
  }

  function escapeTeamcityString(message) {
    if(!message) {
        return "";
    }

    return message.replace(/\|/g, "||")
                  .replace(/\'/g, "|'")
                  .replace(/\n/g, "|n")
                  .replace(/\r/g, "|r")
                  .replace(/\u0085/g, "|x")
                  .replace(/\u2028/g, "|l")
                  .replace(/\u2029/g, "|p")
                  .replace(/\[/g, "|[")
                  .replace(/]/g, "|]");
  }

  return self;
};
module.exports = TeamCityFormatter;<|endoftext|>


<commit_before>/* eslint-disable no-param-reassign */

import {rollup} from 'rollup';
import {parse} from 'acorn';
import {analyze} from 'escope';
import {generate} from 'escodegen';
import {writeFile} from 'js-utils-fs';
// https://github.com/evanw/emscripten-library-generator/blob/5038b54bb8b5906572b09bc370f4b249776f2a3f/generator.js#L9-L19
function isPureValue(value) {
	return (
		value.type === 'Literal' ||
		value.type === 'ThisExpression' ||
		value.type === 'FunctionExpression' ||
		value.type === 'UnaryExpression' && isPureValue(value.argument) ||
		value.type === 'ArrayExpression' && value.elements.every(isPureValue) ||
		value.type === 'ObjectExpression' && value.properties.every(e => isPureValue(e.value)) ||
		(
			value.type === 'BinaryExpression' || value.type === 'LogicalExpression') &&
			isPureValue(value.left) && isPureValue(value.right
		)
	);
}

class EmscriptenTransform {
	constructor(input, localPrefix = 'unnamed') {
		this._localPrefix = localPrefix;
		this._input = input;
		this._dependencies = {};
		this._exports = {}; // [localName] = exportedName
	}

	_checkNodes() {
		this._input.body.forEach(node => {
			if (node.type === 'VariableDeclaration') {
				node.declarations.forEach(dec => {
					if (dec.init && !isPureValue(dec.init)) {
						const nodeJson = JSON.stringify(dec, undefined, '  ');
						throw new Error(`Unsupported non-pure initializer:\n${nodeJson}`);
					}
				});
			} else if (
				node.type !== 'FunctionDeclaration' &&
				node.type !== 'ExportNamedDeclaration'
			) {
				const nodeJson = JSON.stringify(node, undefined, '  ');
				throw new Error(`Unsupported top-level statement:\n${nodeJson}`);
			}
		});
	}

	_determineAndNormalizeExports() {
		this._input.body = this._input.body
			.map(node => {
				if (node.type !== 'ExportNamedDeclaration') return node;

				if (node.declaration) {
					const {name} = node.declaration.id;
					this._exports[name] = name;
					return node.declaration;
				}

				node.specifiers.forEach(n => {
					this._exports[n.local.name] = n.exported.name;
				});
				return undefined;
			})
			.filter(node => !!node);
	}

	_prefixName(name) {
		return `_${this._localPrefix}_${name}`;
	}

	_prefixLocalAndDetermineDeps() {
		analyze(this._input, {ecmaVersion: 6, sourceType: 'module'}).scopes.forEach(scope => {
			if (scope.type !== 'module') return;

			scope.variables.forEach(v => {
				v.references.forEach(ref => {
					let funcScope = ref.from;
					while (
						funcScope && (
							funcScope.upper.type !== 'module' ||
							funcScope.type !== 'function' ||
							!funcScope.block.id
						)
					) {
						funcScope = funcScope.upper;
					}
					if (funcScope) {
						let funcName = funcScope.block.id.name;
						if (!this._exports[funcName]) {
							funcName = this._prefixName(funcName);
						}
						let depName = v.name;
						if (!this._exports[depName]) {
							depName = this._prefixName(depName);
						}

						if (
							funcName !== depName && (
								!this._dependencies[funcName] ||
								this._dependencies[funcName].indexOf(depName) !== -1
							)
						) {
							this._dependencies[funcName] = this._dependencies[funcName] || [];
							this._dependencies[funcName].push(depName);
						}
					}
				});

				if (!this._exports[v.name]) {
					const newName = this._prefixName(v.name);
					v.identifiers.forEach(id => {
						id.name = newName;
					});
					v.references.forEach(ref => {
						ref.identifier.name = newName;
					});
				} else if (this._exports[v.name] !== v.name) {
					// rename exported symbols from local name to exported name
					const newName = this._exports[v.name];
					v.identifiers.forEach(id => {
						id.name = newName;
					});
					v.references.forEach(ref => {
						ref.identifier.name = newName;
					});
				}
			});
		});
	}

	_transformIntoProperties() {
		const result = [];
		this._input.body.forEach(node => {
			switch (node.type) {
				case 'VariableDeclaration':
					node.declarations.forEach(v => {
						result.push({
							type: 'Property',
							key: {type: 'Identifier', name: v.id.name},
							value: node.init || {type: 'Literal', value: null},
						});
					});
					break;

				case 'FunctionDeclaration':
					result.push({
						type: 'Property',
						key: {type: 'Identifier', name: node.id.name},
						value: {
							type: 'FunctionExpression',
							params: node.params,
							body: node.body,
						},
					});
					break;

				default:
					throw new Error('unreachable');
			}
		});
		this._input.body = result;
	}

	_addDeps() {
		Object.keys(this._dependencies).forEach(name => {
			this._input.body.push({
				type: 'Property',
				key: {type: 'Identifier', name: `${name}__deps`},
				value: {
					type: 'ArrayExpression',
					elements: this._dependencies[name].map(dep => ({type: 'Literal', value: dep})),
				},
			});
		});
	}

	transform() {
		this._checkNodes();
		this._determineAndNormalizeExports();
		this._prefixLocalAndDetermineDeps();
		this._transformIntoProperties();
		this._addDeps();

		const output = parse('Object.assign(LibraryManager.library, {})');
		output.body[0].expression.arguments[1].properties = this._input.body;
		return output;
	}
}

export default function main(options = {}) {
	const localPrefix = options.localPrefix;
	delete options.localPrefix;

	return rollup(options).then(bundle => {
		const {code} = bundle.generate(Object.assign({}, options, {format: 'es'}));
		const ast = parse(code, {sourceType: 'module'});
		const transform = new EmscriptenTransform(ast, localPrefix);
		const outCode = generate(transform.transform());
		return {
			code: outCode,
			write(fileName) {
				return writeFile(fileName, outCode);
			},
		};
	});
}
<commit_msg>fix function scope search<commit_after>/* eslint-disable no-param-reassign */

import {rollup} from 'rollup';
import {parse} from 'acorn';
import {analyze} from 'escope';
import {generate} from 'escodegen';
import {writeFile} from 'js-utils-fs';
// https://github.com/evanw/emscripten-library-generator/blob/5038b54bb8b5906572b09bc370f4b249776f2a3f/generator.js#L9-L19
function isPureValue(value) {
	return (
		value.type === 'Literal' ||
		value.type === 'ThisExpression' ||
		value.type === 'FunctionExpression' ||
		value.type === 'UnaryExpression' && isPureValue(value.argument) ||
		value.type === 'ArrayExpression' && value.elements.every(isPureValue) ||
		value.type === 'ObjectExpression' && value.properties.every(e => isPureValue(e.value)) ||
		(
			value.type === 'BinaryExpression' || value.type === 'LogicalExpression') &&
			isPureValue(value.left) && isPureValue(value.right
		)
	);
}

class EmscriptenTransform {
	constructor(input, localPrefix = 'unnamed') {
		this._localPrefix = localPrefix;
		this._input = input;
		this._dependencies = {};
		this._exports = {}; // [localName] = exportedName
	}

	_checkNodes() {
		this._input.body.forEach(node => {
			if (node.type === 'VariableDeclaration') {
				node.declarations.forEach(dec => {
					if (dec.init && !isPureValue(dec.init)) {
						const nodeJson = JSON.stringify(dec, undefined, '  ');
						throw new Error(`Unsupported non-pure initializer:\n${nodeJson}`);
					}
				});
			} else if (
				node.type !== 'FunctionDeclaration' &&
				node.type !== 'ExportNamedDeclaration'
			) {
				const nodeJson = JSON.stringify(node, undefined, '  ');
				throw new Error(`Unsupported top-level statement:\n${nodeJson}`);
			}
		});
	}

	_determineAndNormalizeExports() {
		this._input.body = this._input.body
			.map(node => {
				if (node.type !== 'ExportNamedDeclaration') return node;

				if (node.declaration) {
					const {name} = node.declaration.id;
					this._exports[name] = name;
					return node.declaration;
				}

				node.specifiers.forEach(n => {
					this._exports[n.local.name] = n.exported.name;
				});
				return undefined;
			})
			.filter(node => !!node);
	}

	_prefixName(name) {
		return `_${this._localPrefix}_${name}`;
	}

	_prefixLocalAndDetermineDeps() {
		analyze(this._input, {ecmaVersion: 6, sourceType: 'module'}).scopes.forEach(scope => {
			if (scope.type !== 'module') return;

			scope.variables.forEach(v => {
				v.references.forEach(ref => {
					let funcScope = ref.from;
					while (
						funcScope.upper && (
							funcScope.upper.type !== 'module' ||
							funcScope.type !== 'function' ||
							!funcScope.block.id
						)
					) {
						funcScope = funcScope.upper;
					}
					if (funcScope.upper) {
						let funcName = funcScope.block.id.name;
						if (!this._exports[funcName]) {
							funcName = this._prefixName(funcName);
						}
						let depName = v.name;
						if (!this._exports[depName]) {
							depName = this._prefixName(depName);
						}

						if (
							funcName !== depName && (
								!this._dependencies[funcName] ||
								this._dependencies[funcName].indexOf(depName) !== -1
							)
						) {
							this._dependencies[funcName] = this._dependencies[funcName] || [];
							this._dependencies[funcName].push(depName);
						}
					}
				});

				if (!this._exports[v.name]) {
					const newName = this._prefixName(v.name);
					v.identifiers.forEach(id => {
						id.name = newName;
					});
					v.references.forEach(ref => {
						ref.identifier.name = newName;
					});
				} else if (this._exports[v.name] !== v.name) {
					// rename exported symbols from local name to exported name
					const newName = this._exports[v.name];
					v.identifiers.forEach(id => {
						id.name = newName;
					});
					v.references.forEach(ref => {
						ref.identifier.name = newName;
					});
				}
			});
		});
	}

	_transformIntoProperties() {
		const result = [];
		this._input.body.forEach(node => {
			switch (node.type) {
				case 'VariableDeclaration':
					node.declarations.forEach(v => {
						result.push({
							type: 'Property',
							key: {type: 'Identifier', name: v.id.name},
							value: node.init || {type: 'Literal', value: null},
						});
					});
					break;

				case 'FunctionDeclaration':
					result.push({
						type: 'Property',
						key: {type: 'Identifier', name: node.id.name},
						value: {
							type: 'FunctionExpression',
							params: node.params,
							body: node.body,
						},
					});
					break;

				default:
					throw new Error('unreachable');
			}
		});
		this._input.body = result;
	}

	_addDeps() {
		Object.keys(this._dependencies).forEach(name => {
			this._input.body.push({
				type: 'Property',
				key: {type: 'Identifier', name: `${name}__deps`},
				value: {
					type: 'ArrayExpression',
					elements: this._dependencies[name].map(dep => ({type: 'Literal', value: dep})),
				},
			});
		});
	}

	transform() {
		this._checkNodes();
		this._determineAndNormalizeExports();
		this._prefixLocalAndDetermineDeps();
		this._transformIntoProperties();
		this._addDeps();

		const output = parse('Object.assign(LibraryManager.library, {})');
		output.body[0].expression.arguments[1].properties = this._input.body;
		return output;
	}
}

export default function main(options = {}) {
	const localPrefix = options.localPrefix;
	delete options.localPrefix;

	return rollup(options).then(bundle => {
		const {code} = bundle.generate(Object.assign({}, options, {format: 'es'}));
		const ast = parse(code, {sourceType: 'module'});
		const transform = new EmscriptenTransform(ast, localPrefix);
		const outCode = generate(transform.transform());
		return {
			code: outCode,
			write(fileName) {
				return writeFile(fileName, outCode);
			},
		};
	});
}
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const NullDependency = require("./NullDependency");
const HarmonyImportDependency = require("./HarmonyImportDependency");

class HarmonyAcceptDependency extends NullDependency {
	constructor(range, dependencies, hasCallback) {
		super();
		this.range = range;
		this.dependencies = dependencies;
		this.hasCallback = hasCallback;
	}

	get type() {
		return "accepted harmony modules";
	}
}

HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate {
	apply(dep, source, runtime) {
		const content = dep.dependencies
			.filter(dependency =>
				HarmonyImportDependency.Template.isImportEmitted(dependency, source)
			)
			.map(dependency => dependency.getImportStatement(true, runtime))
			.join("");

		if (dep.hasCallback) {
			source.insert(
				dep.range[0],
				`function(__WEBPACK_OUTDATED_DEPENDENCIES__) { ${content}(`
			);
			source.insert(dep.range[1], ")(__WEBPACK_OUTDATED_DEPENDENCIES__); }");
			return;
		}

		source.insert(dep.range[1] - 0.5, `, function() { ${content} }`);
	}
};

module.exports = HarmonyAcceptDependency;
<commit_msg>bugfix(harmony-deps) : bind the function to prevent the this keyword to be overriden<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const NullDependency = require("./NullDependency");
const HarmonyImportDependency = require("./HarmonyImportDependency");

class HarmonyAcceptDependency extends NullDependency {
	constructor(range, dependencies, hasCallback) {
		super();
		this.range = range;
		this.dependencies = dependencies;
		this.hasCallback = hasCallback;
	}

	get type() {
		return "accepted harmony modules";
	}
}

HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate {
	apply(dep, source, runtime) {
		const content = dep.dependencies
			.filter(dependency =>
				HarmonyImportDependency.Template.isImportEmitted(dependency, source)
			)
			.map(dependency => dependency.getImportStatement(true, runtime))
			.join("");

		if (dep.hasCallback) {
			source.insert(
				dep.range[0],
				`function(__WEBPACK_OUTDATED_DEPENDENCIES__) { ${content}(`
			);
			source.insert(dep.range[1], ")(__WEBPACK_OUTDATED_DEPENDENCIES__); }.bind(this)");
			return;
		}

		source.insert(dep.range[1] - 0.5, `, function() { ${content} }`);
	}
};

module.exports = HarmonyAcceptDependency;
<|endoftext|>