<commit_before>var http = Npm.require('http');
var hostname = Npm.require('os').hostname();
var logger = Npm.require('debug')('kadira:apm');
var Fibers = Npm.require('fibers');

Kadira.models = {};
Kadira.options = {};
Kadira.env = {
  currentSub: null, // keep current subscription inside ddp
  kadiraInfo: new Meteor.EnvironmentVariable(),
};
Kadira.waitTimeBuilder = new WaitTimeBuilder();
Kadira.errors = [];
Kadira.errors.addFilter = Kadira.errors.push.bind(Kadira.errors);

Kadira.connect = function(appId, appSecret, options) {
  options = options || {};
  options.appId = appId;
  options.appSecret = appSecret;
  options.payloadTimeout = options.payloadTimeout || 1000 * 20;
  options.endpoint = options.endpoint || "https://engine.kadira.io";
  options.thresholds = options.thresholds || {};

  // remove trailing slash from endpoint url (if any)
  if(_.last(options.endpoint) === '/') {
    options.endpoint = options.endpoint.substr(0, options.endpoint.length - 1);
  }

  // error tracking is enabled by default
  if(options.enableErrorTracking === undefined) {
    options.enableErrorTracking = true;
  }

  Kadira.options = options;
  Kadira.options.authHeaders = {
    'KADIRA-APP-ID': Kadira.options.appId,
    'KADIRA-APP-SECRET': Kadira.options.appSecret
  };

  Kadira.syncedDate = new Ntp(options.endpoint);
  Kadira.syncedDate.sync();
  Kadira.models.methods = new MethodsModel(options.thresholds.methods);
  Kadira.models.pubsub = new PubsubModel();
  Kadira.models.system = new SystemModel();
  Kadira.models.error = new ErrorModel(appId);

  // handle pre-added filters
  var addFilterFn = Kadira.models.error.addFilter.bind(Kadira.models.error);
  Kadira.errors.forEach(addFilterFn);
  Kadira.errors = Kadira.models.error;

  // setting runtime info, which will be sent to kadira
  __meteor_runtime_config__.kadira = {
    appId: appId,
    endpoint: options.endpoint
  };

  if(options.enableErrorTracking) {
    Kadira.enableErrorTracking();
  } else {
    Kadira.disableErrorTracking();
  }

  if(appId && appSecret) {
    options.appId = options.appId.trim();
    options.appSecret = options.appSecret.trim();
    Kadira._pingToCheckAuth(function(){
      // it takes time to calculate version 'sha' values
      // it'll be ready when Meteor.startup is called
      Meteor.startup(Kadira._sendAppStats);
      Kadira._schedulePayloadSend();
    });
    logger('connected to app: ', appId);
  } else {
    throw new Error('Kadira: required appId and appSecret');
  }

  //start wrapping Meteor's internal methods
  Kadira._startInstrumenting(function() {
    console.log('Kadira: completed instrumenting the app')
    Kadira.connected = true;
  });

  Meteor.publish(null, function () {
    var options = __meteor_runtime_config__.kadira;
    this.added('kadira_settings', Random.id(), options);
    this.ready();
  });
};

//track how many times we've sent the data (once per minute)
Kadira._buildPayload = function () {
  var payload = {host: hostname};
  var buildDetailedInfo = Kadira._isDetailedInfo();
  _.extend(payload, Kadira.models.methods.buildPayload(buildDetailedInfo));
  _.extend(payload, Kadira.models.pubsub.buildPayload(buildDetailedInfo));
  _.extend(payload, Kadira.models.system.buildPayload());
  if(Kadira.options.enableErrorTracking) {
    _.extend(payload, Kadira.models.error.buildPayload());
  }

  return payload;
}

Kadira._countDataSent = 0;
Kadira._detailInfoSentInterval = Math.ceil((1000*60) / Kadira.options.payloadTimeout);
Kadira._isDetailedInfo = function () {
  return (Kadira._countDataSent++ % Kadira._detailInfoSentInterval) == 0;
}

Kadira.authCheckFailures = 0;
Kadira._pingToCheckAuth = function (callback) {
  var httpOptions = {headers: Kadira.options.authHeaders, data: {}};
  var endpoint = Kadira.options.endpoint + '/ping';
  var authRetry = new Retry({
    minCount: 0, // don't do any immediate retries
    baseTimeout: 5 * 1000
  });

  new Fibers(function() {
    HTTP.call('POST', endpoint, httpOptions, function(err, response){
      if(response) {
        if(response.statusCode == 200) {
          console.log('Kadira: successfully authenticated');
          authRetry.clear();
          callback();
        } else if(response.statusCode == 401) {
          console.error('Kadira: authentication failed - check your appId & appSecret')
        } else {
          retryPingToCheckAuth();
        }
      } else {
        retryPingToCheckAuth();
      }
    });
  }).run();

  function retryPingToCheckAuth(){
    console.log('Kadira: retrying to authenticate');
    authRetry.retryLater(Kadira.authCheckFailures, function(){
      Kadira._pingToCheckAuth(callback);
    });
  }
}

Kadira._sendAppStats = function () {
  var appStats = {};
  appStats.release = Meteor.release;
  appStats.packageVersions = [];
  appStats.appVersions = {
    webapp: __meteor_runtime_config__['autoupdateVersion'],
    refreshable: __meteor_runtime_config__['autoupdateVersionRefreshable'],
    cordova: __meteor_runtime_config__['autoupdateVersionCordova']
  }

  // TODO get version number for installed packages
  _.each(Package, function (v, name) {
    appStats.packageVersions.push({name: name, version: null});
  });

  Kadira._send({
    host: hostname,
    startTime: new Date(),
    appStats: appStats
  });
}

Kadira._schedulePayloadSend = function () {
  setTimeout(function () {
    Kadira._sendPayload(Kadira._schedulePayloadSend);
  }, Kadira.options.payloadTimeout);
}

Kadira._sendPayload = function (callback) {
  new Fibers(function() {
    var payload = Kadira._buildPayload();
    Kadira._send(payload, function (err) {
      if(err) {
        console.error('Kadira: Error sending payload (dropped after 5 tries)', err.message);
      }

      callback && callback();
    });
  }).run();
}

Kadira._send = function (payload, callback) {
  var endpoint = Kadira.options.endpoint;
  var httpOptions = {headers: Kadira.options.authHeaders, data: payload};
  var payloadRetries = 0;
  var payloadRetry = new Retry({
    minCount: 0, // don't do any immediate payloadRetries
    baseTimeout: 5*1000,
    maxTimeout: 60000
  });

  callHTTP();

  function callHTTP() {
    new Fibers(function() {
      HTTP.call('POST', endpoint, httpOptions, function(err, response){
        if(response && response.statusCode === 401) {
          // do not retry if authentication fails
          throw new Error('Kadira: AppId, AppSecret combination is invalid');
        }

        if(response && response.statusCode == 200) {
          if(payloadRetries > 0) {
            logger('connected again and payload sent.')
          }
          cleaPayloadRetry();
          callback && callback();
        } else {
          tryAgain(err);
        }
      });
    }).run();
  }

  function tryAgain(err) {
    err = err || {};
    logger('retrying to send payload to server')
    if(++payloadRetries < 5) {
      payloadRetry.retryLater(payloadRetries, callHTTP);
    } else {
      cleaPayloadRetry();
      callback && callback(err);
    }
  }

  function cleaPayloadRetry() {
    payloadRetries = 0;
    payloadRetry.clear();
  }
}

// this return the __kadiraInfo from the current Fiber by default
// if called with 2nd argument as true, it will get the kadira info from
// Meteor.EnvironmentVariable
//
// WARNNING: returned info object is the reference object.
//  Changing it might cause issues when building traces. So use with care
Kadira._getInfo = function(currentFiber, useEnvironmentVariable) {
  currentFiber = currentFiber || Fibers.current;
  if(currentFiber) {
    if(useEnvironmentVariable) {
      return Kadira.env.kadiraInfo.get();
    }
    return currentFiber.__kadiraInfo;
  }
};

// this does not clone the info object. So, use with care
Kadira._setInfo = function(info) {
  Fibers.current.__kadiraInfo = info;
};

Kadira.enableErrorTracking = function () {
  __meteor_runtime_config__.kadira.enableErrorTracking = true;
  Kadira.options.enableErrorTracking = true;
};

Kadira.disableErrorTracking = function () {
  __meteor_runtime_config__.kadira.enableErrorTracking = false;
  Kadira.options.enableErrorTracking = false;
};

Kadira.trackError = function (type, message, options) {
  if(Kadira.options.enableErrorTracking && type && message) {
    options = options || {};
    options.subType = options.subType || 'server';
    options.stacks = options.stacks || '';
    var error = {message: message, stack: options.stacks};
    var trace = {
      type: type,
      subType: options.subType,
      name: message,
      errored: true,
      at: Kadira.syncedDate.getTime(),
      events: [['start', 0, {}], ['error', 0, {error: error}]],
      metrics: {total: 0}
    };
    Kadira.models.error.trackError(error, trace);
  }
}
<commit_msg>Support nicknames for hosts<commit_after>var http = Npm.require('http');
var hostname = Npm.require('os').hostname();
var logger = Npm.require('debug')('kadira:apm');
var Fibers = Npm.require('fibers');

Kadira.models = {};
Kadira.options = {};
Kadira.env = {
  currentSub: null, // keep current subscription inside ddp
  kadiraInfo: new Meteor.EnvironmentVariable(),
};
Kadira.waitTimeBuilder = new WaitTimeBuilder();
Kadira.errors = [];
Kadira.errors.addFilter = Kadira.errors.push.bind(Kadira.errors);

Kadira.connect = function(appId, appSecret, options) {
  options = options || {};
  options.appId = appId;
  options.appSecret = appSecret;
  options.payloadTimeout = options.payloadTimeout || 1000 * 20;
  options.endpoint = options.endpoint || "https://engine.kadira.io";
  options.thresholds = options.thresholds || {};
  options.hostname = options.hostname || hostname;

  // remove trailing slash from endpoint url (if any)
  if(_.last(options.endpoint) === '/') {
    options.endpoint = options.endpoint.substr(0, options.endpoint.length - 1);
  }

  // error tracking is enabled by default
  if(options.enableErrorTracking === undefined) {
    options.enableErrorTracking = true;
  }

  Kadira.options = options;
  Kadira.options.authHeaders = {
    'KADIRA-APP-ID': Kadira.options.appId,
    'KADIRA-APP-SECRET': Kadira.options.appSecret
  };

  Kadira.syncedDate = new Ntp(options.endpoint);
  Kadira.syncedDate.sync();
  Kadira.models.methods = new MethodsModel(options.thresholds.methods);
  Kadira.models.pubsub = new PubsubModel();
  Kadira.models.system = new SystemModel();
  Kadira.models.error = new ErrorModel(appId);

  // handle pre-added filters
  var addFilterFn = Kadira.models.error.addFilter.bind(Kadira.models.error);
  Kadira.errors.forEach(addFilterFn);
  Kadira.errors = Kadira.models.error;

  // setting runtime info, which will be sent to kadira
  __meteor_runtime_config__.kadira = {
    appId: appId,
    endpoint: options.endpoint
  };

  if(options.enableErrorTracking) {
    Kadira.enableErrorTracking();
  } else {
    Kadira.disableErrorTracking();
  }

  if(appId && appSecret) {
    options.appId = options.appId.trim();
    options.appSecret = options.appSecret.trim();
    Kadira._pingToCheckAuth(function(){
      // it takes time to calculate version 'sha' values
      // it'll be ready when Meteor.startup is called
      Meteor.startup(Kadira._sendAppStats);
      Kadira._schedulePayloadSend();
    });
    logger('connected to app: ', appId);
  } else {
    throw new Error('Kadira: required appId and appSecret');
  }

  //start wrapping Meteor's internal methods
  Kadira._startInstrumenting(function() {
    console.log('Kadira: completed instrumenting the app')
    Kadira.connected = true;
  });

  Meteor.publish(null, function () {
    var options = __meteor_runtime_config__.kadira;
    this.added('kadira_settings', Random.id(), options);
    this.ready();
  });
};

//track how many times we've sent the data (once per minute)
Kadira._buildPayload = function () {
  var payload = {host: Kadira.options.hostname};
  var buildDetailedInfo = Kadira._isDetailedInfo();
  _.extend(payload, Kadira.models.methods.buildPayload(buildDetailedInfo));
  _.extend(payload, Kadira.models.pubsub.buildPayload(buildDetailedInfo));
  _.extend(payload, Kadira.models.system.buildPayload());
  if(Kadira.options.enableErrorTracking) {
    _.extend(payload, Kadira.models.error.buildPayload());
  }

  return payload;
}

Kadira._countDataSent = 0;
Kadira._detailInfoSentInterval = Math.ceil((1000*60) / Kadira.options.payloadTimeout);
Kadira._isDetailedInfo = function () {
  return (Kadira._countDataSent++ % Kadira._detailInfoSentInterval) == 0;
}

Kadira.authCheckFailures = 0;
Kadira._pingToCheckAuth = function (callback) {
  var httpOptions = {headers: Kadira.options.authHeaders, data: {}};
  var endpoint = Kadira.options.endpoint + '/ping';
  var authRetry = new Retry({
    minCount: 0, // don't do any immediate retries
    baseTimeout: 5 * 1000
  });

  new Fibers(function() {
    HTTP.call('POST', endpoint, httpOptions, function(err, response){
      if(response) {
        if(response.statusCode == 200) {
          console.log('Kadira: successfully authenticated');
          authRetry.clear();
          callback();
        } else if(response.statusCode == 401) {
          console.error('Kadira: authentication failed - check your appId & appSecret')
        } else {
          retryPingToCheckAuth();
        }
      } else {
        retryPingToCheckAuth();
      }
    });
  }).run();

  function retryPingToCheckAuth(){
    console.log('Kadira: retrying to authenticate');
    authRetry.retryLater(Kadira.authCheckFailures, function(){
      Kadira._pingToCheckAuth(callback);
    });
  }
}

Kadira._sendAppStats = function () {
  var appStats = {};
  appStats.release = Meteor.release;
  appStats.packageVersions = [];
  appStats.appVersions = {
    webapp: __meteor_runtime_config__['autoupdateVersion'],
    refreshable: __meteor_runtime_config__['autoupdateVersionRefreshable'],
    cordova: __meteor_runtime_config__['autoupdateVersionCordova']
  }

  // TODO get version number for installed packages
  _.each(Package, function (v, name) {
    appStats.packageVersions.push({name: name, version: null});
  });

  Kadira._send({
    host: Kadira.options.hostname,
    startTime: new Date(),
    appStats: appStats
  });
}

Kadira._schedulePayloadSend = function () {
  setTimeout(function () {
    Kadira._sendPayload(Kadira._schedulePayloadSend);
  }, Kadira.options.payloadTimeout);
}

Kadira._sendPayload = function (callback) {
  new Fibers(function() {
    var payload = Kadira._buildPayload();
    Kadira._send(payload, function (err) {
      if(err) {
        console.error('Kadira: Error sending payload (dropped after 5 tries)', err.message);
      }

      callback && callback();
    });
  }).run();
}

Kadira._send = function (payload, callback) {
  var endpoint = Kadira.options.endpoint;
  var httpOptions = {headers: Kadira.options.authHeaders, data: payload};
  var payloadRetries = 0;
  var payloadRetry = new Retry({
    minCount: 0, // don't do any immediate payloadRetries
    baseTimeout: 5*1000,
    maxTimeout: 60000
  });

  callHTTP();

  function callHTTP() {
    new Fibers(function() {
      HTTP.call('POST', endpoint, httpOptions, function(err, response){
        if(response && response.statusCode === 401) {
          // do not retry if authentication fails
          throw new Error('Kadira: AppId, AppSecret combination is invalid');
        }

        if(response && response.statusCode == 200) {
          if(payloadRetries > 0) {
            logger('connected again and payload sent.')
          }
          cleaPayloadRetry();
          callback && callback();
        } else {
          tryAgain(err);
        }
      });
    }).run();
  }

  function tryAgain(err) {
    err = err || {};
    logger('retrying to send payload to server')
    if(++payloadRetries < 5) {
      payloadRetry.retryLater(payloadRetries, callHTTP);
    } else {
      cleaPayloadRetry();
      callback && callback(err);
    }
  }

  function cleaPayloadRetry() {
    payloadRetries = 0;
    payloadRetry.clear();
  }
}

// this return the __kadiraInfo from the current Fiber by default
// if called with 2nd argument as true, it will get the kadira info from
// Meteor.EnvironmentVariable
//
// WARNNING: returned info object is the reference object.
//  Changing it might cause issues when building traces. So use with care
Kadira._getInfo = function(currentFiber, useEnvironmentVariable) {
  currentFiber = currentFiber || Fibers.current;
  if(currentFiber) {
    if(useEnvironmentVariable) {
      return Kadira.env.kadiraInfo.get();
    }
    return currentFiber.__kadiraInfo;
  }
};

// this does not clone the info object. So, use with care
Kadira._setInfo = function(info) {
  Fibers.current.__kadiraInfo = info;
};

Kadira.enableErrorTracking = function () {
  __meteor_runtime_config__.kadira.enableErrorTracking = true;
  Kadira.options.enableErrorTracking = true;
};

Kadira.disableErrorTracking = function () {
  __meteor_runtime_config__.kadira.enableErrorTracking = false;
  Kadira.options.enableErrorTracking = false;
};

Kadira.trackError = function (type, message, options) {
  if(Kadira.options.enableErrorTracking && type && message) {
    options = options || {};
    options.subType = options.subType || 'server';
    options.stacks = options.stacks || '';
    var error = {message: message, stack: options.stacks};
    var trace = {
      type: type,
      subType: options.subType,
      name: message,
      errored: true,
      at: Kadira.syncedDate.getTime(),
      events: [['start', 0, {}], ['error', 0, {error: error}]],
      metrics: {total: 0}
    };
    Kadira.models.error.trackError(error, trace);
  }
}
<|endoftext|>


<commit_before>$(function () {
    // Ajax Setup
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        var token;
        if (! options.crossDomain) {
            token = $('meta[name="token"]').attr('content');
            if (token) {
                jqXHR.setRequestHeader('X-CSRF-Token', token);
            }
        }

        return jqXHR;
    });

    $.ajaxSetup({
        beforeSend: function (xhr) {
            xhr.setRequestHeader('Accept', 'application/json');
            // xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
        },
        statusCode: {
            401: function () {
                window.location.href = '/';
            },
            403: function () {
                window.location.href = '/';
            }
        }
    });

    // Prevent double form submission
    $('form').submit(function () {
        var $form = $(this);
        $form.find(':submit').prop('disabled', true);
    });

    // Autosizing of textareas.
    // autosize($('textarea.autosize'));

    // Mock the DELETE form requests.
    $('[data-method]').not(".disabled").append(function () {
        var methodForm = "\n";
        methodForm += "<form action='" + $(this).attr('href') + "' method='POST' style='display:none'>\n";
        methodForm += "<input type='hidden' name='_method' value='" + $(this).attr('data-method') + "'>\n";
        methodForm += "<input type='hidden' name='_token' value='" + $('meta[name=token]').attr('content') + "'>\n";
        methodForm += "</form>\n";
        return methodForm;
    })
        .removeAttr('href')
        .on('click', function () {
            var button = $(this);

            if (button.hasClass('confirm-action')) {
                askConfirmation(function () {
                    button.find("form").submit();
                });
            } else {
                button.find("form").submit();
            }
        });

    // Messenger config
    Messenger.options = {
        extraClasses: 'messenger-fixed messenger-on-top',
        theme: 'air'
    };

    // App setup
    window.Cachet = {};

    moment.locale(Global.locale);

    $('abbr.timeago').each(function () {
        var $el = $(this);
        $el
            .livestamp($el.data('timeago'))
            .tooltip();
    });

    window.Cachet.Notifier = function () {
        this.notify = function (message, type, options) {
            if (_.isPlainObject(message)) {
                message = message.detail;
            }
            type = (typeof type === 'undefined' || type === 'error') ? 'error' : type;

            var defaultOptions = {
                message: message,
                type: type,
                showCloseButton: true
            };

            options = _.extend(defaultOptions, options);

            Messenger().post(options);
        };
    };

    $(".sidebar-toggler").on('click', function (e) {
        e.preventDefault();
        $(".wrapper").toggleClass("toggled");
    });

    $('.color-code').each(function () {
        var $this = $(this);

        $this.minicolors({
            control: 'hue',
            defaultValue: $this.val() || '',
            inline: false,
            letterCase: 'lowercase',
            opacity: false,
            position: 'bottom left',
            theme: 'bootstrap'
        });
    });

    $('[data-toggle="tooltip"]').tooltip();

    $('button.close').on('click', function () {
        $(this).parents('div.alert').addClass('hide');
    });

    $('form[name=IncidentForm] select[name=component_id]').on('change', function () {
        var $option = $(this).find('option:selected');
        var $componentStatus = $('#component-status');

        if (parseInt($option.val(), 10) !== 0) {
            if ($componentStatus.hasClass('hidden')) {
                $componentStatus.removeClass('hidden');
            }
        } else {
            $componentStatus.addClass('hidden');
        }
    });

    // Date picker.
    $('input[rel=datepicker]').datetimepicker({
        format: "DD/MM/YYYY HH:mm",
        minDate: new Date(), // Don't allow dates before today.
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    $('input[rel=datepicker-any]').datetimepicker({
        format: "DD/MM/YYYY HH:mm",
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    $('input[rel=datepicker-custom]').datetimepicker({
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    // Sortable models.
    var orderableLists = document.querySelectorAll('[data-orderable-list]');

    $.each(orderableLists, function (k, list) {
        var url = $(list).data('orderableList');
        var notifier = new Cachet.Notifier();

        new Sortable(list, {
            group: 'omega',
            handle: '.drag-handle',
            onUpdate: function () {
                var orderedIds = $.map(list.querySelectorAll('[data-orderable-id]'), function(elem) {
                    return $(elem).data('orderable-id');
                });

                $.ajax({
                    async: true,
                    url: url,
                    type: 'POST',
                    data: {
                        ids: orderedIds
                    },
                    success: function () {
                        notifier.notify('Ordering updated.', 'success');
                    },
                    error: function () {
                        notifier.notify('Ordering not updated.', 'error');
                    }
                });
            }
        });
    });

    // Toggle inline component statuses.
    $('form.component-inline').on('click', 'input[type=radio]', function () {
        var $form = $(this).parents('form');
        var formData = $form.serializeObject();

        $.ajax({
            async: true,
            url: '/dashboard/api/components/' + formData.component_id,
            type: 'POST',
            data: formData,
            success: function(component) {
                (new Cachet.Notifier()).notify($form.data('messenger'), 'success');
            },
            error: function(a, b, c) {
                (new Cachet.Notifier()).notify('Something went wrong updating the component.');
            }
        });
    });

    // Incident management
    $('select[name=template]').on('change', function () {
        var $this = $(this).find('option:selected'),
            slug   = $this.val();

        // Only fetch the template if we've picked one.
        if (slug) {
            $.ajax({
                async: true,
                data: {
                    slug: slug
                },
                url: '/dashboard/api/incidents/templates',
                success: function(tpl) {
                    var $form = $('form[role=form]');
                    $form.find('input[name=name]').val(tpl.name);
                    $form.find('textarea[name=message]').val(tpl.template);
                },
                error: function () {
                    (new Cachet.Notifier()).notify('There was an error finding that template.');
                }
            });
        }
    });

    // Banner removal JS
    $('#remove-banner').on('click', function (){
        $('#banner-view').remove();
        $('input[name=remove_banner]').val('1');
    });

    $('.group-name').on('click', function () {
        var $this = $(this);

        $this.find('.group-toggle').toggleClass('ion-ios-minus-outline').toggleClass('ion-ios-plus-outline');

        $this.next('.group-items').toggleClass('hide');
    });

    $('.select-group').on('click', function () {
        var $parentGroup = $(this).closest('ul.list-group');
        $parentGroup.find('input[type=checkbox]').prop('checked', true);
        $parentGroup.find('.group-items').removeClass('hide')
        $parentGroup.find('.group-toggle').addClass('ion-ios-minus-outline').removeClass('ion-ios-plus-outline');
        event.stopPropagation();
        return false;
    });

    $('.deselect-group').on('click', function () {
        var $parentGroup = $(this).closest('ul.list-group');
        $parentGroup.find('input[type=checkbox]').prop('checked', false);
        $parentGroup.find('.group-items').addClass('hide');
        $parentGroup.find('.group-toggle').removeClass('ion-ios-minus-outline').addClass('ion-ios-plus-outline');
        event.stopPropagation();
        return false;
    });

    // Setup wizard
    $('.wizard-next').on('click', function () {
        var $form   = $('#setup-form'),
            $btn    = $(this),
            current = $btn.data('currentBlock'),
            next    = $btn.data('nextBlock');

        $btn.button('loading');

        // Only validate going forward. If current group is invalid, do not go further
        if (next > current) {
            var url = '/setup/step' + current;
            $.post(url, $form.serializeObject())
                .done(function(response) {
                    goToStep(current, next);
                })
                .fail(function(response) {
                    var errors = _.toArray(response.responseJSON.errors);
                    _.each(errors, function(error) {
                        (new Cachet.Notifier()).notify(error);
                    });
                })
                .always(function () {
                    $btn.button('reset');
                });

            return false;
        } else {
            goToStep(current, next);
            $btn.button('reset');
        }
    });

    // Sparkline
    if ($.fn.sparkline) {
        var sparkLine = function () {
            $('.sparkline').each(function () {
                var data = $(this).data();
                data.valueSpots = {
                    '0:': data.spotColor
                };

                $(this).sparkline(data.data, data);
                var composite = data.compositedata;

                if (composite) {
                    var stlColor = $(this).attr("data-stack-line-color"),
                        stfColor = $(this).attr("data-stack-fill-color"),
                        sptColor = $(this).attr("data-stack-spot-color"),
                        sptRadius = $(this).attr("data-stack-spot-radius");

                    $(this).sparkline(composite, {
                        composite: true,
                        lineColor: stlColor,
                        fillColor: stfColor,
                        spotColor: sptColor,
                        highlightSpotColor: sptColor,
                        spotRadius: sptRadius,
                        valueSpots: {
                            '0:': sptColor
                        }
                    });
                };
            });
        };

        sparkLine(false);
    }

    function goToStep(current, next) {
        // validation was ok. We can go on next step.
        $('.block-' + current)
          .removeClass('show')
          .addClass('hidden');

        $('.block-' + next)
          .removeClass('hidden')
          .addClass('show');

        $('.steps .step')
            .removeClass("active")
            .filter(":lt(" + (next) + ")")
            .addClass("active");
    }

    // Password strength
    $('.password-strength').strengthify();

    // Check for updates.
    if ($('#update-alert').length > 0) {
        $.ajax({
            async: true,
            dataType: 'json',
            url: '/api/v1/version',
        }).done(function (result) {
            if (result.meta.on_latest === false) {
                $('#update-alert').removeClass('hidden');
            }
        });
    }

    function askConfirmation(callback, cancelCallback) {
        swal({
            type: "warning",
            title: "Confirm your action",
            text: "Are you sure you want to do this?",
            buttonsStyling: false,
            reverseButtons: true,
            confirmButtonText: "Yes",
            confirmButtonClass: "btn btn-lg btn-danger",
            cancelButtonClass: "btn btn-lg btn-default",
            showCancelButton: true,
            focusCancel: true
        }).then(function () {
            if (_.isFunction(callback)) callback();
        }, function () {
            if (_.isFunction(cancelCallback)) cancelCallback();
        });
    }
});
<commit_msg>If not logged in, redirect to login page<commit_after>$(function () {
    // Ajax Setup
    $.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        var token;
        if (! options.crossDomain) {
            token = $('meta[name="token"]').attr('content');
            if (token) {
                jqXHR.setRequestHeader('X-CSRF-Token', token);
            }
        }

        return jqXHR;
    });

    $.ajaxSetup({
        beforeSend: function (xhr) {
            xhr.setRequestHeader('Accept', 'application/json');
            // xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
        },
        statusCode: {
            401: function () {
                window.location.href = '/auth/login';
            },
            403: function () {
                window.location.href = '/';
            }
        }
    });

    // Prevent double form submission
    $('form').submit(function () {
        var $form = $(this);
        $form.find(':submit').prop('disabled', true);
    });

    // Autosizing of textareas.
    // autosize($('textarea.autosize'));

    // Mock the DELETE form requests.
    $('[data-method]').not(".disabled").append(function () {
        var methodForm = "\n";
        methodForm += "<form action='" + $(this).attr('href') + "' method='POST' style='display:none'>\n";
        methodForm += "<input type='hidden' name='_method' value='" + $(this).attr('data-method') + "'>\n";
        methodForm += "<input type='hidden' name='_token' value='" + $('meta[name=token]').attr('content') + "'>\n";
        methodForm += "</form>\n";
        return methodForm;
    })
        .removeAttr('href')
        .on('click', function () {
            var button = $(this);

            if (button.hasClass('confirm-action')) {
                askConfirmation(function () {
                    button.find("form").submit();
                });
            } else {
                button.find("form").submit();
            }
        });

    // Messenger config
    Messenger.options = {
        extraClasses: 'messenger-fixed messenger-on-top',
        theme: 'air'
    };

    // App setup
    window.Cachet = {};

    moment.locale(Global.locale);

    $('abbr.timeago').each(function () {
        var $el = $(this);
        $el
            .livestamp($el.data('timeago'))
            .tooltip();
    });

    window.Cachet.Notifier = function () {
        this.notify = function (message, type, options) {
            if (_.isPlainObject(message)) {
                message = message.detail;
            }
            type = (typeof type === 'undefined' || type === 'error') ? 'error' : type;

            var defaultOptions = {
                message: message,
                type: type,
                showCloseButton: true
            };

            options = _.extend(defaultOptions, options);

            Messenger().post(options);
        };
    };

    $(".sidebar-toggler").on('click', function (e) {
        e.preventDefault();
        $(".wrapper").toggleClass("toggled");
    });

    $('.color-code').each(function () {
        var $this = $(this);

        $this.minicolors({
            control: 'hue',
            defaultValue: $this.val() || '',
            inline: false,
            letterCase: 'lowercase',
            opacity: false,
            position: 'bottom left',
            theme: 'bootstrap'
        });
    });

    $('[data-toggle="tooltip"]').tooltip();

    $('button.close').on('click', function () {
        $(this).parents('div.alert').addClass('hide');
    });

    $('form[name=IncidentForm] select[name=component_id]').on('change', function () {
        var $option = $(this).find('option:selected');
        var $componentStatus = $('#component-status');

        if (parseInt($option.val(), 10) !== 0) {
            if ($componentStatus.hasClass('hidden')) {
                $componentStatus.removeClass('hidden');
            }
        } else {
            $componentStatus.addClass('hidden');
        }
    });

    // Date picker.
    $('input[rel=datepicker]').datetimepicker({
        format: "DD/MM/YYYY HH:mm",
        minDate: new Date(), // Don't allow dates before today.
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    $('input[rel=datepicker-any]').datetimepicker({
        format: "DD/MM/YYYY HH:mm",
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    $('input[rel=datepicker-custom]').datetimepicker({
        sideBySide: true,
        icons: {
            time: 'ion-clock',
            date: 'ion-android-calendar',
            up: 'ion-ios-arrow-up',
            down: 'ion-ios-arrow-down',
            previous: 'ion-ios-arrow-left',
            next: 'ion-ios-arrow-right',
            today: 'ion-android-home',
            clear: 'ion-trash-a',
        }
    });

    // Sortable models.
    var orderableLists = document.querySelectorAll('[data-orderable-list]');

    $.each(orderableLists, function (k, list) {
        var url = $(list).data('orderableList');
        var notifier = new Cachet.Notifier();

        new Sortable(list, {
            group: 'omega',
            handle: '.drag-handle',
            onUpdate: function () {
                var orderedIds = $.map(list.querySelectorAll('[data-orderable-id]'), function(elem) {
                    return $(elem).data('orderable-id');
                });

                $.ajax({
                    async: true,
                    url: url,
                    type: 'POST',
                    data: {
                        ids: orderedIds
                    },
                    success: function () {
                        notifier.notify('Ordering updated.', 'success');
                    },
                    error: function () {
                        notifier.notify('Ordering not updated.', 'error');
                    }
                });
            }
        });
    });

    // Toggle inline component statuses.
    $('form.component-inline').on('click', 'input[type=radio]', function () {
        var $form = $(this).parents('form');
        var formData = $form.serializeObject();

        $.ajax({
            async: true,
            url: '/dashboard/api/components/' + formData.component_id,
            type: 'POST',
            data: formData,
            success: function(component) {
                (new Cachet.Notifier()).notify($form.data('messenger'), 'success');
            },
            error: function(a, b, c) {
                (new Cachet.Notifier()).notify('Something went wrong updating the component.');
            }
        });
    });

    // Incident management
    $('select[name=template]').on('change', function () {
        var $this = $(this).find('option:selected'),
            slug   = $this.val();

        // Only fetch the template if we've picked one.
        if (slug) {
            $.ajax({
                async: true,
                data: {
                    slug: slug
                },
                url: '/dashboard/api/incidents/templates',
                success: function(tpl) {
                    var $form = $('form[role=form]');
                    $form.find('input[name=name]').val(tpl.name);
                    $form.find('textarea[name=message]').val(tpl.template);
                },
                error: function () {
                    (new Cachet.Notifier()).notify('There was an error finding that template.');
                }
            });
        }
    });

    // Banner removal JS
    $('#remove-banner').on('click', function (){
        $('#banner-view').remove();
        $('input[name=remove_banner]').val('1');
    });

    $('.group-name').on('click', function () {
        var $this = $(this);

        $this.find('.group-toggle').toggleClass('ion-ios-minus-outline').toggleClass('ion-ios-plus-outline');

        $this.next('.group-items').toggleClass('hide');
    });

    $('.select-group').on('click', function () {
        var $parentGroup = $(this).closest('ul.list-group');
        $parentGroup.find('input[type=checkbox]').prop('checked', true);
        $parentGroup.find('.group-items').removeClass('hide')
        $parentGroup.find('.group-toggle').addClass('ion-ios-minus-outline').removeClass('ion-ios-plus-outline');
        event.stopPropagation();
        return false;
    });

    $('.deselect-group').on('click', function () {
        var $parentGroup = $(this).closest('ul.list-group');
        $parentGroup.find('input[type=checkbox]').prop('checked', false);
        $parentGroup.find('.group-items').addClass('hide');
        $parentGroup.find('.group-toggle').removeClass('ion-ios-minus-outline').addClass('ion-ios-plus-outline');
        event.stopPropagation();
        return false;
    });

    // Setup wizard
    $('.wizard-next').on('click', function () {
        var $form   = $('#setup-form'),
            $btn    = $(this),
            current = $btn.data('currentBlock'),
            next    = $btn.data('nextBlock');

        $btn.button('loading');

        // Only validate going forward. If current group is invalid, do not go further
        if (next > current) {
            var url = '/setup/step' + current;
            $.post(url, $form.serializeObject())
                .done(function(response) {
                    goToStep(current, next);
                })
                .fail(function(response) {
                    var errors = _.toArray(response.responseJSON.errors);
                    _.each(errors, function(error) {
                        (new Cachet.Notifier()).notify(error);
                    });
                })
                .always(function () {
                    $btn.button('reset');
                });

            return false;
        } else {
            goToStep(current, next);
            $btn.button('reset');
        }
    });

    // Sparkline
    if ($.fn.sparkline) {
        var sparkLine = function () {
            $('.sparkline').each(function () {
                var data = $(this).data();
                data.valueSpots = {
                    '0:': data.spotColor
                };

                $(this).sparkline(data.data, data);
                var composite = data.compositedata;

                if (composite) {
                    var stlColor = $(this).attr("data-stack-line-color"),
                        stfColor = $(this).attr("data-stack-fill-color"),
                        sptColor = $(this).attr("data-stack-spot-color"),
                        sptRadius = $(this).attr("data-stack-spot-radius");

                    $(this).sparkline(composite, {
                        composite: true,
                        lineColor: stlColor,
                        fillColor: stfColor,
                        spotColor: sptColor,
                        highlightSpotColor: sptColor,
                        spotRadius: sptRadius,
                        valueSpots: {
                            '0:': sptColor
                        }
                    });
                };
            });
        };

        sparkLine(false);
    }

    function goToStep(current, next) {
        // validation was ok. We can go on next step.
        $('.block-' + current)
          .removeClass('show')
          .addClass('hidden');

        $('.block-' + next)
          .removeClass('hidden')
          .addClass('show');

        $('.steps .step')
            .removeClass("active")
            .filter(":lt(" + (next) + ")")
            .addClass("active");
    }

    // Password strength
    $('.password-strength').strengthify();

    // Check for updates.
    if ($('#update-alert').length > 0) {
        $.ajax({
            async: true,
            dataType: 'json',
            url: '/api/v1/version',
        }).done(function (result) {
            if (result.meta.on_latest === false) {
                $('#update-alert').removeClass('hidden');
            }
        });
    }

    function askConfirmation(callback, cancelCallback) {
        swal({
            type: "warning",
            title: "Confirm your action",
            text: "Are you sure you want to do this?",
            buttonsStyling: false,
            reverseButtons: true,
            confirmButtonText: "Yes",
            confirmButtonClass: "btn btn-lg btn-danger",
            cancelButtonClass: "btn btn-lg btn-default",
            showCancelButton: true,
            focusCancel: true
        }).then(function () {
            if (_.isFunction(callback)) callback();
        }, function () {
            if (_.isFunction(cancelCallback)) cancelCallback();
        });
    }
});
<|endoftext|>


<commit_before>var recipeApp = angular.module('cooking', ['RecipeModel']);

// Index: http://localhost/views/recipe/index.html

recipeApp.controller('IndexCtrl', function ($scope, RecipeRestangular) {

  // Helper function for opening new webviews
  $scope.open = function(id) {
    webView = new steroids.views.WebView("/views/recipe/show.html?id="+id);
    steroids.layers.push(webView);
  };

  // Fetch all objects from the local JSON (see app/models/recipe.js)
  RecipeRestangular.all('recipe').getList().then(function(recipes){
    $scope.recipes = recipes;
  });

  // -- Native navigation
  steroids.view.navigationBar.show("Recipes");

});

// Show: http://localhost/views/recipe/show.html?id=<id>

recipeApp.controller('ShowCtrl', function ($scope, $filter, RecipeRestangular) {

  // Fetch all objects from the local JSON (see app/models/recipe.js)
  RecipeRestangular.all('recipe').getList().then( function(recipes) {
    // Then select the one based on the view's id query parameter
    $scope.recipe = $filter('filter')(recipes, {recipe_id: steroids.view.params['id']})[0];
  });

  // -- Native navigation
  steroids.view.navigationBar.show("Recipe " + steroids.view.params.id );

});
<commit_msg>playing with onload events<commit_after>document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
  document.addEventListener("online", onOnline, false);
}

function onOnline() {
  alert('online')
}

var app = angular.module('cooking', ['RecipeModel']);

// Index: http://localhost/views/recipe/index.html

app.controller('IndexCtrl', function ($scope, RecipeRestangular) {

  // Helper function for opening new webviews
  $scope.open = function(id) {
    webView = new steroids.views.WebView("/views/recipe/show.html?id="+id);
    steroids.layers.push(webView);
  };

  // Fetch all objects from the local JSON (see app/models/recipe.js)
  RecipeRestangular.all('recipe').getList().then(function(recipes){
    $scope.recipes = recipes;
  });

  // -- Native navigation
  steroids.view.navigationBar.show("Recipes");

});

// Show: http://localhost/views/recipe/show.html?id=<id>

app.controller('ShowCtrl', function ($scope, $filter, RecipeRestangular) {

  // Fetch all objects from the local JSON (see app/models/recipe.js)
  RecipeRestangular.all('recipe').getList().then( function(recipes) {
    // Then select the one based on the view's id query parameter
    $scope.recipe = $filter('filter')(recipes, {recipe_id: steroids.view.params['id']})[0];
  });

  // -- Native navigation
  steroids.view.navigationBar.show("Recipe " + steroids.view.params.id );

});
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.controllers.signup', [])

// Homepage controller
.controller('SignUpCtrl', function($scope, $location, $rootScope, firebaseData) {
	$scope.emailSignUp = "";
	$scope.passwordSignUp = "";
	$scope.emailSignIn = "";
	$scope.passwordSignIn = "";
	$scope.signUpErrorMessage = "";
	$scope.loginErrorMessage = "";
	$scope.showSignUp = true;

	$scope.signUp = function() {
		firebaseData.provider()
			.createUserWithEmailAndPassword(this.emailSignUp, this.passwordSignUp)
			.then(function() {
				console.log("user signed up.");
				redirect('/user');
			})
			.catch(function(error) {
			  // Handle Errors here.
			  var errorCode = error.code;
			  var errorMessage = error.message;
			  // Need to force apply for some reason
			  // TODO: Figure out why apply is neccesary
			  // to update angular binding
			  $scope.$apply(function() {
			  	$scope.signUpErrorMessage = errorMessage;
			  });
			  console.log("Error message is: " + errorMessage);
			});
	}

	$scope.signIn = function() {
		firebaseData.provider()
			.signInWithEmailAndPassword(this.emailSignIn, this.passwordSignIn)
			.then(function() {
				console.log('User signed in.');
				redirect('/user');
			})
		    .catch(function(error) {
			  // Handle Errors here.
			  var errorCode = error.code;
			  var errorMessage = error.message;
			  if (errorCode === 'auth/wrong-password') {
			  	$scope.loginErrorMessage = "Incorrect Password.";
			  } else {
			  	$scope.loginErrorMessage = errorMessage;
			  }
			  $scope.$apply();

			  console.log(error);
			});
	}

	$scope.toggleSignUp = function() {
		$scope.showSignUp = !$scope.showSignUp;
	}

	var redirect = function(path) {
		$location.path(path);
	}
});<commit_msg>added manual apply to refresh digest cycle when redirecting the url<commit_after>'use strict';

angular.module('myApp.controllers.signup', [])

// Homepage controller
.controller('SignUpCtrl', function($scope, $location, $rootScope, firebaseData) {
	$scope.emailSignUp = "";
	$scope.passwordSignUp = "";
	$scope.emailSignIn = "";
	$scope.passwordSignIn = "";
	$scope.signUpErrorMessage = "";
	$scope.loginErrorMessage = "";
	$scope.showSignUp = true;

	$scope.signUp = function() {
		firebaseData.provider()
			.createUserWithEmailAndPassword(this.emailSignUp, this.passwordSignUp)
			.then(function() {
				console.log("user signed up.");
				$scope.$apply(function() {
					redirect('/user');
				});
			})
			.catch(function(error) {
			  // Handle Errors here.
			  var errorCode = error.code;
			  var errorMessage = error.message;
			  // Need to force apply for some reason
			  // TODO: Figure out why apply is neccesary
			  // to update angular binding
			  $scope.$apply(function() {
			  	$scope.signUpErrorMessage = errorMessage;
			  });
			  console.log("Error message is: " + errorMessage);
			});
	}

	$scope.signIn = function() {
		firebaseData.provider()
			.signInWithEmailAndPassword(this.emailSignIn, this.passwordSignIn)
			.then(function() {
				console.log('User signed in.');
				$scope.$apply(function() {
					redirect('/user');
				});
			})
		    .catch(function(error) {
			  // Handle Errors here.
			  var errorCode = error.code;
			  var errorMessage = error.message;
			  if (errorCode === 'auth/wrong-password') {
			  	$scope.loginErrorMessage = "Incorrect Password.";
			  } else {
			  	$scope.loginErrorMessage = errorMessage;
			  }
			  $scope.$apply();

			  console.log(error);
			});
	}

	$scope.toggleSignUp = function() {
		$scope.showSignUp = !$scope.showSignUp;
	}

	var redirect = function(path) {
		$location.path(path);
	}
});<|endoftext|>


<commit_before>'use strict';

// server-side socket behaviour
var ios = null; // io is already taken in express
var util = require('bitcore').util;
var mdb = require('../../lib/MessageDb').default();
var microtime = require('microtime');
var enableMessageBroker;

module.exports.init = function(io_ext, config) {
  enableMessageBroker = config ? config.enableMessageBroker : false;
  ios = io_ext;
  if (ios) {
    // when a new socket connects
    ios.sockets.on('connection', function(socket) {
      // when it subscribes, make it join the according room
      socket.on('subscribe', function(topic) {
        if (socket.rooms.length === 1) {
          console.log('subscribe to ' + topic);
          socket.join(topic);
        }
      });

      if (enableMessageBroker) {
        // when it requests sync, send him all pending messages
        socket.on('sync', function(ts) {
          var rooms = socket.rooms;
          if (rooms.length !== 2) {
            socket.emit('insight-error', 'Must subscribe with public key before syncing');
            return;
          }
          var to = rooms[1];
          var upper_ts = Math.round(microtime.now());
          mdb.getMessages(to, ts, upper_ts, function(err, messages) {
            if (err) {
              throw new Error('Couldn\'t get messages on sync request: ' + err);
            }
            for (var i = 0; i < messages.length; i++) {
              broadcastMessage(messages[i], socket);
            }
          });
        });

        // when it sends a message, add it to db
        socket.on('message', function(m) {
          mdb.addMessage(m, function(err) {
            if (err) {
              throw new Error('Couldn\'t add message to database: ' + err);
            }
          });
        });
      }
    });
    if (enableMessageBroker)
      mdb.on('message', broadcastMessage);
  }
};

var simpleTx = function(tx) {
  return {
    txid: tx
  };
};

var fullTx = function(tx) {
  var t = {
    txid: tx.txid,
    size: tx.size,
  };
  // Outputs
  var valueOut = 0;
  tx.vout.forEach(function(o) {
    valueOut += o.valueSat;
  });

  t.valueOut = (valueOut.toFixed(8) / util.COIN);
  return t;
};

module.exports.broadcastTx = function(tx) {
  if (ios) {
    var t = (typeof tx === 'string') ? simpleTx(tx) : fullTx(tx);
    ios.sockets.in('inv').emit('tx', t);
  }
};

module.exports.broadcastBlock = function(block) {
  if (ios)
    ios.sockets.in('inv').emit('block', block);
};

module.exports.broadcastAddressTx = function(txid, address) {
  if (ios) {
    ios.sockets.in(address).emit(address, txid);
  }
};

module.exports.broadcastSyncInfo = function(historicSync) {
  if (ios)
    ios.sockets.in('sync').emit('status', historicSync);
};

var broadcastMessage = module.exports.broadcastMessage = function(message, socket) {
  if (ios) {
    var s = socket || ios.sockets.in(message.to);
    s.emit('message', message);
  }

}
<commit_msg>use socket.io-browserify<commit_after>'use strict';

// server-side socket behaviour
var ios = null; // io is already taken in express
var util = require('bitcore').util;
var mdb = require('../../lib/MessageDb').default();
var microtime = require('microtime');
var enableMessageBroker;

module.exports.init = function(io_ext, config) {
  enableMessageBroker = config ? config.enableMessageBroker : false;
  ios = io_ext;
  if (ios) {
    // when a new socket connects
    ios.sockets.on('connection', function(socket) {
      console.log("New connection from " + socket.request.connection.remoteAddress + ":" + socket.request.connection.remotePort);
      // when it subscribes, make it join the according room
      socket.on('subscribe', function(topic) {
        if (socket.rooms.length === 1) {
          console.log('subscribe to ' + topic);
          socket.join(topic);
        }
      });

      if (enableMessageBroker) {
        // when it requests sync, send him all pending messages
        socket.on('sync', function(ts) {
          var rooms = socket.rooms;
          if (rooms.length !== 2) {
            socket.emit('insight-error', 'Must subscribe with public key before syncing');
            return;
          }
          var to = rooms[1];
          var upper_ts = Math.round(microtime.now());
          mdb.getMessages(to, ts, upper_ts, function(err, messages) {
            if (err) {
              throw new Error('Couldn\'t get messages on sync request: ' + err);
            }
            for (var i = 0; i < messages.length; i++) {
              broadcastMessage(messages[i], socket);
            }
          });
        });

        // when it sends a message, add it to db
        socket.on('message', function(m) {
          mdb.addMessage(m, function(err) {
            if (err) {
              throw new Error('Couldn\'t add message to database: ' + err);
            }
          });
        });
      }
    });
    if (enableMessageBroker)
      mdb.on('message', broadcastMessage);
  }
};

var simpleTx = function(tx) {
  return {
    txid: tx
  };
};

var fullTx = function(tx) {
  var t = {
    txid: tx.txid,
    size: tx.size,
  };
  // Outputs
  var valueOut = 0;
  tx.vout.forEach(function(o) {
    valueOut += o.valueSat;
  });

  t.valueOut = (valueOut.toFixed(8) / util.COIN);
  return t;
};

module.exports.broadcastTx = function(tx) {
  if (ios) {
    var t = (typeof tx === 'string') ? simpleTx(tx) : fullTx(tx);
    ios.sockets.in('inv').emit('tx', t);
  }
};

module.exports.broadcastBlock = function(block) {
  if (ios)
    ios.sockets.in('inv').emit('block', block);
};

module.exports.broadcastAddressTx = function(txid, address) {
  if (ios) {
    ios.sockets.in(address).emit(address, txid);
  }
};

module.exports.broadcastSyncInfo = function(historicSync) {
  if (ios)
    ios.sockets.in('sync').emit('status', historicSync);
};

var broadcastMessage = module.exports.broadcastMessage = function(message, socket) {
  if (ios) {
    var s = socket || ios.sockets.in(message.to);
    s.emit('message', message);
  }

}
<|endoftext|>


<commit_before>/*OverPass-API layer*/

function debug_draw_beer(url,icon){
        return new L.OverPassLayer({
                minzoom: 17,
                query: url,
                callback: function(data) {
                        for(i=0;i<data.elements.length;i++) {
                        e = data.elements[i];

                        if (e.id in this.instance._ids) return;
                        this.instance._ids[e.id] = true;
                        var pos = new L.LatLng(e.lat, e.lon);
                        var popup = this.instance._poiInfo(e.tags,e.id);
		        var myicon = L.icon({
                          iconUrl: icon,
                      });
                var marker = L.marker(pos, {icon: myicon}).bindPopup(popup);
                this.instance.addLayer(marker);

        }
      },
    })
    };

function draw_beer(url,icon){
        return new L.OverPassLayer({
	minzoom: 17,
	query: url,

	callback: function(data) {
                for(i=0;i<data.elements.length;i++) {
                e = data.elements[i];

                if (e.id in this.instance._ids) return;
                this.instance._ids[e.id] = true;
                var pos = new L.LatLng(e.lat, e.lon);
                //var popup = e.tags["name"]
                var content = "
"
                if (e.tags["name"]) {content += "
Nom	" + e.tags["name"] + "
"}
                if (e.tags["opening_hours"]) {content += "
Horaires d'ouvertures	" + e.tags["opening_hours"] + "
"}
                if (e.tags["happy_hours"]) {content += "
Happy Hours	" + e.tags["happy_hours"] + "
"}
                if (e.tags["brewery"]) {content += "
Type de bières	" + e.tags["brewery"] + "
"}
                content += "
Ajouter des infos sur ce bar
";
                //content += "
Modifier ce bar dans OSM
"
                content +="
";

		var myicon = L.icon({
                  iconUrl: icon,
              });
        var marker = L.marker(pos, {icon: myicon}).bindPopup(content);
        this.instance.addLayer(marker);

        }
      },
    })
    };

<commit_msg>réduction du niveau de zoom min<commit_after>/*OverPass-API layer*/

function debug_draw_beer(url,icon){
        return new L.OverPassLayer({
                minzoom: 17,
                query: url,
                callback: function(data) {
                        for(i=0;i<data.elements.length;i++) {
                        e = data.elements[i];

                        if (e.id in this.instance._ids) return;
                        this.instance._ids[e.id] = true;
                        var pos = new L.LatLng(e.lat, e.lon);
                        var popup = this.instance._poiInfo(e.tags,e.id);
		        var myicon = L.icon({
                          iconUrl: icon,
                      });
                var marker = L.marker(pos, {icon: myicon}).bindPopup(popup);
                this.instance.addLayer(marker);

        }
      },
    })
    };

function draw_beer(url,icon){
        return new L.OverPassLayer({
	minzoom: 14,
	query: url,

	callback: function(data) {
                for(i=0;i<data.elements.length;i++) {
                e = data.elements[i];

                if (e.id in this.instance._ids) return;
                this.instance._ids[e.id] = true;
                var pos = new L.LatLng(e.lat, e.lon);
                //var popup = e.tags["name"]
                var content = "
"
                if (e.tags["name"]) {content += "
Nom	" + e.tags["name"] + "
"}
                if (e.tags["opening_hours"]) {content += "
Horaires d'ouvertures	" + e.tags["opening_hours"] + "
"}
                if (e.tags["happy_hours"]) {content += "
Happy Hours	" + e.tags["happy_hours"] + "
"}
                if (e.tags["brewery"]) {content += "
Type de bières	" + e.tags["brewery"] + "
"}
                content += "
Ajouter des infos sur ce bar
";
                //content += "
Modifier ce bar dans OSM
"
                content +="
";

		var myicon = L.icon({
                  iconUrl: icon,
              });
        var marker = L.marker(pos, {icon: myicon}).bindPopup(content);
        this.instance.addLayer(marker);

        }
      },
    })
    };

<|endoftext|>


<commit_before>/**
	Various sorting algorithms for lists of non-negative integers
*/
var merge_sort = function(list, step_callback) {

};

/** O(n^2) */
var bubble_sort = function(list, step_callback) {
	var sortedList = list;
	var isSorted = false;

	for (var i = 0; i < list.length && !isSorted; i++) {
		var unsortedLength = list.length - i;
		isSorted = true;

		for (var j = 0; j < unsortedLength - 1; j++) {
			var left = sortedList[j];
			var right = sortedList[j + 1];
			if (left > right) {
				isSorted = false;
				sortedList[j + 1] = left;
				sortedList[j] = right;
			}
			step_callback({ "sorted_list": sortedList });
		}
	}

	return sortedList;
};
var insertion_sort = function(list, step_callback) {

};
var selection_sort = function(list, step_callback) {

};

/** O(n) */
var bucket_sort = function(list, step_callback) {
	var maxValue = 0;
	for (var i = 0; i < list.length; i++) {
		maxValue = Math.max(maxValue, list[i]);
	}
	step_callback({ "max_value": maxValue });

	var buckets = Array(maxValue + 1).fill(0);
	for (var i = 0; i < list.length; i++) {
		var bucketIndex = list[i];
		buckets[bucketIndex] += 1;
	}
	step_callback({ "buckets": buckets })

	var sortedList = [];
	for (var i = 0; i < buckets.length; i++) {
		var bucketCount = buckets[i];
		for (var j = 0; j < bucketCount; j++) {
			sortedList.push(i);
			step_callback({ "sorted_list": sortedList });
		}
	}

	return sortedList;
};

var sortList = function(list, algorithm, algorithmName) {
	console.log("--- " + algorithmName.toUpperCase() + " ---");
	console.log("LIST: " + JSON.stringify(list));
	var result = algorithm(list, function(data) {
		console.log(JSON.stringify(data));
	});
	console.log("RESULT: " + JSON.stringify(result) + "\n");
};

var list = [3, 2, 5, 0, 1, 9, 1, 8, 8, 8, 7];
sortList(list, bucket_sort, "bucket sort");
sortList(list, bubble_sort, "bubble sort");<commit_msg>selection sort<commit_after>/**
	Various sorting algorithms for lists of non-negative integers
*/
var merge_sort = function(list, step_callback) {

};

/** O(n^2) */
var bubble_sort = function(list, step_callback) {
	var sortedList = list;
	var isSorted = false;

	for (var i = 0; i < list.length && !isSorted; i++) {
		var unsortedLength = list.length - i;
		isSorted = true;

		for (var j = 0; j < unsortedLength - 1; j++) {
			var left = sortedList[j];
			var right = sortedList[j + 1];
			if (left > right) {
				isSorted = false;
				sortedList[j + 1] = left;
				sortedList[j] = right;
			}
			step_callback({ "sorted_list": sortedList });
		}
	}

	return sortedList;
};
var insertion_sort = function(list, step_callback) {

};
var selection_sort = function(list, step_callback) {
	var sortedList = list;

	for (var i = 0; i < sortedList.length - 1; i++) {
		var smallestIndex = i;
		for (var j = i + 1; j < sortedList.length; j++) {
			if (sortedList[j] < sortedList[smallestIndex]) {
				smallestIndex = j;
			}
		}

		var smallestValue = sortedList[smallestIndex];
		sortedList[smallestIndex] = sortedList[i];
		sortedList[i] = smallestValue;
		step_callback({ "sorted_list": sortedList });
	}

	return sortedList;
};

/** O(n) */
var bucket_sort = function(list, step_callback) {
	var maxValue = 0;
	for (var i = 0; i < list.length; i++) {
		maxValue = Math.max(maxValue, list[i]);
	}
	step_callback({ "max_value": maxValue });

	var buckets = Array(maxValue + 1).fill(0);
	for (var i = 0; i < list.length; i++) {
		var bucketIndex = list[i];
		buckets[bucketIndex] += 1;
	}
	step_callback({ "buckets": buckets })

	var sortedList = [];
	for (var i = 0; i < buckets.length; i++) {
		var bucketCount = buckets[i];
		for (var j = 0; j < bucketCount; j++) {
			sortedList.push(i);
			step_callback({ "sorted_list": sortedList });
		}
	}

	return sortedList;
};

var sortList = function(list, algorithm, algorithmName) {
	console.log("--- " + algorithmName.toUpperCase() + " ---");
	console.log("LIST: " + JSON.stringify(list));
	var result = algorithm(list, function(data) {
		console.log(JSON.stringify(data));
	});
	console.log("RESULT: " + JSON.stringify(result) + "\n");
};

var list = [3, 2, 5, 0, 1, 9, 1, 8, 8, 8, 7];
sortList(list, bucket_sort, "bucket sort");
sortList(list, bubble_sort, "bubble sort");

list = [3, 2, 5, 0, 1, 9, 1, 8, 8, 8, 7];
sortList(list, selection_sort, "selection sort");<|endoftext|>


<commit_before>var models = require('../models');
var _ = require('lodash');
var resumer = require('resumer');
var browserify = require('browserify');
var path = require('path');
var cache = require('../cache');
var sass = require('node-sass');
var uuid = require('node-uuid');
var Q = require('q');

function protectRequire(str) {
    var protectedVars = ['define', 'require'];
    var initialCode = ';';
    var postCode = ';';
    _.each(protectedVars, function(v) {
        initialCode += 'window._' + v + ' = window.' + v + ';';
        initialCode += 'window.' + v + ' = undefined;';

        postCode += 'window.' + v + ' = window._' + v + ';';
    });

    return initialCode + str;// + postCode;

}

exports.getDynamicVizBundle = function (req, res, next) {

    res.set('Content-Type', 'application/javascript');
    res.set('Access-Control-Allow-Origin', "*");

    // Get all vizTypes in array
    var visualizationTypes = _.uniq(req.query.visualizations).sort();

    if(!req.query.cachemiss) {
        var bundle = cache.get('js/' + visualizationTypes.toString());

        if(bundle) {
            return res.send(bundle);
        }
    }

    console.log('building viz bundle with ' + visualizationTypes);
    var tmpPath = path.resolve(__dirname + '/../../tmp/js-build/' + uuid.v4() + '/viz/');

    req.session.lastBundlePath = tmpPath;

    var b = browserify();

    models.VisualizationType
        .findAll().success(function(vizTypes) {

            console.log(_.pluck(vizTypes, 'name'));

            var funcs = [];
            _.each(vizTypes, function(vizType) {
                funcs.push(vizType.exportToFS(tmpPath));
            });

            Q.all(funcs).spread(function() {

                _.each(_.filter(vizTypes, function(vizType) { return (visualizationTypes.indexOf(vizType.name) > -1); }), function(vizType) {

                    var stream = resumer().queue(vizType.javascript).end();
                    b.require(stream, {
                        basedir: tmpPath,
                        expose: 'viz/' + vizType.name
                    });

                });

                b.bundle(function(err, buf) {

                    if(err) {
                        return next(err);
                    }

                    // var out = protectRequire(buf.toString('utf8'));
                    var out = buf.toString('utf8');
                    cache.put('js/' + visualizationTypes.toString(), out, 1000 * 60 * 60);
                    res.send(out);
                });
            });
        }).error(next);

};

exports.bundleJSForExecution = function(req, res, next) {

    res.set('Content-Type', 'application/javascript');

    var b = browserify();

    var js = req.body.javascript;
    var stream = resumer().queue(js).end();
    b.require(stream, {
        basedir: req.session.lastBundlePath || '',
        expose: 'dynamicallyBundledJavascript'
    });

    var bundle = b.bundle();

    bundle.on('error', function(err) {
        return res.status(500).send();
    });

    bundle.pipe(res);

};

exports.buildSCSS = function(req, res) {
    res.set('Content-Type', 'text/css');

    var scssData = '#lightning-body {\n';
    scssData += req.body.styles + '\n';
    scssData += '\n}';

    sass.render({
        data: scssData,
        success: function(css) {
            res.send(css);
        }
    });
};

exports.getDynamicVizStyles = function (req, res, next) {

    res.set('Content-Type', 'text/css');

    // Get all vizTypes in array
    var visualizationTypes = _.uniq(req.query.visualizations).sort();
    var styles = cache.get('css/' + visualizationTypes.toString());

    if(styles) {
        return res.send(styles);
    }

    console.log('building viz styles with ' + visualizationTypes);

    models.VisualizationType
        .findAll({
            where: {
                name: {
                    in: visualizationTypes
                }
            }
        }).success(function(vizTypes) {

            var scssData = '#lightning-body {\n';
            _.each(vizTypes, function(vizType) {
                if(vizType.styles) {
                    scssData += vizType.styles  + '\n';
                }
            });

            scssData += '\n}';

            sass.render({
                data: scssData,
                success: function(css) {
                    cache.put('css/' + visualizationTypes.toString(), css, 1000 * 60 * 60);
                    res.send(css);
                }
            });
        }).error(next);

};

<commit_msg>better error output for failed js bundles<commit_after>var models = require('../models');
var _ = require('lodash');
var resumer = require('resumer');
var browserify = require('browserify');
var path = require('path');
var cache = require('../cache');
var sass = require('node-sass');
var uuid = require('node-uuid');
var Q = require('q');

function protectRequire(str) {
    var protectedVars = ['define', 'require'];
    var initialCode = ';';
    var postCode = ';';
    _.each(protectedVars, function(v) {
        initialCode += 'window._' + v + ' = window.' + v + ';';
        initialCode += 'window.' + v + ' = undefined;';

        postCode += 'window.' + v + ' = window._' + v + ';';
    });

    return initialCode + str;// + postCode;

}

exports.getDynamicVizBundle = function (req, res, next) {

    res.set('Content-Type', 'application/javascript');
    res.set('Access-Control-Allow-Origin', "*");

    // Get all vizTypes in array
    var visualizationTypes = _.uniq(req.query.visualizations).sort();

    if(!req.query.cachemiss) {
        var bundle = cache.get('js/' + visualizationTypes.toString());

        if(bundle) {
            return res.send(bundle);
        }
    }

    console.log('building viz bundle with ' + visualizationTypes);
    var tmpPath = path.resolve(__dirname + '/../../tmp/js-build/' + uuid.v4() + '/viz/');

    req.session.lastBundlePath = tmpPath;

    var b = browserify();

    models.VisualizationType
        .findAll().success(function(vizTypes) {

            console.log(_.pluck(vizTypes, 'name'));

            var funcs = [];
            _.each(vizTypes, function(vizType) {
                funcs.push(vizType.exportToFS(tmpPath));
            });

            Q.all(funcs).spread(function() {

                _.each(_.filter(vizTypes, function(vizType) { return (visualizationTypes.indexOf(vizType.name) > -1); }), function(vizType) {

                    var stream = resumer().queue(vizType.javascript).end();
                    b.require(stream, {
                        basedir: tmpPath,
                        expose: 'viz/' + vizType.name
                    });

                });

                b.bundle(function(err, buf) {

                    if(err) {
                        return next(err);
                    }

                    // var out = protectRequire(buf.toString('utf8'));
                    var out = buf.toString('utf8');
                    cache.put('js/' + visualizationTypes.toString(), out, 1000 * 60 * 60);
                    res.send(out);
                });
            });
        }).error(next);

};

exports.bundleJSForExecution = function(req, res, next) {

    res.set('Content-Type', 'application/javascript');

    var b = browserify();

    var js = req.body.javascript;
    var stream = resumer().queue(js).end();
    b.require(stream, {
        basedir: req.session.lastBundlePath || '',
        expose: 'dynamicallyBundledJavascript'
    });

    var bundle = b.bundle();

    bundle.on('error', function(err) {
        console.log(err);
        return res.status(500).send();
    });

    bundle.pipe(res);

};

exports.buildSCSS = function(req, res) {
    res.set('Content-Type', 'text/css');

    var scssData = '#lightning-body {\n';
    scssData += req.body.styles + '\n';
    scssData += '\n}';

    sass.render({
        data: scssData,
        success: function(css) {
            res.send(css);
        }
    });
};

exports.getDynamicVizStyles = function (req, res, next) {

    res.set('Content-Type', 'text/css');

    // Get all vizTypes in array
    var visualizationTypes = _.uniq(req.query.visualizations).sort();
    var styles = cache.get('css/' + visualizationTypes.toString());

    if(styles) {
        return res.send(styles);
    }

    console.log('building viz styles with ' + visualizationTypes);

    models.VisualizationType
        .findAll({
            where: {
                name: {
                    in: visualizationTypes
                }
            }
        }).success(function(vizTypes) {

            var scssData = '#lightning-body {\n';
            _.each(vizTypes, function(vizType) {
                if(vizType.styles) {
                    scssData += vizType.styles  + '\n';
                }
            });

            scssData += '\n}';

            sass.render({
                data: scssData,
                success: function(css) {
                    cache.put('css/' + visualizationTypes.toString(), css, 1000 * 60 * 60);
                    res.send(css);
                }
            });
        }).error(next);

};

<|endoftext|>


<commit_before>/*
 * navigation drawer
 * requires bootstrap's modal js (/assets/js/addons/bootstrap.js)
 */
(function ($) {
	'use strict';

	var Menu = function (element, options) {
		this.ignoreBackdropClick = false;
		this.isShown             = null;
		this.options             = options;
		this.originalBodyPad     = null;
		this.scrollbarWidth      = 0;
		this.$backdrop           = null;
		this.$body               = $(document.body);
		this.$element            = $(element);
		this.$dialog             = this.$element.find('.menu-scroll');
	};

	if (typeof $.fn.modal === 'undefined') {
		throw new Error('Material\'s JavaScript requires Bootstrap\'s modal.js');
	};

	Menu.DEFAULTS = $.extend({}, $.fn.modal.Constructor.DEFAULTS, {});
	Menu.TRANSITION_DURATION = 300;
	Menu.TRANSITION_DURATION_BACKDROP = 150;

	Menu.prototype = $.extend({}, $.fn.modal.Constructor.prototype);

	Menu.prototype.backdrop = function (callback) {
		var that = this;

		if (this.isShown && this.options.backdrop) {
			var doAnimate = $.support.transition;

			this.$backdrop = $(document.createElement('div')).addClass('menu-backdrop').appendTo(this.$body);

			this.$element.on('click.dismiss.bs.menu', $.proxy(function (e) {
				if (this.ignoreBackdropClick) {
					this.ignoreBackdropClick = false;
					return;
				};

				if (e.target !== e.currentTarget) {
					return;
				};

				this.options.backdrop == 'static' ? this.$element[0].focus() : this.hide();
			}, this));

			if (doAnimate) {
				this.$backdrop[0].offsetWidth;
			};

			this.$backdrop.addClass('in');

			if (!callback) {
				return;
			};

			doAnimate ? this.$backdrop.one('bsTransitionEnd', callback).emulateTransitionEnd(Menu.TRANSITION_DURATION_BACKDROP) : callback();
		} else if (!this.isShown && this.$backdrop) {
			this.$backdrop.removeClass('in');

			var callbackRemove = function () {
				that.removeBackdrop();
				callback && callback();
			};

			$.support.transition ? this.$backdrop.one('bsTransitionEnd', callbackRemove).emulateTransitionEnd(Menu.TRANSITION_DURATION_BACKDROP) : callbackRemove();
		} else if (callback) {
			callback();
		};
	};

	Menu.prototype.hide = function (e) {
		if (e) e.preventDefault();

		e = $.Event('hide.bs.menu');

		this.$element.trigger(e);

		if (!this.isShown || e.isDefaultPrevented()) {
			return;
		};

		this.isShown = false;

		this.escape();

		$(document).off('focusin.bs.modal');

		this.$element.removeClass('in').off('click.dismiss.bs.menu').off('mouseup.dismiss.bs.menu');

		this.$dialog.off('mousedown.dismiss.bs.menu');

		$.support.transition ? this.$element.one('bsTransitionEnd', $.proxy(this.hideModal, this)).emulateTransitionEnd(Menu.TRANSITION_DURATION) : this.hideModal();
	};

	Menu.prototype.hideModal = function () {
		var that = this;

		this.$element.hide();

		this.backdrop(function () {
			that.$element.trigger('hidden.bs.menu');
		});
	};

	Menu.prototype.show = function (_relatedTarget) {
		var that = this;
		var e    = $.Event('show.bs.menu', { relatedTarget: _relatedTarget });

		this.$element.trigger(e);

		if (this.isShown || e.isDefaultPrevented()) {
			return;
		};

		this.isShown = true;

		this.escape();

		this.$element.on('click.dismiss.bs.menu', '[data-dismiss="menu"]', $.proxy(this.hide, this));

		this.$dialog.on('mousedown.dismiss.bs.menu', function () {
			that.$element.one('mouseup.dismiss.bs.menu', function (e) {
				if ($(e.target).is(that.$element)) {
					that.ignoreBackdropClick = true;
				};
			});
		});

		this.backdrop(function () {
			var transition = $.support.transition;

			if (!that.$element.parent().length) {
				that.$element.appendTo(that.$body);
			};

			that.$element.show();

			if (transition) {
				that.$element[0].offsetWidth;
			};

			that.$element.addClass('in');

			that.enforceFocus();

			var e = $.Event('shown.bs.menu', { relatedTarget: _relatedTarget });

			transition ? that.$dialog.one('bsTransitionEnd', function () {
				that.$element.trigger('focus').trigger(e);
			}).emulateTransitionEnd(Menu.TRANSITION_DURATION) : that.$element.trigger('focus').trigger(e);
		});
	};

	function Plugin (option, _relatedTarget) {
		return this.each(function () {
			var $this   = $(this);
			var data    = $this.data('bs.menu');
			var options = $.extend({}, Menu.DEFAULTS, $this.data(), typeof option == 'object' && option);

			if (!data) $this.data('bs.menu', (data = new Menu(this, options)));
			if (typeof option == 'string') data[option](_relatedTarget);
			else if (options.show) data.show(_relatedTarget);
		});
	};

	var old = $.fn.menu;

	$.fn.menu             = Plugin;
	$.fn.menu.Constructor = Menu;

	$.fn.menu.noConflict = function () {
		$.fn.menu = old;
		return this;
	};

	$(document).on('click.bs.menu.data-api', '[data-toggle="menu"]', function (e) {
		var $this   = $(this);
		var href    = $this.attr('href');
		var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')));
		var option  = $target.data('bs.menu') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

		if ($this.is('a')) e.preventDefault();

		$target.one('show.bs.menu', function (showEvent) {
			if (showEvent.isDefaultPrevented()) {
				return;
			} else {
				$target.attr('tabindex', '-1');
			};

			$target.one('hidden.bs.menu', function () {
				$this.is(':visible') && $this.trigger('focus');
			});
		});

		Plugin.call($target, option, this);
	});
}(jQuery));
<commit_msg>update menu.js to work with bootstrap 4's js<commit_after>// todo: rename "menu" to "navdrawer" based on material design specs
// https://www.google.com/design/spec/patterns/navigation-drawer.html

/*
 * navigation drawer
 * based on Bootstrap's (v4.0.0-alpha.2) modal.js
 */
var Menu = (function ($) {
  var BACKDROP_TRANSITION_DURATION = 150;
  var DATA_API_KEY = '.data-api';
  var DATA_KEY = 'md.menu';
  var EVENT_KEY = '.' + DATA_KEY;
  var NAME = 'menu';
  var NO_CONFLICT = $.fn[NAME];
  var TRANSITION_DURATION = 300;

  var ClassName = {
    BACKDROP: 'menu-backdrop',
    IN: 'in',
    OPEN: 'menu-open'
  };

  var Default = {
    keyboard: true,
    show: true
  };

  var DefaultType = {
    keyboard: 'boolean',
    show: 'boolean'
  };

  var Event = {
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
    CLICK_DISMISS: 'click.dismiss' + EVENT_KEY,
    FOCUSIN: 'focusin' + EVENT_KEY,
    HIDDEN: 'hidden' + EVENT_KEY,
    HIDE: 'hide' + EVENT_KEY,
    KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY,
    MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY,
    MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY,
    SHOW: 'show' + EVENT_KEY,
    SHOWN: 'shown' + EVENT_KEY
  };

  var Selector = {
    CONTENT: '.menu-scroll',
    DATA_DISMISS: '[data-dismiss="menu"]',
    DATA_TOGGLE: '[data-toggle="menu"]'
  };

  var Menu = (function () {
    function Menu(element, config) {
      _classCallCheck(this, Menu);

      this._backdrop = null;
      this._config = this._getConfig(config);
      this._content = $(element).find(Selector.CONTENT)[0];
      this._element = element;
      this._ignoreBackdropClick = false;
      this._isShown = false;
    }

    _createClass(Menu, [{
      key: 'hide',
      value: function hide(event) {
        if (event) {
          event.preventDefault();
        };

        var hideEvent = $.Event(Event.HIDE);

        $(this._element).trigger(hideEvent);

        if (!this._isShown || hideEvent.isDefaultPrevented()) {
          return;
        };

        this._isShown = false;
        this._setEscapeEvent();
        $(document).off(Event.FOCUSIN);
        $(this._element).removeClass(ClassName.IN);
        $(this._element).off(Event.CLICK_DISMISS);
        $(this._content).off(Event.MOUSEDOWN_DISMISS);

        if (Util.supportsTransitionEnd()) {
          $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideMenu, this)).emulateTransitionEnd(TRANSITION_DURATION);
        } else {
          this._hideMenu();
        };
      }
    }, {
      key: 'show',
      value: function show(relatedTarget) {
        var _this = this;
        var showEvent = $.Event(Event.SHOW, {
          relatedTarget: relatedTarget
        });

        $(this._element).trigger(showEvent);

        if (this._isShown || showEvent.isDefaultPrevented()) {
          return;
        };

        this._isShown = true;
        $(document.body).addClass(ClassName.OPEN);
        this._setEscapeEvent();
        $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this));

        $(this._content).on(Event.MOUSEDOWN_DISMISS, function () {
          $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
            if ($(event.target).is(_this._element)) {
              _this._ignoreBackdropClick = true;
            };
          });
        });

        this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
      }
    }, {
      key: 'toggle',
      value: function toggle(relatedTarget) {
        return this._isShown ? this.hide() : this.show(relatedTarget);
      }
    }, {
      key: '_enforceFocus',
      value: function _enforceFocus() {
        var _this = this;

        $(document).off(Event.FOCUSIN).on(Event.FOCUSIN, function (event) {
          if (_this._element !== event.target && !$(_this._element).has(event.target).length) {
            _this._element.focus();
          };
        });
      }
    }, {
      key: '_getConfig',
      value: function _getConfig(config) {
        config = $.extend({}, Default, config);
        Util.typeCheckConfig(NAME, config, DefaultType);
        return config;
      }
    }, {
      key: '_hideMenu',
      value: function _hideMenu() {
        var _this = this;

        this._showBackdrop(function () {
          $(document.body).removeClass(ClassName.OPEN);
          $(_this._element).trigger(Event.HIDDEN);
        });
      }
    }, {
      key: '_removeBackdrop',
      value: function _removeBackdrop() {
        if (this._backdrop) {
          $(this._backdrop).remove();
          this._backdrop = null;
        };
      }
    }, {
      key: '_setEscapeEvent',
      value: function _setEscapeEvent() {
        var _this = this;

        if (this._isShown && this._config.keyboard) {
          $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
            if (event.which === 27) {
              _this.hide();
            }
          });
        } else if (!this._isShown) {
          $(this._element).off(Event.KEYDOWN_DISMISS);
        };
      }
    }, {
      key: '_showBackdrop',
      value: function _showBackdrop(callback) {
        var _this = this;

        if (this._isShown) {
          var doAnimate = Util.supportsTransitionEnd();

          this._backdrop = document.createElement('div');
          this._backdrop.className = ClassName.BACKDROP;
          $(this._backdrop).addClass('fade');

          $(this._backdrop).appendTo(document.body);
          $(this._element).on(Event.CLICK_DISMISS, function (event) {
            if (_this._ignoreBackdropClick) {
              _this._ignoreBackdropClick = false;
              return;
            };

            if (event.target !== event.currentTarget) {
              return;
            };

            _this.hide();
          });

          if (doAnimate) {
            Util.reflow(this._backdrop);
          };

          $(this._backdrop).addClass(ClassName.IN);

          if (!callback) {
            return;
          };

          if (!doAnimate) {
            callback();
            return;
          };

          $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
        } else if (this._backdrop) {
          $(this._backdrop).removeClass(ClassName.IN);

          var callbackRemove = function callbackRemove() {
            _this._removeBackdrop();

            if (callback) {
              callback();
            };
          };

          if (Util.supportsTransitionEnd()) {
            $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
          } else {
            callbackRemove();
          };
        } else if (callback) {
          callback();
        };
      }
    }, {
      key: '_showElement',
      value: function _showElement(relatedTarget) {
        var _this = this;
        var transition = Util.supportsTransitionEnd();

        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
          document.body.appendChild(this._element);
        };

        if (transition) {
          Util.reflow(this._element);
        };

        $(this._element).addClass(ClassName.IN);
        this._enforceFocus();

        var shownEvent = $.Event(Event.SHOWN, {
          relatedTarget: relatedTarget
        });

        var transitionComplete = function transitionComplete() {
          _this._element.focus();
          $(_this._element).trigger(shownEvent);
        };

        if (transition) {
          $(this._content).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
        } else {
          transitionComplete();
        };
      }
    }], [{
      key: 'Default',
      get: function get() {
        return Default;
      }
    }, {
      key: '_jQueryInterface',
      value: function _jQueryInterface(config, relatedTarget) {
        return this.each(function () {
          var data = $(this).data(DATA_KEY);
          var _config = $.extend({}, Menu.Default, $(this).data(), typeof config === 'object' && config);

          if (!data) {
            data = new Menu(this, _config);
            $(this).data(DATA_KEY, data);
          };

          if (typeof config === 'string') {
            if (data[config] === undefined) {
              throw new Error('No method named "' + config + '"');
            };
            data[config](relatedTarget);
          } else if (_config.show) {
            data.show(relatedTarget);
          };
        });
      }
    }]);

    return Menu;
  })();

  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
    var _this = this;
    var selector = Util.getSelectorFromElement(this);
    var target = undefined;

    if (selector) {
      target = $(selector)[0];
    };

    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());

    if (this.tagName === 'A') {
      event.preventDefault();
    };

    var $target = $(target).one(Event.SHOW, function (showEvent) {
      if (showEvent.isDefaultPrevented()) {
        return;
      };

      $target.one(Event.HIDDEN, function () {
        if ($(_this).is(':visible')) {
          _this.focus();
        };
      });
    });

    Menu._jQueryInterface.call($(target), config, this);
  });

  $.fn[NAME] = Menu._jQueryInterface;
  $.fn[NAME].Constructor = Menu;
  $.fn[NAME].noConflict = function () {
    $.fn[NAME] = NO_CONFLICT;
    return Menu._jQueryInterface;
  };

  return Menu;
})(jQuery);
<|endoftext|>


<commit_before>// Init Select2
window.aeria_init_select2 = function(){
	jQuery(function(){
		(function(formatRes,formatSel){
			jQuery('.select2:not(.multisettings)').each(function(idx,e){
				var $this = jQuery(e);
				if( ! $this.data("select2")){
					$this.select2({
						formatResult: formatRes,
						minimumInputLength: $this.data('minimum'),
						formatSelection: formatSel || undefined,
						escapeMarkup: function(m) { return m; }
					}).on('select2-loaded',function(){
						this.addClass('loaded').css({opacity:1});
					});
				}
			});
		})(
		function(state){
      if (!state.id) return state.text; // optgroup
      var originalOption = state.element,
      $me = jQuery(originalOption);
      var tmp = '';
      if($me.data('image')) {
      	tmp += '

'+$me.data('html')+'
';
      } else {
      	tmp += $me.data('html') || state.text;
      }
      return tmp ;
  },
  function(state){
  	var originalOption = state.element,
  	$me = jQuery(originalOption);
  	var tmp = '';
  	if($me.data('image')) {
  		tmp += '

'+$me.data('html')+'

';
  	} else {
  		tmp += $me.data('html') || state.text;
  	}
  	return tmp ;
  });
	});
};

window.aeria_init_select2_ajax = function(){
	jQuery(function(){
		(function(formatRes,formatSel){
			jQuery('.select2_ajax').each(function(idx,e){
				var $this = jQuery(e);
				var posts_per_page = 10;
				var multiple = $this.attr('data-multiple');
				if(multiple=="true") {
					multiple = true;
				}else{
					multiple = false;
				}
				var relation = $this.attr('data-relation');
				if( ! $this.data("select2")){
					$this.select2({
						minimumInputLength: 0,
						formatResult: formatRes,
						formatSelection: formatSel || undefined,
						allowClear: true,
						multiple: multiple,
						ajax: {
							url: "/wp/wp-admin/admin-ajax.php",
							dataType: 'json',
							quietMillis: 300,
							data: function (term, page) {
								return {
								  q: term,
								  page: page,
								  posts_per_page : posts_per_page,
								  action: 'aeria_search',
								  post_type: relation
								};
							},
							results: function (data, page) {
								var more = (page * posts_per_page) < data.total;
								return { results: data.result, more: more };
							},
    					},
						initSelection: function(element, callback) {

							var id=$this.val();
							if (id!=''||id!='-') {

							    jQuery.ajax("/wp/wp-admin/admin-ajax.php", {
							        data: {
							            id : id,
							            action : 'aeria_search_init',
							            multiple : multiple
							        },
							        dataType: "json"
							    }).done(function(data) {
							    	callback(data);
							    });
							}
						},
					});
				}
			});
		})();
	});
};

window.aeria_init_select2_ajax();
window.aeria_init_select2();<commit_msg>Fixed ajaxurl bug<commit_after>// Init Select2
window.aeria_init_select2 = function(){
	jQuery(function(){
		(function(formatRes,formatSel){
			jQuery('.select2:not(.multisettings)').each(function(idx,e){
				var $this = jQuery(e);
				if( ! $this.data("select2")){
					$this.select2({
						formatResult: formatRes,
						minimumInputLength: $this.data('minimum'),
						formatSelection: formatSel || undefined,
						escapeMarkup: function(m) { return m; }
					}).on('select2-loaded',function(){
						this.addClass('loaded').css({opacity:1});
					});
				}
			});
		})(
		function(state){
      if (!state.id) return state.text; // optgroup
      var originalOption = state.element,
      $me = jQuery(originalOption);
      var tmp = '';
      if($me.data('image')) {
      	tmp += '

'+$me.data('html')+'
';
      } else {
      	tmp += $me.data('html') || state.text;
      }
      return tmp ;
  },
  function(state){
  	var originalOption = state.element,
  	$me = jQuery(originalOption);
  	var tmp = '';
  	if($me.data('image')) {
  		tmp += '

'+$me.data('html')+'

';
  	} else {
  		tmp += $me.data('html') || state.text;
  	}
  	return tmp ;
  });
	});
};

window.aeria_init_select2_ajax = function(){
	jQuery(function(){
		(function(formatRes,formatSel){
			jQuery('.select2_ajax').each(function(idx,e){
				var $this = jQuery(e);
				var posts_per_page = 10;
				var multiple = $this.attr('data-multiple');
				if(multiple=="true") {
					multiple = true;
				}else{
					multiple = false;
				}
				var relation = $this.attr('data-relation');
				if( ! $this.data("select2")){
					$this.select2({
						minimumInputLength: 0,
						formatResult: formatRes,
						formatSelection: formatSel || undefined,
						allowClear: true,
						multiple: multiple,
						ajax: {
							url: window.ajaxurl,
							dataType: 'json',
							quietMillis: 300,
							data: function (term, page) {
								return {
								  q: term,
								  page: page,
								  posts_per_page : posts_per_page,
								  action: 'aeria_search',
								  post_type: relation
								};
							},
							results: function (data, page) {
								var more = (page * posts_per_page) < data.total;
								return { results: data.result, more: more };
							},
    					},
						initSelection: function(element, callback) {

							var id=$this.val();
							if (id!=''||id!='-') {

							    jQuery.ajax(window.ajaxurl, {
							        data: {
							            id : id,
							            action : 'aeria_search_init',
							            multiple : multiple
							        },
							        dataType: "json"
							    }).done(function(data) {
							    	callback(data);
							    });
							}
						},
					});
				}
			});
		})();
	});
};

window.aeria_init_select2_ajax();
window.aeria_init_select2();
<|endoftext|>


<commit_before>var mongoose = require('mongoose')
    , Truck = mongoose.model('Truck')
    , Feed = mongoose.model('Feed')

exports.get = function (req, res) {
    Truck
        .find({})
        .exec(function (err, trucks) {
            if (err) throw err
            if (trucks) res.json(trucks)
        })
}

function populateTruck (params, truck, user) {
     console.log(req.user)
     truck.date=Date.now()
     if (params.temporality) truck.temporality = params.temporality
     if (params.location) truck.location = params.location
     if (params.validity) truck.validity = params.validity
     truck.version++
     var id = params.id
     Feed
         .findOne({id : _id})
         .exec(function (err, tweet) {
             if (err) throw err
             if (tweet) {
                tweet.username =
                tweet.version = truck.version
                truck.tweets.push(tweet)
             }else {

             }
         })
}

exports.post = function (req, res) {
    var params = null
    if (req.params) params = req.params
    if (req.body) params = req.body

    if (!params) return null

    Truck
        .findOne({truckName: req.truckName})
        .exec(function (err, truck) {
            if (err) throw err
            if (!truck) {
                console.log("New truck created...")
                var truck = new Truck()
            }
            console.log(truck)
            populateTruck(params, truck, req.user)
        })

    res.send("ok")
    return null
}
<commit_msg>can add trucks, need to add features<commit_after>var mongoose = require('mongoose')
    , Truck = mongoose.model('Truck')
    , Feed = mongoose.model('Feed')

exports.get = function (req, res) {
    Truck
        .find({})
        .exec(function (err, trucks) {
            if (err) throw err
            if (trucks) res.json(trucks)
        })
}

function populateTruck (params, truck, user) {
     console.log(user)
     //if (!user) return null
     truck.date=Date.now()

     if (params.temporality) truck.temporality = params.temporality
     if (params.location) truck.location = params.location
     if (params.validity) truck.validity = params.validity
     truck.version++
     var id = params.id
     Feed
         .findOne({_id : id})
         .exec(function (err, tweet) {
             if (err) throw err
             if (tweet) {
                tweet.username = user
                tweet.version = truck.version
                truck.tweets.push(tweet)
             }
             truck.save()
         })
}

exports.post = function (req, res) {
    var params = null
    if (req.params) params = req.params
    if (req.body) params = req.body

    if (!params) return null

    Truck
        .findOne({truckName: params.truckname})
        .exec(function (err, truck) {
            if (err) throw err
            if (!truck) {
                console.log("New truck created...")
                var truck = new Truck()
                truck.truckName=params.truckname
            }
            console.log(truck)
            populateTruck(params, truck, req.user)
        })

    res.send("ok")
    return null
}
<|endoftext|>