<commit_before>$(function () {
    var hasInit = false;
    var hash = 1;
    var async = function (bool) {
        $.ajaxSetup({
            async: bool
        });
    }

    var gallery = function (el, settings) {
        var csrf = $.ajaxSetup().data.csrf_test_name;
        var async_default = $.ajaxSetup().async;
        async(false);
        var permissions = $.getJSON(url + "apps/gallery/list-permissions").responseJSON;
        var lang = $.getJSON(url + "apps/gallery/list-lang").responseJSON;
        async(async_default);
        var self = this;
        var config = {
            limit_select: null, // multiple default
            files_selecteds: [], // String or array
            saved_list: [],
            complete: function (files) {}, // callback function
            /*Config upload*/
            extensions_allowed: null,
            image_resize: null,
            image_y: null,
            image_x: null,
            image_ratio: null,
            image_ratio_x: null,
            image_ratio_y: null,
            image_ratio_crop: null,
            image_ratio_fill: null,
            image_background_color: null,
            image_convert: null,
            image_text: null,
            image_text_color: null,
            image_text_background: null,
            image_text_opacity: null,
            image_text_background_opacity: null,
            image_text_padding: null,
            image_text_position: null,
            image_text_direction: null,
            image_text_x: null,
            image_text_y: null,
            image_thumbnails: null
        };
        var selector = {
            modal: ".gallery-upload-modal",
            content_modal: ".gallery-upload-modal #files-content",
            current_modal: null,
            container_modal: ".main_container > .right_col",
            btn_save: ".gallery-upload-modal #btn-save-change",
            btn_add: ".gallery-upload-modal #list-files .btn-add",
            modal_footer: ".gallery-upload-modal .modal-footer",
            upload_config: "#upload_config",
            image_file: ".gallery-upload-modal .image-file",
            current_file: ".file",
            fancybox: ".fancybox",
            input_search: ".gallery-upload-modal #search-files",
            pagination: ".gallery-upload-modal #list-files .btn-page"
        };
        config = $.extend(config, settings);
        config.saved_list = config.files_selecteds;
        selector.current_modal = "#gallery-upload-" + hash++;
        var fancybox = selector.fancybox;
        var current_modal = selector.current_modal;
        var btn_save = current_modal + selector.btn_save;
        var btn_add = current_modal + selector.btn_add;
        var input_search = current_modal + selector.input_search;
        var pagination = current_modal + selector.pagination;
        var container_modal = selector.container_modal;

        var load_dependencies = function () {
            // Carrega os plugins e o modal apenas uma vez para o template
            var template_modal = new EJS({url: url + "application/apps/gallery/assets/ejs/modal.ejs"}).render({
                perm: permissions,
                lang: lang,
                url: url,
                csrf_test_name: csrf
            });
            $(container_modal).append(template_modal);

            // Carrega Dropzone
            if (typeof Dropzone == 'function') {
                Dropzone.autoDiscover = false;
                var myDropzone = new Dropzone("#dropzone_gallery");
                // Atualizar lista de arquivos ao fazer upload
                myDropzone.on("complete", function () {
                    list_files({});
                });
            }
        }

        var load_fancybox = function () {
            $(fancybox).attr('rel', 'gallery').fancybox({
                nextEffect: 'fade',
                prevEffect: 'fade',
                openEffect: 'elastic',
                closeEffect: 'elastic',
                autoCenter: true,
                padding: 0,
                margin: 20,
                arrows: true,
                mouseWheel: true,
                fitToView: true,
            });

            $(fancybox).attr('rel', 'gallery').fancybox({
                beforeShow: function () {
                    /* Disable right click */
                    $.fancybox.wrap.bind("contextmenu", function (e) {
                        return false;
                    });
                }
            });
        }

        var treat_list_selected = function (el) {
            config.files_selecteds = JSON.parse(JSON.stringify(config.saved_list));
            var files = config.files_selecteds;
            if (files !== null && typeof files != 'array') {
                files = new Array();
                files[0] = files;
            }
        }

        var list_files = function (param) {
            var content = $(selector.content_modal);
            if (param.url === '' || param.url === undefined) {
                param.url = url + "apps/gallery/files-list"
            }

            content.html('

');
            var config_upload = $(selector.upload_config).val();
            $.ajax({
                url: param.url,
                type: "POST",
                data: {limit: 18, config: config_upload, saved_list: config.saved_list, modal: true},
                success: function (template) {
                    content.html(template);
                    load_fancybox();
                }
            });
        }

        // public method
        this.save_list = function () {
            var self = this;
            config.saved_list = JSON.parse(JSON.stringify(config.files_selecteds));
            // Callback
            config.complete(config.saved_list);
        }

        // public method
        this.reset_selecteds = function () {
            config.files_selecteds = [];
            config.saved_list = [];
        }

        // public method
        this.delete_file = function (file) {
            var files = config.files_selecteds;
            if (files == undefined || typeof files != "object") {
                files = new Array();
            }

            var new_list = new Array();
            for (var x = 0; x<files.length; x++){
                var file_current = files[x];
                if (file_current != file) {
                    new_list.push(file_current);
                }
            }

            config.files_selecteds = new_list;
        }

        // public method
        this.add_file = function (file) {
            var files = config.files_selecteds;
            if (files == undefined || typeof files != "object") {
                files = new Array();
            }

            var file_current = files.length;
            files[file_current] = file;

            config.files_selecteds = files;
        }

        if (!hasInit) {
            load_dependencies();
            hasInit = true;
        }

        el.click(function (e) {
            var modal = selector.modal;
            var modal_footer = selector.modal_footer;
            var upload_config = selector.upload_config;
            var limit_select = config.limit_select;

            treat_list_selected(el);

            $(modal).modal("show");
            $(modal).attr("id", selector.current_modal.replace("#", ""));
            if (permissions.app !== true || limit_select === 1) {
                $(modal_footer).addClass("hide");
            } else {
                $(modal_footer).removeClass("hide");
            }

            $(upload_config).val(JSON.stringify({
                extensions_allowed: config.extensions_allowed,
                image_resize: config.image_resize,
                image_y: config.image_y,
                image_x: config.image_x,
                image_ratio: config.image_ratio,
                image_ratio_x: config.image_ratio_x,
                image_ratio_y: config.image_ratio_y,
                image_ratio_crop: config.image_ratio_crop,
                image_ratio_fill: config.image_ratio_fill,
                image_background_color: config.image_background_color,
                image_convert: config.image_convert,
                image_text: config.image_text,
                image_text_color: config.image_text_color,
                image_text_background: config.image_text_background,
                image_text_opacity: config.image_text_opacity,
                image_text_background_opacity: config.image_text_background_opacity,
                image_text_padding: config.image_text_padding,
                image_text_position: config.image_text_position,
                image_text_direction: config.image_text_direction,
                image_text_x: config.image_text_x,
                image_text_y: config.image_text_y,
                image_thumbnails: config.image_thumbnails,
            }));

            list_files({});
        });

        $(container_modal).on("click", btn_save, function () {
            var modal = selector.modal;
            self.save_list();
            $(modal).modal('hide');
        });
        $(container_modal).on("click", btn_add, function () {
            var modal = selector.modal;
            var btn_add = selector.btn_add;
            var index = $(btn_add).index(this);
            var image_file = selector.image_file;
            var limit_select = config.limit_select;
            var file = $(selector.current_file).eq(index).data('file');
            if (limit_select === 1) {
                self.reset_selecteds();
                self.add_file(file);
                self.save_list();

                $(modal).modal('hide');
            } else {
                if ($(image_file).eq(index).hasClass("active")) {
                    self.delete_file(file);
                    $(image_file).eq(index).removeClass("active");
                } else {
                    self.add_file(file);
                    $(image_file).eq(index).addClass("active");
                }
            }
        });

        /*
         * Search
         */
        $(container_modal).on("submit", input_search, function (e) {
            var keyword = $("#search-field").val();
            list_files({
                url: url + 'apps/gallery/files-list?search=' + keyword
            });

            e.preventDefault();
            return false;
        });

        /*
         * Pagination
         */
        $(container_modal).on("click", pagination, function (e) {
            list_files({
                url: $(this).attr("href")
            });

            e.preventDefault();
            return false;
        });
    }

    $.fn.gallery = function (settings) {
        var el = $(this);
        if (el.data('gallery')) {
            return el.data('gallery');
        }

        var plugin = new gallery(el, settings);
        el.data('gallery', plugin);
        return gallery;
    }
});<commit_msg>Correção de erro na exibição de modal multiupload<commit_after>$(function () {
    var hasInit = false;
    var hash = 1;
    var async = function (bool) {
        $.ajaxSetup({
            async: bool
        });
    }

    var gallery = function (el, settings) {
        var csrf = $.ajaxSetup().data.csrf_test_name;
        var async_default = $.ajaxSetup().async;
        async(false);
        var permissions = $.getJSON(url + "apps/gallery/list-permissions").responseJSON;
        var lang = $.getJSON(url + "apps/gallery/list-lang").responseJSON;
        async(async_default);
        var self = this;
        var config = {
            limit_select: null, // multiple default
            files_selecteds: [], // String or array
            saved_list: [],
            complete: function (files) {}, // callback function
            /*Config upload*/
            extensions_allowed: null,
            image_resize: null,
            image_y: null,
            image_x: null,
            image_ratio: null,
            image_ratio_x: null,
            image_ratio_y: null,
            image_ratio_crop: null,
            image_ratio_fill: null,
            image_background_color: null,
            image_convert: null,
            image_text: null,
            image_text_color: null,
            image_text_background: null,
            image_text_opacity: null,
            image_text_background_opacity: null,
            image_text_padding: null,
            image_text_position: null,
            image_text_direction: null,
            image_text_x: null,
            image_text_y: null,
            image_thumbnails: null
        };
        var selector = {
            modal: ".gallery-upload-modal",
            content_modal: ".gallery-upload-modal #files-content",
            current_modal: null,
            container_modal: ".main_container > .right_col",
            btn_save: ".gallery-upload-modal #btn-save-change",
            btn_add: ".gallery-upload-modal #list-files .btn-add",
            modal_footer: ".gallery-upload-modal .modal-footer",
            upload_config: "#upload_config",
            image_file: ".gallery-upload-modal .image-file",
            current_file: ".file",
            fancybox: ".fancybox",
            input_search: ".gallery-upload-modal #search-files",
            pagination: ".gallery-upload-modal #list-files .btn-page"
        };
        config = $.extend(config, settings);
        config.saved_list = config.files_selecteds;
        selector.current_modal = "#gallery-upload-" + hash++;
        var fancybox = selector.fancybox;
        var current_modal = selector.current_modal;
        var btn_save = current_modal + selector.btn_save;
        var btn_add = current_modal + selector.btn_add;
        var input_search = current_modal + selector.input_search;
        var pagination = current_modal + selector.pagination;
        var container_modal = selector.container_modal;

        var load_dependencies = function () {
            // Carrega os plugins e o modal apenas uma vez para o template
            var template_modal = new EJS({url: url + "application/apps/gallery/assets/ejs/modal.ejs"}).render({
                perm: permissions,
                lang: lang,
                url: url,
                csrf_test_name: csrf
            });
            $(container_modal).append(template_modal);

            // Carrega Dropzone
            if (typeof Dropzone == 'function') {
                Dropzone.autoDiscover = false;
                var myDropzone = new Dropzone("#dropzone_gallery");
                // Atualizar lista de arquivos ao fazer upload
                myDropzone.on("complete", function () {
                    list_files({});
                });
            }
        }

        var load_fancybox = function () {
            $(fancybox).attr('rel', 'gallery').fancybox({
                nextEffect: 'fade',
                prevEffect: 'fade',
                openEffect: 'elastic',
                closeEffect: 'elastic',
                autoCenter: true,
                padding: 0,
                margin: 20,
                arrows: true,
                mouseWheel: true,
                fitToView: true,
            });

            $(fancybox).attr('rel', 'gallery').fancybox({
                beforeShow: function () {
                    /* Disable right click */
                    $.fancybox.wrap.bind("contextmenu", function (e) {
                        return false;
                    });
                }
            });
        }

        var treat_list_selected = function (el) {
            config.files_selecteds = JSON.parse(JSON.stringify(config.saved_list));
            var files = config.files_selecteds;
            if (files !== null && typeof files != 'array') {
                files = new Array();
                files[0] = files;
            }
        }

        var list_files = function (param) {
            var content = $(selector.content_modal);
            if (param.url === '' || param.url === undefined) {
                param.url = url + "apps/gallery/files-list"
            }

            content.html('

');
            var config_upload = $(selector.upload_config).val();
            $.ajax({
                url: param.url,
                type: "POST",
                data: {limit: 18, config: config_upload, saved_list: config.saved_list, modal: true},
                success: function (template) {
                    content.html(template);
                    load_fancybox();
                }
            });
        }

        // public method
        this.save_list = function () {
            var self = this;
            config.saved_list = JSON.parse(JSON.stringify(config.files_selecteds));
            // Callback
            config.complete(config.saved_list);
        }

        // public method
        this.reset_selecteds = function () {
            config.files_selecteds = [];
            config.saved_list = [];
        }

        // public method
        this.delete_file = function (file) {
            var files = config.files_selecteds;
            if (files == undefined || typeof files != "object") {
                files = new Array();
            }

            var new_list = new Array();
            for (var x = 0; x<files.length; x++){
                var file_current = files[x];
                if (file_current != file) {
                    new_list.push(file_current);
                }
            }

            config.files_selecteds = new_list;
        }

        // public method
        this.add_file = function (file) {
            var files = config.files_selecteds;
            if (files == undefined || typeof files != "object") {
                files = new Array();
            }

            var file_current = files.length;
            files[file_current] = file;

            config.files_selecteds = files;
        }

        if (!hasInit) {
            load_dependencies();
            hasInit = true;
        }

        el.click(function (e) {
            var modal = selector.modal;
            var modal_footer = selector.modal_footer;
            var upload_config = selector.upload_config;
            var limit_select = config.limit_select;

            treat_list_selected(el);

            $(modal).modal("show");
            $(modal).attr("id", selector.current_modal.replace("#", ""));
            if (permissions.app != '1' || limit_select === 1) {
                $(modal_footer).addClass("hide");
            } else {
                $(modal_footer).removeClass("hide");
            }

            $(upload_config).val(JSON.stringify({
                extensions_allowed: config.extensions_allowed,
                image_resize: config.image_resize,
                image_y: config.image_y,
                image_x: config.image_x,
                image_ratio: config.image_ratio,
                image_ratio_x: config.image_ratio_x,
                image_ratio_y: config.image_ratio_y,
                image_ratio_crop: config.image_ratio_crop,
                image_ratio_fill: config.image_ratio_fill,
                image_background_color: config.image_background_color,
                image_convert: config.image_convert,
                image_text: config.image_text,
                image_text_color: config.image_text_color,
                image_text_background: config.image_text_background,
                image_text_opacity: config.image_text_opacity,
                image_text_background_opacity: config.image_text_background_opacity,
                image_text_padding: config.image_text_padding,
                image_text_position: config.image_text_position,
                image_text_direction: config.image_text_direction,
                image_text_x: config.image_text_x,
                image_text_y: config.image_text_y,
                image_thumbnails: config.image_thumbnails,
            }));

            list_files({});
        });

        $(container_modal).on("click", btn_save, function () {
            var modal = selector.modal;
            self.save_list();
            $(modal).modal('hide');
        });
        $(container_modal).on("click", btn_add, function () {
            var modal = selector.modal;
            var btn_add = selector.btn_add;
            var index = $(btn_add).index(this);
            var image_file = selector.image_file;
            var limit_select = config.limit_select;
            var file = $(selector.current_file).eq(index).data('file');
            if (limit_select === 1) {
                self.reset_selecteds();
                self.add_file(file);
                self.save_list();

                $(modal).modal('hide');
            } else {
                if ($(image_file).eq(index).hasClass("active")) {
                    self.delete_file(file);
                    $(image_file).eq(index).removeClass("active");
                } else {
                    self.add_file(file);
                    $(image_file).eq(index).addClass("active");
                }
            }
        });

        /*
         * Search
         */
        $(container_modal).on("submit", input_search, function (e) {
            var keyword = $("#search-field").val();
            list_files({
                url: url + 'apps/gallery/files-list?search=' + keyword
            });

            e.preventDefault();
            return false;
        });

        /*
         * Pagination
         */
        $(container_modal).on("click", pagination, function (e) {
            list_files({
                url: $(this).attr("href")
            });

            e.preventDefault();
            return false;
        });
    }

    $.fn.gallery = function (settings) {
        var el = $(this);
        if (el.data('gallery')) {
            return el.data('gallery');
        }

        var plugin = new gallery(el, settings);
        el.data('gallery', plugin);
        return gallery;
    }
});<|endoftext|>


<commit_before>'use strict';

var ap = require('ap');
var d = require('../decorators');
var fs = require('fs');
var merge = require('merge');
var q = require('q');
var cons = require('consolidate');

var writeFile;

Object.keys(cons).forEach(function (engine) {
  var renderFile;

  exports[engine] = d.push(d.srcDest(function (src, dest, options) {
    // Lazy
    renderFile = renderFile || q.denodeify(cons[engine]);
    writeFile = writeFile || q.denodeify(fs.writeFile);

    // Merge options
    var ctx = merge(true, this.ctx, options);

    // Write destination callback
    var writeDest = ap([dest], writeFile);

    // Ensure base path is set
    this.base(dest);

    // Render, then write
    return renderFile(src, ctx).then(writeDest);
  }));
});
<commit_msg>Fix merge options<commit_after>'use strict';

var ap = require('ap');
var d = require('../decorators');
var fs = require('fs');
var merge = require('merge');
var q = require('q');
var cons = require('consolidate');

var writeFile;

Object.keys(cons).forEach(function (engine) {
  var renderFile;

  exports[engine] = d.push(d.srcDest(function (src, dest, options) {
    // Lazy
    renderFile = renderFile || q.denodeify(cons[engine]);
    writeFile = writeFile || q.denodeify(fs.writeFile);

    // Merge options
    var ctx = merge({}, this.ctx, options);

    // Write destination callback
    var writeDest = ap([dest], writeFile);

    // Ensure base path is set
    this.base(dest);

    // Render, then write
    return renderFile(src, ctx).then(writeDest);
  }));
});
<|endoftext|>


<commit_before>//
// JaySchema (draft v4) validator for Node.js.
//

'use strict';

var jsonPointer = require('./jsonPointer.js')
  , url = require('url')
  , downloadSchema = require('./downloadSchema.js')
  , Errors = require('./errors.js')
  , uuid = require('./uuid.js')
  ;

var DEFAULT_SCHEMA_VERSION = 'http://json-schema.org/draft-04/schema#';
var ANON_URI_SCHEME = 'anon-schema';

var schemaTestSets = {
  'http://json-schema.org/draft-04/schema#': require('./suites/draft-04.js')
};

// ******************************************************************
// Constructor
// ******************************************************************
var JaySchema = function(maxPreload) {
  this.schemas = {};
  this._urlsRequested = [];
  this.maxPreload = maxPreload || 5;
};

// ******************************************************************
// Register the given schema in our library of schemas.
// ******************************************************************
JaySchema.prototype.register = function(schema, resolutionScope, _fallbackId,
  _path)
{
  // We stash each schema that has a unique URI, not including
  // the fragment part.

  var id = schema.id || _fallbackId;
  if (id) {
    var resolvedId = jsonPointer.resolve(resolutionScope, id);
    resolutionScope = resolvedId;
    var parts = url.parse(resolvedId);
    var fragment = parts.hash;
    delete parts.hash;
    var baseUri = url.format(parts);

    if (!fragment || fragment === '#' || fragment === '') {
      // top-level schema
      if (this.schemas.hasOwnProperty(baseUri)) {
        // this and its sub-schemas are already registered
        return;
      }
      this.schemas[baseUri] = { schema: schema, fragments: {} };
      _path = '#';
    } else {
      // fragment reference within a top-level schema
      if (this.schemas.hasOwnProperty(baseUri)) {
        if (!this.schemas[baseUri].fragments.hasOwnProperty(fragment)) {
          this.schemas[baseUri].fragments[fragment] = _path;
        }
      }
    }
  }

  // register sub-schemas
  var keys = Object.keys(schema);
  for (var index = 0, len = keys.length; index !== len; ++index) {
    var key = keys[index];
    if (typeof schema[key] === 'object') {
      if (!Array.isArray(schema[key])) {
        this.register(schema[key], resolutionScope, null, _path + '/' + key);
      }
    }
  }
};

// ******************************************************************
// Get a previously-registered schema, if available. Returns null if
// the schema is not available.
// ******************************************************************
JaySchema.prototype.getSchema = function(resolvedId) {
  var parts = url.parse(resolvedId);
  var fragment = parts.hash;
  delete parts.hash;
  var baseUri = url.format(parts);

  if (!this.schemas.hasOwnProperty(baseUri)) { return null; }

  if (!fragment || fragment === '#' || fragment === '') {

    // base, non-fragment URI
    return this.schemas[baseUri].schema;
  } else {

    // It’s a fragment, and can be either a JSON pointer or a URI
    // fragment identifier. In the latter case, look up the
    // corresponding JSON pointer and proceed.

    if (fragment.slice(0, 2) !== '#/') {  // URI fragment
      fragment = this.schemas[baseUri].fragments[fragment] || fragment;
    }

    var path = fragment.slice(2).split('/');
    var currentSchema = this.schemas[baseUri].schema;
    while (path.length) {
      var element = jsonPointer.decode(path.shift());
      if (!currentSchema.hasOwnProperty(element)) { return null; }
      currentSchema = currentSchema[element];
    }
    return currentSchema;
  }
};

// ******************************************************************
// [static] Helper to gather all $refs values from the given object
// ******************************************************************
JaySchema._gatherRefs = function(obj) {
  var result = [];

  var currentObj = obj;
  var keys = Object.keys(currentObj);
  var subObjects = [];

  do {

    if (currentObj.hasOwnProperty('$ref')) { result.push(currentObj.$ref); }

    for (var index = 0, len = keys.length; index !== len; ++index) {
      var prop = currentObj[keys[index]];
      if (typeof prop === 'object') { subObjects.push(prop); }
    }

    currentObj = subObjects.pop();

  } while(currentObj);

  return result;
};

// ******************************************************************
// Recursively and asynchronously pre-load all schemas that are
// referenced ('$ref') from the given schema.
//
// Recurses to the given depth: if a schema references an external
// schema, it will be fetched. If THAT schema references an external
// schema, it will be fetched etc. Once this reaches the specified
// depth, an error will be returned.
// ******************************************************************
JaySchema.prototype._recursivePreload = function(schema, depth, callback) {
  var self = this;
  var errs = [];
  var index, len, ref;

  var refs = JaySchema._gatherRefs(schema);

  refs = refs.filter(function(ref) {
    if (this.schemas.hasOwnProperty(ref)) { return false; }
    if (this._urlsRequested.indexOf(ref) !== -1) { return false; }
    var parts = url.parse(ref);
    if (!parts.protocol || parts.protocol.slice(0, 4) !== 'http') {
      return false;
    }
    return true;
  }, this);

  // nothing to fetch?
  if (refs.length === 0) { return process.nextTick(callback); }

  // are we in too deep?
  if (!depth) {
    var desc = 'would exceed max recursion depth fetching these referenced ' +
      'schemas: ' + refs;
    var err = new Errors.ValidationError(null, null, null, null, null,
      desc);
    return process.nextTick(callback.bind(null, err));
  }

  // fetch 'em
  var completedCount = 0;
  var totalCount = refs.length;

  for (index = 0, len = refs.length; index !== len; ++index) {
    ref = refs[index];
    this._urlsRequested.push(ref);
    downloadSchema(ref, function(err, schema) {
      if (err) { return errs.push(err); }
      self.register(schema, ref, ref);
      self._recursivePreload(schema, depth - 1, function(moreErrs) {
        if (moreErrs) { errs = errs.concat(moreErrs); }
        completedCount++;
        if (completedCount === totalCount) {
          callback(errs);
        }
      });
    });
  }
};

// ******************************************************************
// The main validation guts (internal implementation).
// ******************************************************************
JaySchema.prototype._validateImpl = function(instance, schema, resolutionScope,
  instanceContext)
{
  // for schemas that have no id, use an internal anonymous id
  var schemaId = schema.id || ANON_URI_SCHEME + '://' + uuid.uuid4() + '#';
  this.register(schema, resolutionScope, schemaId);
  resolutionScope = resolutionScope || schemaId;

  // dereference schema if needed
  if (schema.hasOwnProperty('$ref')) {
    var ref = jsonPointer.resolve(resolutionScope, decodeURI(schema.$ref));
    resolutionScope = ref;
    schema = this.getSchema(ref);

    if (!schema) {
      var desc = 'schema not available: ' + ref;
      if (ref.slice(0, 4) === 'http') {
        desc += ' [schemas can be retrieved over HTTP, but only if ' +
          'validate() is called asynchronously]';
      }
      var err = new Errors.ValidationError(null, null, null, null, null,
        desc);
      return [err];
    }
  }

  // no schema passed
  if (!schema) { return [];}

  // create the TestSet for this schema version
  var TestSetClass = schemaTestSets[schema.$schema || DEFAULT_SCHEMA_VERSION];
  var testSet = new TestSetClass(this._validateImpl.bind(this), instance,
    schema, resolutionScope, instanceContext || '#');

  return testSet.run();
};

// ******************************************************************
// The main validation function (public API). Our raison d'être.
// ******************************************************************
JaySchema.prototype.validate = function(instance, schema, callback)
{
  // for schemas that have no id, use an internal anonymous id
  var schemaId = schema.id || ANON_URI_SCHEME + '://' + uuid.uuid4() + '#';
  this.register(schema, null, schemaId);

  // preload referenced schemas (recursively)
  if (callback) {
    var self = this;
    self._recursivePreload(schema, this.maxPreload, function(errs) {
      // no further disk or net I/O from here on
      if (errs && errs.length !== 0) { return callback(errs); }
      var result = self._validateImpl(instance, schema);
      if (result.length) { callback(result); }
      else { callback(); }
    });
  } else {
    return this._validateImpl(instance, schema);
  }
};

module.exports = JaySchema;
<commit_msg>fix _gatherRefs failure to recurse<commit_after>//
// JaySchema (draft v4) validator for Node.js.
//

'use strict';

var jsonPointer = require('./jsonPointer.js')
  , url = require('url')
  , downloadSchema = require('./downloadSchema.js')
  , Errors = require('./errors.js')
  , uuid = require('./uuid.js')
  ;

var DEFAULT_SCHEMA_VERSION = 'http://json-schema.org/draft-04/schema#';
var ANON_URI_SCHEME = 'anon-schema';

var schemaTestSets = {
  'http://json-schema.org/draft-04/schema#': require('./suites/draft-04.js')
};

// ******************************************************************
// Constructor
// ******************************************************************
var JaySchema = function(maxPreload) {
  this.schemas = {};
  this._urlsRequested = [];
  this.maxPreload = maxPreload || 5;
};

// ******************************************************************
// Register the given schema in our library of schemas.
// ******************************************************************
JaySchema.prototype.register = function(schema, resolutionScope, _fallbackId,
  _path)
{
  // We stash each schema that has a unique URI, not including
  // the fragment part.

  var id = schema.id || _fallbackId;
  if (id) {
    var resolvedId = jsonPointer.resolve(resolutionScope, id);
    resolutionScope = resolvedId;
    var parts = url.parse(resolvedId);
    var fragment = parts.hash;
    delete parts.hash;
    var baseUri = url.format(parts);

    if (!fragment || fragment === '#' || fragment === '') {
      // top-level schema
      if (this.schemas.hasOwnProperty(baseUri)) {
        // this and its sub-schemas are already registered
        return;
      }
      this.schemas[baseUri] = { schema: schema, fragments: {} };
      _path = '#';
    } else {
      // fragment reference within a top-level schema
      if (this.schemas.hasOwnProperty(baseUri)) {
        if (!this.schemas[baseUri].fragments.hasOwnProperty(fragment)) {
          this.schemas[baseUri].fragments[fragment] = _path;
        }
      }
    }
  }

  // register sub-schemas
  var keys = Object.keys(schema);
  for (var index = 0, len = keys.length; index !== len; ++index) {
    var key = keys[index];
    if (typeof schema[key] === 'object') {
      if (!Array.isArray(schema[key])) {
        this.register(schema[key], resolutionScope, null, _path + '/' + key);
      }
    }
  }
};

// ******************************************************************
// Get a previously-registered schema, if available. Returns null if
// the schema is not available.
// ******************************************************************
JaySchema.prototype.getSchema = function(resolvedId) {
  var parts = url.parse(resolvedId);
  var fragment = parts.hash;
  delete parts.hash;
  var baseUri = url.format(parts);

  if (!this.schemas.hasOwnProperty(baseUri)) { return null; }

  if (!fragment || fragment === '#' || fragment === '') {

    // base, non-fragment URI
    return this.schemas[baseUri].schema;
  } else {

    // It’s a fragment, and can be either a JSON pointer or a URI
    // fragment identifier. In the latter case, look up the
    // corresponding JSON pointer and proceed.

    if (fragment.slice(0, 2) !== '#/') {  // URI fragment
      fragment = this.schemas[baseUri].fragments[fragment] || fragment;
    }

    var path = fragment.slice(2).split('/');
    var currentSchema = this.schemas[baseUri].schema;
    while (path.length) {
      var element = jsonPointer.decode(path.shift());
      if (!currentSchema.hasOwnProperty(element)) { return null; }
      currentSchema = currentSchema[element];
    }
    return currentSchema;
  }
};

// ******************************************************************
// [static] Helper to gather all $refs values from the given object
// ******************************************************************
JaySchema._gatherRefs = function(obj) {
  var result = [];

  var currentObj = obj;
  var subObjects = [];

  do {

    if (currentObj.hasOwnProperty('$ref')) { result.push(currentObj.$ref); }

    var keys = Object.keys(currentObj);
    for (var index = 0, len = keys.length; index !== len; ++index) {
      var prop = currentObj[keys[index]];
      if (typeof prop === 'object') { subObjects.push(prop); }
    }

    currentObj = subObjects.pop();

  } while(currentObj);

  return result;
};

// ******************************************************************
// Recursively and asynchronously pre-load all schemas that are
// referenced ('$ref') from the given schema.
//
// Recurses to the given depth: if a schema references an external
// schema, it will be fetched. If THAT schema references an external
// schema, it will be fetched etc. Once this reaches the specified
// depth, an error will be returned.
// ******************************************************************
JaySchema.prototype._recursivePreload = function(schema, depth, callback) {
  var self = this;
  var errs = [];
  var index, len, ref;

  var refs = JaySchema._gatherRefs(schema);

  refs = refs.filter(function(ref) {
    if (this.schemas.hasOwnProperty(ref)) { return false; }
    if (this._urlsRequested.indexOf(ref) !== -1) { return false; }
    var parts = url.parse(ref);
    if (!parts.protocol || parts.protocol.slice(0, 4) !== 'http') {
      return false;
    }
    return true;
  }, this);

  // nothing to fetch?
  if (refs.length === 0) { return process.nextTick(callback); }

  // are we in too deep?
  if (!depth) {
    var desc = 'would exceed max recursion depth fetching these referenced ' +
      'schemas: ' + refs;
    var err = new Errors.ValidationError(null, null, null, null, null,
      desc);
    return process.nextTick(callback.bind(null, err));
  }

  // fetch 'em
  var completedCount = 0;
  var totalCount = refs.length;

  for (index = 0, len = refs.length; index !== len; ++index) {
    ref = refs[index];
    this._urlsRequested.push(ref);
    downloadSchema(ref, function(err, schema) {
      if (err) { return errs.push(err); }
      self.register(schema, ref, ref);
      self._recursivePreload(schema, depth - 1, function(moreErrs) {
        if (moreErrs) { errs = errs.concat(moreErrs); }
        completedCount++;
        if (completedCount === totalCount) {
          callback(errs);
        }
      });
    });
  }
};

// ******************************************************************
// The main validation guts (internal implementation).
// ******************************************************************
JaySchema.prototype._validateImpl = function(instance, schema, resolutionScope,
  instanceContext)
{
  // for schemas that have no id, use an internal anonymous id
  var schemaId = schema.id || ANON_URI_SCHEME + '://' + uuid.uuid4() + '#';
  this.register(schema, resolutionScope, schemaId);
  resolutionScope = resolutionScope || schemaId;

  // dereference schema if needed
  if (schema.hasOwnProperty('$ref')) {
    var ref = jsonPointer.resolve(resolutionScope, decodeURI(schema.$ref));
    resolutionScope = ref;
    schema = this.getSchema(ref);

    if (!schema) {
      var desc = 'schema not available: ' + ref;
      if (ref.slice(0, 4) === 'http') {
        desc += ' [schemas can be retrieved over HTTP, but only if ' +
          'validate() is called asynchronously]';
      }
      var err = new Errors.ValidationError(null, null, null, null, null,
        desc);
      return [err];
    }
  }

  // no schema passed
  if (!schema) { return [];}

  // create the TestSet for this schema version
  var TestSetClass = schemaTestSets[schema.$schema || DEFAULT_SCHEMA_VERSION];
  var testSet = new TestSetClass(this._validateImpl.bind(this), instance,
    schema, resolutionScope, instanceContext || '#');

  return testSet.run();
};

// ******************************************************************
// The main validation function (public API). Our raison d'être.
// ******************************************************************
JaySchema.prototype.validate = function(instance, schema, callback)
{
  // for schemas that have no id, use an internal anonymous id
  var schemaId = schema.id || ANON_URI_SCHEME + '://' + uuid.uuid4() + '#';
  this.register(schema, null, schemaId);

  // preload referenced schemas (recursively)
  if (callback) {
    var self = this;
    self._recursivePreload(schema, this.maxPreload, function(errs) {
      // no further disk or net I/O from here on
      if (errs && errs.length !== 0) { return callback(errs); }
      var result = self._validateImpl(instance, schema);
      if (result.length) { callback(result); }
      else { callback(); }
    });
  } else {
    return this._validateImpl(instance, schema);
  }
};

module.exports = JaySchema;
<|endoftext|>


<commit_before>$(function() {
  // Correctly position the content based on banner size
  $('div.app-events-detail div.banner img').load(function() {
    $('div.app-events-detail div.event-wrapper').css('margin-top', ($(this).parent().height() - 175) + 'px');
  });

  var $share_buttons = $('.share-buttons');

  // No need to execute the rest of this script if this element does not exist.
  if (!$share_buttons.length)
    return;

  // Handles popups
  $share_buttons.find('a').click(function(e) {
    var $this = $(this),
        left  = (screen.width / 2) - (500 / 2),
        top   = (screen.height / 2) - (250 / 2);

    if ($this.hasClass('fa-facebook')) {
      window.open('https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(window.location.href), '', 'width=500, height=250, top=' + top + ', left=' + left);
    } else if ($this.hasClass('fa-twitter')) {
      window.open('https://twitter.com/share?url=' + encodeURIComponent(window.location.href) + '&text=' + encodeURIComponent($this.attr('data-text')), '', 'width=500, height=250, top=' + top + ', left=' + left);
    } else if ($this.hasClass('fa-google-plus')) {
      window.open('http://plus.google.com/share?url=' + encodeURIComponent(window.location.href), '', 'width=500, height=250, top=' + top + ', left=' + left);
    }

    // Preventing an eventual default behavior
    e.preventDefault();
    return false;
  });
});
<commit_msg>Fix a bug on event detail when no banner<commit_after>$(function() {
  // Correctly position the content based on banner size
  $('div.app-events-detail div.banner img').load(function() {
    $('div.app-events-detail div.event-wrapper').css('margin-top', ($(this).parent().height() - 175) + 'px');
  });

  // If no banner, remove the margin
  if (!$('div.app-events-detail div.banner').length) {
    $('div.app-events-detail div.event-wrapper').css('margin-top', '0px');
  }

  var $share_buttons = $('.share-buttons');

  // No need to execute the rest of this script if this element does not exist.
  if (!$share_buttons.length)
    return;

  // Handles popups
  $share_buttons.find('a').click(function(e) {
    var $this = $(this),
        left  = (screen.width / 2) - (500 / 2),
        top   = (screen.height / 2) - (250 / 2);

    if ($this.hasClass('fa-facebook')) {
      window.open('https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(window.location.href), '', 'width=500, height=250, top=' + top + ', left=' + left);
    } else if ($this.hasClass('fa-twitter')) {
      window.open('https://twitter.com/share?url=' + encodeURIComponent(window.location.href) + '&text=' + encodeURIComponent($this.attr('data-text')), '', 'width=500, height=250, top=' + top + ', left=' + left);
    } else if ($this.hasClass('fa-google-plus')) {
      window.open('http://plus.google.com/share?url=' + encodeURIComponent(window.location.href), '', 'width=500, height=250, top=' + top + ', left=' + left);
    }

    // Preventing an eventual default behavior
    e.preventDefault();
    return false;
  });
});
<|endoftext|>


<commit_before>'use strict';

define(['ol',
        'toolbar',
        'layermanager',
        'WfsSource', 'query',
        'search',
        'print',
        'permalink',
        'measure',
        'geolocation',
        'api',
        'poly2tri',
        'glutils', 'WGL', 'wglinit',  'mapconf', 'manager', 'mapcontroller', 'dataloader', 'd3',  'dimension',
        'heatmapdimension', 'heatmaprenderer', 'heatmaplegend', 'maxcalculator', 'chart_panel', 'stackedbarchart', 'histogramdimension', 'mapdimension', 'floatreaderhistogram',
        'floatrasterreader', 'linearfilter', 'filter', 'bootstrap', 'multibrush', 'extentfilter', 'mappolyfilter'
    ],

    function(ol, toolbar, layermanager, WfsSource) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.geolocation', 'hs.widgets.chart_panel'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', 'webgl_viz', function(OlMap, Core, $compile, webgl_viz) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    Core.fullscreenMap(element, 'right');
                    $("#right-pane", element).append($compile('

')(scope));
                    $("#right-pane", element).css({
                        'width': '560px',
                        'padding-top': "40px",
                        'padding-left': '33px'
                    });
                    $(".search-container").removeClass('col-md-4').addClass('col-md-3');
                    //webgl_viz.webgl_el = $compile('<canvas id="webglayer"></canvas>')(scope);
                    //element.append(webgl_viz.webgl_el);
                    webgl_viz.init();
                }
            };
        }]);

        module.service('webgl_viz', ['hs.map.service', function(OlMap) {
            OlMap.map.removeInteraction(OlMap.interactions.DragPan);
            OlMap.interactions.DragPan = new ol.interaction.DragPan({
                kinetic: false
            });
            OlMap.map.addInteraction(OlMap.interactions.DragPan);

            var me = {
                map: OlMap.map,
                ol: ol,
                init: function() {
                    wglinit(this);
                }
            };

            return me;
        }]);

        module.value('config', {
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: 'http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
                        attributions: [new ol.Attribution({
                            html: ['© OpenStreetMap contributors, © CartoDB']
                        })]
                    })
                })
            ],
            default_view: new ol.View({
                center: ol.proj.transform([-1.9, 52.5], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 4,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', 'Core', 'hs.map.service', 'webgl_viz',
            function($scope, Core, OlMap, webgl_viz) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                var map = OlMap.map;
                $scope.$on('infopanel.updated', function(event) {});

            }
        ]);

        return module;
    });
<commit_msg>fixes #5280 Firefox doesn't dispaly tiles from cartodb<commit_after>'use strict';

define(['ol',
        'toolbar',
        'layermanager',
        'WfsSource', 'query',
        'search',
        'print',
        'permalink',
        'measure',
        'geolocation',
        'api',
        'poly2tri',
        'glutils', 'WGL', 'wglinit',  'mapconf', 'manager', 'mapcontroller', 'dataloader', 'd3',  'dimension',
        'heatmapdimension', 'heatmaprenderer', 'heatmaplegend', 'maxcalculator', 'chart_panel', 'stackedbarchart', 'histogramdimension', 'mapdimension', 'floatreaderhistogram',
        'floatrasterreader', 'linearfilter', 'filter', 'bootstrap', 'multibrush', 'extentfilter', 'mappolyfilter'
    ],

    function(ol, toolbar, layermanager, WfsSource) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.geolocation', 'hs.widgets.chart_panel'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', 'webgl_viz', function(OlMap, Core, $compile, webgl_viz) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    Core.fullscreenMap(element, 'right');
                    $("#right-pane", element).append($compile('

')(scope));
                    $("#right-pane", element).css({
                        'width': '560px',
                        'padding-top': "40px",
                        'padding-left': '33px'
                    });
                    $(".search-container").removeClass('col-md-4').addClass('col-md-3');
                    //webgl_viz.webgl_el = $compile('<canvas id="webglayer"></canvas>')(scope);
                    //element.append(webgl_viz.webgl_el);
                    webgl_viz.init();
                }
            };
        }]);

        module.service('webgl_viz', ['hs.map.service', function(OlMap) {
            OlMap.map.removeInteraction(OlMap.interactions.DragPan);
            OlMap.interactions.DragPan = new ol.interaction.DragPan({
                kinetic: false
            });
            OlMap.map.addInteraction(OlMap.interactions.DragPan);

            var me = {
                map: OlMap.map,
                ol: ol,
                init: function() {
                    wglinit(this);
                }
            };

            return me;
        }]);

        module.value('config', {
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: 'http://{a-z}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
                        attributions: [new ol.Attribution({
                            html: ['© OpenStreetMap contributors, © CartoDB']
                        })]
                    }),
                    title: 'OpenStreetMap'
                })
            ],
            default_view: new ol.View({
                center: ol.proj.transform([-1.9, 52.5], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 4,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', 'Core', 'hs.map.service', 'webgl_viz',
            function($scope, Core, OlMap, webgl_viz) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                var map = OlMap.map;
                $scope.$on('infopanel.updated', function(event) {});

            }
        ]);

        return module;
    });
<|endoftext|>


<commit_before>var ExplorerController = Backbone.Router.extend({

    tabs: null,

    routes: {
        "tabs-annotation-:idAnnotation": "browseAnnotation",
        "tabs-image-:idProject-:idImage-:idAnnotation": "browse",
        "tabs-review-:idProject-:idImage-": "review",
        "close": "close"
    },

    initialize: function () {
    },

    initTabs: function () { //SHOULD BE OUTSIDE OF THIS CONTROLLER
        this.tabs = new ExplorerTabs({
            el: $("#explorer > .browser"),
            container: window.app.view.components.explorer
        }).render();
    },

    browseAnnotation: function (idAnnotation) {
        var self = this;
        console.log("browseAnnotation");
        //allow to access an annotation without knowing its projet/image (usefull to access annotation when we just have annotationTerm data).
        new AnnotationModel({id: idAnnotation}).fetch({
            success: function (model, response) {
                self.browse(model.get("project"), model.get("image"), idAnnotation);
            }
        });
    },
    browse: function (idProject, idImage, idAnnotation) {
        console.log("browse2");
        /*
         if (window.app.secondaryWindow) {
         window.app.secondaryWindow.location = window.location;
         }
         */
        var self = this;
        //create tabs if not exist
        if (this.tabs == null) {
            console.log("this.tabs==null");
            this.initTabs();
        }
        var createBrowseImageViewTab = function () {
            console.log("createBrowseImageViewTab");
            var browseImageViewInitOptions = {};
            if (idAnnotation != "") {
                browseImageViewInitOptions.goToAnnotation = {value: idAnnotation};
            }
            self.tabs.addBrowseImageView(idImage, browseImageViewInitOptions);
            //$('#tabs-image-'+idImage).tab('show');
            // window.app.view.showComponent(self.tabs.container);
            console.log("showView");

            self.showView();
        };

        if (window.app.status.currentProject == undefined || window.app.status.currentProject != idProject) {//direct access -> create dashboard
            console.log("project check");
            window.app.controllers.dashboard.dashboard(idProject, createBrowseImageViewTab);
            return;
        }

        createBrowseImageViewTab();
    },

    review: function (idProject, idImage) {
        console.log("review:" + idProject + "-" + idImage);

        var self = this;
        //create tabs if not exist
        if (this.tabs == null) {
            console.log("this.tabs==null");
            this.initTabs();
        }
        var createReviewImageViewTab = function () {
            console.log("createReviewImageViewTab");
            var reviewImageViewInitOptions = {};
            self.tabs.addReviewImageView(idImage, reviewImageViewInitOptions);
            //$('#tabs-image-'+idImage).tab('show');
            // window.app.view.showComponent(self.tabs.container);
            console.log("showView");

            self.showView();
        };

        if (window.app.status.currentProject == undefined || window.app.status.currentProject != idProject) {//direct access -> create dashboard
            console.log("project check");
            window.app.controllers.dashboard.dashboard(idProject, createReviewImageViewTab);
            return;
        }

        createReviewImageViewTab();

    },

    closeAll: function () {
        if (this.tabs == null) {
            return;
        }
        this.tabs = null;
        $("#explorer > .browser").empty();
    },

    showView: function () {
        $("#explorer > .browser").show();
        $("#explorer > .noProject").hide();
        window.app.view.showComponent(window.app.view.components.explorer);
    }

});<commit_msg>fix bug with image access (?)<commit_after>var ExplorerController = Backbone.Router.extend({

    tabs: null,

    routes: {
        "tabs-annotation-:idAnnotation": "browseAnnotation",
        "tabs-image-:idProject-:idImage-": "browse",
        "tabs-image-:idProject-:idImage-:idAnnotation": "browse",
        "tabs-review-:idProject-:idImage-": "review",
        "close": "close"
    },

    initialize: function () {
    },

    initTabs: function () { //SHOULD BE OUTSIDE OF THIS CONTROLLER
        this.tabs = new ExplorerTabs({
            el: $("#explorer > .browser"),
            container: window.app.view.components.explorer
        }).render();
    },

    browseAnnotation: function (idAnnotation) {
        var self = this;
        console.log("browseAnnotation");
        //allow to access an annotation without knowing its projet/image (usefull to access annotation when we just have annotationTerm data).
        new AnnotationModel({id: idAnnotation}).fetch({
            success: function (model, response) {
                self.browse(model.get("project"), model.get("image"), idAnnotation);
            }
        });
    },
    browse: function (idProject, idImage) {
        this.browse(idProject,idImage,"");
    },
    browse: function (idProject, idImage, idAnnotation) {
        console.log("browse2");
        /*
         if (window.app.secondaryWindow) {
         window.app.secondaryWindow.location = window.location;
         }
         */
        var self = this;
        //create tabs if not exist
        if (this.tabs == null) {
            console.log("this.tabs==null");
            this.initTabs();
        }
        var createBrowseImageViewTab = function () {
            console.log("createBrowseImageViewTab");
            var browseImageViewInitOptions = {};
            if (idAnnotation != "") {
                browseImageViewInitOptions.goToAnnotation = {value: idAnnotation};
            }
            self.tabs.addBrowseImageView(idImage, browseImageViewInitOptions);
            //$('#tabs-image-'+idImage).tab('show');
            // window.app.view.showComponent(self.tabs.container);
            console.log("showView");

            self.showView();
        };

        if (window.app.status.currentProject == undefined || window.app.status.currentProject != idProject) {//direct access -> create dashboard
            console.log("project check");
            window.app.controllers.dashboard.dashboard(idProject, createBrowseImageViewTab);
            return;
        }

        createBrowseImageViewTab();
    },

    review: function (idProject, idImage) {
        console.log("review:" + idProject + "-" + idImage);

        var self = this;
        //create tabs if not exist
        if (this.tabs == null) {
            console.log("this.tabs==null");
            this.initTabs();
        }
        var createReviewImageViewTab = function () {
            console.log("createReviewImageViewTab");
            var reviewImageViewInitOptions = {};
            self.tabs.addReviewImageView(idImage, reviewImageViewInitOptions);
            //$('#tabs-image-'+idImage).tab('show');
            // window.app.view.showComponent(self.tabs.container);
            console.log("showView");

            self.showView();
        };

        if (window.app.status.currentProject == undefined || window.app.status.currentProject != idProject) {//direct access -> create dashboard
            console.log("project check");
            window.app.controllers.dashboard.dashboard(idProject, createReviewImageViewTab);
            return;
        }

        createReviewImageViewTab();

    },

    closeAll: function () {
        if (this.tabs == null) {
            return;
        }
        this.tabs = null;
        $("#explorer > .browser").empty();
    },

    showView: function () {
        $("#explorer > .browser").show();
        $("#explorer > .noProject").hide();
        window.app.view.showComponent(window.app.view.components.explorer);
    }

});<|endoftext|>


<commit_before>nforge.namespace('shortcut');

// ctrl + enter to submit a form
nforge.shortcut.submit = function () {
  var that;

  that = {
    init : function () {
      var eventHandler = function (event) {
        if (event.ctrlKey && event.which == 13) {
        $(event.target).parents('form').get(0).submit();
        }
      }

      $('textarea').keydown(eventHandler);
      $('input').keydown(eventHandler);
    }
  };

  return that;
};
<commit_msg>shortcut: Fix that submit shortcut ignores event.<commit_after>nforge.namespace('shortcut');

// ctrl + enter to submit a form
nforge.shortcut.submit = function () {
  var that;

  that = {
    init : function () {
      var eventHandler = function (event) {
        if (event.ctrlKey && event.which == 13) {
          $($(event.target).parents('form').get(0)).submit();
        }
      }

      $('textarea').keydown(eventHandler);
      $('input').keydown(eventHandler);
    }
  };

  return that;
};
<|endoftext|>


<commit_before>// @flow

import type { Account } from './Account'
import type { Channel } from './Channel'
import type { Playlist } from './Playlist'
import type { SubscriptionState } from './SubscriptionState'
import type { SubscriptionType } from './SubscriptionType'

/**
 * An entity representing a subscription to new videos from a single channel or
 * added to a single playlist.
 */
export interface Subscription {
  /**
   * The type of this subscription, must be one of the
   * {@linkcode SubscriptionType.*} constants.
   */
  type: SubscriptionType;

  /**
   * The Playlist from which the videos should be retrieved. This is the
   * "uploads" playlist if this is a subscription to a YouTube channel.
   */
  playlist: Playlist;

  /**
   * The channel to which the subscription is made to. The field is set to the
   * channel owning the playlist for incognito subscriptions to a playlist.
   */
  channel: Channel;

  /**
   * The state of this subscription, must be one of the
   * {@linkcode SubscriptionState.*} constants.
   */
  state: SubscriptionState;

  /**
   * The last reported error related to this subscription, set to
   * {@code undefined} if there is no current error.
   */
  lastError: ?string;

  /**
   * The Google account from which this subscription has been provided. The
   * field is {@code undefined} if this is an incognito subscription.
   */
  account: ?Account;

  /**
   * Set to {@code true} if this is an incognito subscription (has been
   * provided manually instead of read from YouTube channel subscriptions); set
   * to {@code false} otherwise.
   */
  isIncognito: boolean;
}
<commit_msg>added subscription ID<commit_after>// @flow

import type { Account } from './Account'
import type { Channel } from './Channel'
import type { Playlist } from './Playlist'
import type { SubscriptionState } from './SubscriptionState'
import type { SubscriptionType } from './SubscriptionType'

/**
 * An entity representing a subscription to new videos from a single channel or
 * added to a single playlist.
 */
export interface Subscription {
  /**
   * The unique internal identifier of this subscription record. The identifier
   * is generated by the implementation, not the YouTube API.
   */
  id: number|string;

  /**
   * The type of this subscription, must be one of the
   * {@linkcode SubscriptionType.*} constants.
   */
  type: SubscriptionType;

  /**
   * The Playlist from which the videos should be retrieved. This is the
   * "uploads" playlist if this is a subscription to a YouTube channel.
   */
  playlist: Playlist;

  /**
   * The channel to which the subscription is made to. The field is set to the
   * channel owning the playlist for incognito subscriptions to a playlist.
   */
  channel: Channel;

  /**
   * The state of this subscription, must be one of the
   * {@linkcode SubscriptionState.*} constants.
   */
  state: SubscriptionState;

  /**
   * The last reported error related to this subscription, set to
   * {@code undefined} if there is no current error.
   */
  lastError: ?string;

  /**
   * The Google account from which this subscription has been provided. The
   * field is {@code undefined} if this is an incognito subscription.
   */
  account: ?Account;

  /**
   * Set to {@code true} if this is an incognito subscription (has been
   * provided manually instead of read from YouTube channel subscriptions); set
   * to {@code false} otherwise.
   */
  isIncognito: boolean;
}
<|endoftext|>


<commit_before>//from adapter.js
/*global RTCPeerConnection getUserMedia attachMediaStream
  reattachMediaStream webrtcDetectedBrowser webrtcDetectedVersion
  RTCSessionDescription RTCIceCandidate*/

"use strict";

// Create lowercase-and-hyphenated slug for a phrase.
function slugify(phrase) {
  return phrase.toLowerCase()
    .replace(/\&/g,' and ')
    .replace(/\%/g,' percent ')
    .replace(/[^ \-\w]/g,'')
    .replace(/[ \-]+/g,' ')
    .trim()
    .replace(/ /g,'-');
}

// Switch which "page" element is currently visible.
function switchState(stateName) {
  var states = document.querySelectorAll(".page.active");
  for (var i = 0; i < states.length; i++) {
    states[i].classList.remove('active');
    states[i].classList.add('inactive');
  }

  var newactive = document.getElementById(stateName);
  newactive.classList.remove('inactive');
  newactive.classList.add('active');
}

//TODO: general XHR function, with timeout CB

var consoleError = console.error.bind(console);

function pollRing(phrase,body,peercon){
  var pollRq = new XMLHttpRequest();
   pollRq.onreadystatechange = function () {
      if (pollRq.readyState == 4) {
        // parse response
        var resbody = JSON.parse(pollRq.responseText);

        if (resbody.answer) {
          // connect to the answer
          peercon.setRemoteDescription(
            new RTCSessionDescription(resbody.answer),
            function(){
              console.log('connected to',resbody.answer);
            },consoleError);
        }

        // For a second let's make-believe there can never be ICE
        // before we've received the session description
        addIce(peercon,resbody.ice);

        // Keep ringing and gathering ICE candidates until the
        // remote stream handler aborts the running poll
        return pollRing(phrase, body, peercon);
      }
    };
  pollRq.open("POST","/api/ring/"+phrase);
  pollRq.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");

  //allow the remote stream handler to terminate this
  enormousHackToStopPolling = pollRq;
  pollRq.send(body);
}

function answerRing(phrase,body,peercon){
  var answerRq = new XMLHttpRequest();
   answerRq.onreadystatechange = function () {
      function ringFromDesc (f) {
        return function (desc) {
          return f(phrase,JSON.stringify({ "session": desc }));
        };
      }

      if (answerRq.readyState == 4) {
        //parse response
        var resbody = JSON.parse(answerRq.responseText);

        if(resbody.status == "answered") {
          addIce(peercon,resbody.ice);
          //inform the user that they're waiting for the other end
          //to connect (if they haven't already)
          //TODO: continue polling for ICE until connected?
          //(final polls can terminate when the other end
          //acknowledges it's connected)
        } else {
          //go back to the beginning
          //TODO: destroy existing peer connection?
          beginPhrase(phrase);
        }
      }
    };
  answerRq.open("POST","/api/answer/"+phrase);
  answerRq.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");
  answerRq.send(body);
}

//because keeping track of a proper polling state is just too hard
var enormousHackToStopPolling;

// This is also hacky, but this time it's not my fault
var persistentPeerConnectionReferenceToEvadeGarbageCollectionInChrome;

function onRemoteStreamConnected(evt){
  attachMediaStream(document.getElementById('vidscreen'),evt.stream);
}

// Constructs a function that posts ICE candidates.
function icePoster(phrase, party) {
  return function(evt) {
    // After all the ICE candidates have been worked over,
    // onicecandidate gets called with an event without a candidate.
    // Send that so the other end knows when to stop ICE polling.
    //if (evt.candidate) {
      var iceRq = new XMLHttpRequest();
       iceRq.onreadystatechange = function () {
          if (iceRq.readyState == 4) {
            //do nothing
          }
        };
      iceRq.open("POST","/api/ice/"+phrase);
      iceRq.setRequestHeader(
        "Content-type", "application/json; charset=utf-8");
      iceRq.send(JSON.stringify({party: party,
        ic: evt.candidate ? evt.candidate : null}));
    //}
  };
}

//Function to handle incoming ICE candidates.
function addIce(peercon, ice){
  function addCandidate(candidate) {
    peercon.addIceCandidate(candidate,
      function() {console.log('added',candidate)},
      function(err) {console.error(candidate,err)});
  }
  if (ice) {
    for (var i=0; i < ice.length; i++) {
      if(ice[i])
        addCandidate(new RTCIceCandidate(ice[i]));
      else if(enormousHackToStopPolling) {
        enormousHackToStopPolling.abort();
      }
    }
  }
}

function startRinging(phrase,stream){
  // Create a peer connection that will use
  // vline's STUN server, Google's STUN server,
  // and numb.viagenie.ca for TURN
  var peercon = new RTCPeerConnection({
    "iceServers": [
        {"url": "stun:stun.vline.com"}
        ,{"url": "stun:stun.l.google.com:19302"}
        ,{
            url: 'turn:ice%40chatphrase%2ecom@numb.viagenie.ca',
            credential: 'yovipletskickit'
        }
        ]});

  persistentPeerConnectionReferenceToEvadeGarbageCollectionInChrome = peercon;

  //add our stream to the connection
  peercon.addStream(stream);

  //add a listener for the stream from the other end
  peercon.onaddstream = onRemoteStreamConnected;

  var firstRing = new XMLHttpRequest();
   firstRing.onreadystatechange = function () {
      function ringFromDesc (f) {
        return function (desc) {
          //TODO: I'm reading some stuff about how Opus should be listed
          //as preferred at this point?

          //I'm not completely sure I understand this line (we add the session
          //we just made as a "local description"? Uh... duh?)
          peercon.setLocalDescription(desc, null, consoleError);

          //Send this request to the other end
          return f(phrase,JSON.stringify(desc),peercon);
        };
      }

      if (firstRing.readyState == 4) {
        //parse response
        var resbody = JSON.parse(firstRing.responseText);

        //NOTE: Maybe we should hold off on creating the session offers
        //until there's two endpoints on the line
        peercon.onicecandidate = icePoster(phrase,
          resbody.waiting ? 'answerer' : 'waiter');
        if (resbody.waiting) {

          //add the remote session to the connection
          peercon.setRemoteDescription(
            new RTCSessionDescription(resbody.waiting),
            function(){
              console.log('connected to',resbody.waiting);
            }, consoleError);

          addIce(peercon,resbody.ice);

          peercon.createAnswer(ringFromDesc(answerRing));
        } else {
          peercon.createOffer(ringFromDesc(pollRing),
            null, consoleError,
            { mandatory: {
              OfferToReceiveAudio: true,
              OfferToReceiveVideo: true,
              IceRestart: true}});
        }
      }
    };
  firstRing.open("GET","/api/ring/"+phrase);
  firstRing.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");
  firstRing.send();
}

function beginPhrase(phrase) {
  document.title = phrase.replace(/-/g,' ') + ' : Chatphrase';
  getUserMedia({audio:true,video:true},function(stream){
    attachMediaStream(document.getElementById('pip'),stream);
    //advance to lobby / connection
    startRinging(phrase,stream);
    switchState("room");
  },function(err){
    if(err.code && err.code == err.PERMISSION_DENIED
      || err.name == "PERMISSION_DENIED"
    ){
      document.getElementById('virgil').textContent =
        "It looks like we've been denied permission to access your camera. "+
        "We need access to your camera to start the call (it wouldn't be "+
        "much of a video call if we didn't). Please reset permissions for "+
        "camera access on chatphrase.com and refresh the page.";
    } else {
      document.getElementById('virgil').textContent =
        "Recieved error trying to getUserMedia: " +
          (typeof err == "string" ? err : JSON.stringify(err)) ;
    }
  });

  //switch to limbo until media is successfully gotten
  switchState("limbo");
}

//Cheap submission function.
function goToPhrase(phrase) {
  location.hash = '#/'+ slugify(phrase);
}

// Phrase submit event listener is specified in the Jade for the page itself

// Do hashslash location.
function updateFromHash() {
  //If the URL has a hash component and the second character is '/'
  //(a hashslash, so we distinguish from in-page anchoring)
  if (location.hash && location.hash.substr(1,1) == '/'
    && location.hash.length > 2){
    beginPhrase(slugify(decodeURIComponent(location.hash.substr(2))));

  //If the URL has no hash component, or it has some meaningless
  //non-hashslash value
  } else {
    //Reset to the initial state
    document.title = 'Chatphrase';
    document.getElementById("phrase").value = "";
    switchState("landing");
  }
}

//Parse/set the initial load hash value
updateFromHash();
//Set a listener so we update the logo every time the URL hash changes
//(like when the user presses the Back button)
window.onhashchange = updateFromHash;
<commit_msg>Pull username out of TURN credentials (fixes Firefox)<commit_after>//from adapter.js
/*global RTCPeerConnection getUserMedia attachMediaStream
  reattachMediaStream webrtcDetectedBrowser webrtcDetectedVersion
  RTCSessionDescription RTCIceCandidate*/

"use strict";

// Create lowercase-and-hyphenated slug for a phrase.
function slugify(phrase) {
  return phrase.toLowerCase()
    .replace(/\&/g,' and ')
    .replace(/\%/g,' percent ')
    .replace(/[^ \-\w]/g,'')
    .replace(/[ \-]+/g,' ')
    .trim()
    .replace(/ /g,'-');
}

// Switch which "page" element is currently visible.
function switchState(stateName) {
  var states = document.querySelectorAll(".page.active");
  for (var i = 0; i < states.length; i++) {
    states[i].classList.remove('active');
    states[i].classList.add('inactive');
  }

  var newactive = document.getElementById(stateName);
  newactive.classList.remove('inactive');
  newactive.classList.add('active');
}

//TODO: general XHR function, with timeout CB

var consoleError = console.error.bind(console);

function pollRing(phrase,body,peercon){
  var pollRq = new XMLHttpRequest();
   pollRq.onreadystatechange = function () {
      if (pollRq.readyState == 4) {
        // parse response
        var resbody = JSON.parse(pollRq.responseText);

        if (resbody.answer) {
          // connect to the answer
          peercon.setRemoteDescription(
            new RTCSessionDescription(resbody.answer),
            function(){
              console.log('connected to',resbody.answer);
            },consoleError);
        }

        // For a second let's make-believe there can never be ICE
        // before we've received the session description
        addIce(peercon,resbody.ice);

        // Keep ringing and gathering ICE candidates until the
        // remote stream handler aborts the running poll
        return pollRing(phrase, body, peercon);
      }
    };
  pollRq.open("POST","/api/ring/"+phrase);
  pollRq.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");

  //allow the remote stream handler to terminate this
  enormousHackToStopPolling = pollRq;
  pollRq.send(body);
}

function answerRing(phrase,body,peercon){
  var answerRq = new XMLHttpRequest();
   answerRq.onreadystatechange = function () {
      function ringFromDesc (f) {
        return function (desc) {
          return f(phrase,JSON.stringify({ "session": desc }));
        };
      }

      if (answerRq.readyState == 4) {
        //parse response
        var resbody = JSON.parse(answerRq.responseText);

        if(resbody.status == "answered") {
          addIce(peercon,resbody.ice);
          //inform the user that they're waiting for the other end
          //to connect (if they haven't already)
          //TODO: continue polling for ICE until connected?
          //(final polls can terminate when the other end
          //acknowledges it's connected)
        } else {
          //go back to the beginning
          //TODO: destroy existing peer connection?
          beginPhrase(phrase);
        }
      }
    };
  answerRq.open("POST","/api/answer/"+phrase);
  answerRq.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");
  answerRq.send(body);
}

//because keeping track of a proper polling state is just too hard
var enormousHackToStopPolling;

// This is also hacky, but this time it's not my fault
var persistentPeerConnectionReferenceToEvadeGarbageCollectionInChrome;

function onRemoteStreamConnected(evt){
  attachMediaStream(document.getElementById('vidscreen'),evt.stream);
}

// Constructs a function that posts ICE candidates.
function icePoster(phrase, party) {
  return function(evt) {
    // After all the ICE candidates have been worked over,
    // onicecandidate gets called with an event without a candidate.
    // Send that so the other end knows when to stop ICE polling.
    //if (evt.candidate) {
      var iceRq = new XMLHttpRequest();
       iceRq.onreadystatechange = function () {
          if (iceRq.readyState == 4) {
            //do nothing
          }
        };
      iceRq.open("POST","/api/ice/"+phrase);
      iceRq.setRequestHeader(
        "Content-type", "application/json; charset=utf-8");
      iceRq.send(JSON.stringify({party: party,
        ic: evt.candidate ? evt.candidate : null}));
    //}
  };
}

//Function to handle incoming ICE candidates.
function addIce(peercon, ice){
  function addCandidate(candidate) {
    peercon.addIceCandidate(candidate,
      function() {console.log('added',candidate)},
      function(err) {console.error(candidate,err)});
  }
  if (ice) {
    for (var i=0; i < ice.length; i++) {
      if(ice[i])
        addCandidate(new RTCIceCandidate(ice[i]));
      else if(enormousHackToStopPolling) {
        enormousHackToStopPolling.abort();
      }
    }
  }
}

function startRinging(phrase,stream){
  // Create a peer connection that will use
  // vline's STUN server, Google's STUN server,
  // and numb.viagenie.ca for TURN
  var peercon = new RTCPeerConnection({
    "iceServers": [
        {"url": "stun:stun.vline.com"}
        ,{"url": "stun:stun.l.google.com:19302"}
        ,{
            url: 'turn:@numb.viagenie.ca',
            username: 'ice@chatphrase.com',
            credential: 'yovipletskickit'
        }
      ]});

  persistentPeerConnectionReferenceToEvadeGarbageCollectionInChrome = peercon;

  //add our stream to the connection
  peercon.addStream(stream);

  //add a listener for the stream from the other end
  peercon.onaddstream = onRemoteStreamConnected;

  var firstRing = new XMLHttpRequest();
   firstRing.onreadystatechange = function () {
      function ringFromDesc (f) {
        return function (desc) {
          //TODO: I'm reading some stuff about how Opus should be listed
          //as preferred at this point?

          //I'm not completely sure I understand this line (we add the session
          //we just made as a "local description"? Uh... duh?)
          peercon.setLocalDescription(desc, null, consoleError);

          //Send this request to the other end
          return f(phrase,JSON.stringify(desc),peercon);
        };
      }

      if (firstRing.readyState == 4) {
        //parse response
        var resbody = JSON.parse(firstRing.responseText);

        //NOTE: Maybe we should hold off on creating the session offers
        //until there's two endpoints on the line
        peercon.onicecandidate = icePoster(phrase,
          resbody.waiting ? 'answerer' : 'waiter');
        if (resbody.waiting) {

          //add the remote session to the connection
          peercon.setRemoteDescription(
            new RTCSessionDescription(resbody.waiting),
            function(){
              console.log('connected to',resbody.waiting);
            }, consoleError);

          addIce(peercon,resbody.ice);

          peercon.createAnswer(ringFromDesc(answerRing));
        } else {
          peercon.createOffer(ringFromDesc(pollRing),
            null, consoleError,
            { mandatory: {
              OfferToReceiveAudio: true,
              OfferToReceiveVideo: true,
              IceRestart: true}});
        }
      }
    };
  firstRing.open("GET","/api/ring/"+phrase);
  firstRing.setRequestHeader(
    "Content-type", "application/json; charset=utf-8");
  firstRing.send();
}

function beginPhrase(phrase) {
  document.title = phrase.replace(/-/g,' ') + ' : Chatphrase';
  getUserMedia({audio:true,video:true},function(stream){
    attachMediaStream(document.getElementById('pip'),stream);
    //advance to lobby / connection
    startRinging(phrase,stream);
    switchState("room");
  },function(err){
    if(err.code && err.code == err.PERMISSION_DENIED
      || err.name == "PERMISSION_DENIED"
    ){
      document.getElementById('virgil').textContent =
        "It looks like we've been denied permission to access your camera. "+
        "We need access to your camera to start the call (it wouldn't be "+
        "much of a video call if we didn't). Please reset permissions for "+
        "camera access on chatphrase.com and refresh the page.";
    } else {
      document.getElementById('virgil').textContent =
        "Recieved error trying to getUserMedia: " +
          (typeof err == "string" ? err : JSON.stringify(err)) ;
    }
  });

  //switch to limbo until media is successfully gotten
  switchState("limbo");
}

//Cheap submission function.
function goToPhrase(phrase) {
  location.hash = '#/'+ slugify(phrase);
}

// Phrase submit event listener is specified in the Jade for the page itself

// Do hashslash location.
function updateFromHash() {
  //If the URL has a hash component and the second character is '/'
  //(a hashslash, so we distinguish from in-page anchoring)
  if (location.hash && location.hash.substr(1,1) == '/'
    && location.hash.length > 2){
    beginPhrase(slugify(decodeURIComponent(location.hash.substr(2))));

  //If the URL has no hash component, or it has some meaningless
  //non-hashslash value
  } else {
    //Reset to the initial state
    document.title = 'Chatphrase';
    document.getElementById("phrase").value = "";
    switchState("landing");
  }
}

//Parse/set the initial load hash value
updateFromHash();
//Set a listener so we update the logo every time the URL hash changes
//(like when the user presses the Back button)
window.onhashchange = updateFromHash;
<|endoftext|>


<commit_before>'use strict';

starChat.Stream = (function () {
    var Stream = function (packetProcessor) {
        this.packetProcessor_ = packetProcessor;
        this.continuingErrorNum_ = 0;
        this.ajax_ = null;
    };
    Stream.prototype.start = function (view, startTime) {
        if (this.ajax_) {
            console.error('An ajax object already exists!');
            return;
        }
        this.continuingErrorNum_ = 0;
        var self = this;
        var session = view.session();
        var streamReadIndex = 0;
        var url = '/users/' + encodeURIComponent(session.userName()) + '/stream';
        if (startTime !== void(0)) {
            url += '?start_time=' + encodeURIComponent(startTime);
        }
        var restartStream = function (lastTime) {
            self.stop();
            if (!view.session().isLoggedIn()) {
                return;
            }
            self.start(view, lastTime);
        };
        var callbacks = {
            onprogress: function () {
                console.log('Reading stream...');
                self.continuingErrorNum_ = 0;
                // TODO: Reconnecting if overflow
                var xhr = this;
                var text = xhr.responseText;
                var subText = text.substring(streamReadIndex);
                while (true) {
                    var tokenLength = subText.search("\n");
                    if (tokenLength === -1) {
                        break;
                    }
                    streamReadIndex += tokenLength + 1;
                    var token = subText.substring(0, tokenLength);
                    subText = subText.substring(tokenLength + 1);
                    try {
                        var packet = JSON.parse(token);
                    } catch (e) {
                        console.log(e);
                        continue;
                    }
                    self.packetProcessor_.process(packet, view);
                }
                view.update();
            },
            success: function (data, textStatus, jqXHR) {
                self.continuingErrorNum_ = 0;
                setTimeout(function () {
                    restartStream(parseInt($.now() / 1000) - 10);
                }, 0);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.error('Stream Error!');
                console.error(textStatus);
                self.continuingErrorNum_++;
                if (20 <= self.ontinuingErrorNum_) {
                    console.error('Too many errors!');
                    // TODO: implement showing error message
                    return;
                }
                setTimeout(function () {
                    restartStream(parseInt($.now() / 1000) - 10);
                }, 1000);
            },
        };
        console.log('Connecting stream...');
        this.ajax_ = starChat.ajax(session.userName(), session.password(),
                                   url,
                                   'GET',
                                   callbacks);
    };
    Stream.prototype.stop = function () {
        if (!this.ajax_) {
            return;
        }
        this.continuingErrorNum_ = 0;
        this.ajax_.abort();
        this.ajax_ = null;
    };
    return Stream;
})();
<commit_msg>Bug fix: misspelling<commit_after>'use strict';

starChat.Stream = (function () {
    var Stream = function (packetProcessor) {
        this.packetProcessor_ = packetProcessor;
        this.continuingErrorNum_ = 0;
        this.ajax_ = null;
    };
    Stream.prototype.start = function (view, startTime) {
        if (this.ajax_) {
            console.error('An ajax object already exists!');
            return;
        }
        this.continuingErrorNum_ = 0;
        var self = this;
        var session = view.session();
        var streamReadIndex = 0;
        var url = '/users/' + encodeURIComponent(session.userName()) + '/stream';
        if (startTime !== void(0)) {
            url += '?start_time=' + encodeURIComponent(startTime);
        }
        var restartStream = function (lastTime) {
            self.stop();
            if (!view.session().isLoggedIn()) {
                return;
            }
            self.start(view, lastTime);
        };
        var callbacks = {
            onprogress: function () {
                console.log('Reading stream...');
                self.continuingErrorNum_ = 0;
                // TODO: Reconnecting if overflow
                var xhr = this;
                var text = xhr.responseText;
                var subText = text.substring(streamReadIndex);
                while (true) {
                    var tokenLength = subText.search("\n");
                    if (tokenLength === -1) {
                        break;
                    }
                    streamReadIndex += tokenLength + 1;
                    var token = subText.substring(0, tokenLength);
                    subText = subText.substring(tokenLength + 1);
                    try {
                        var packet = JSON.parse(token);
                    } catch (e) {
                        console.log(e);
                        continue;
                    }
                    self.packetProcessor_.process(packet, view);
                }
                view.update();
            },
            success: function (data, textStatus, jqXHR) {
                self.continuingErrorNum_ = 0;
                setTimeout(function () {
                    restartStream(parseInt($.now() / 1000) - 10);
                }, 0);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.error('Stream Error!');
                console.error(textStatus);
                self.continuingErrorNum_++;
                if (20 <= self.continuingErrorNum_) {
                    console.error('Too many errors!');
                    // TODO: implement showing error message
                    return;
                }
                setTimeout(function () {
                    restartStream(parseInt($.now() / 1000) - 10);
                }, 1000);
            },
        };
        console.log('Connecting stream...');
        this.ajax_ = starChat.ajax(session.userName(), session.password(),
                                   url,
                                   'GET',
                                   callbacks);
    };
    Stream.prototype.stop = function () {
        if (!this.ajax_) {
            return;
        }
        this.continuingErrorNum_ = 0;
        this.ajax_.abort();
        this.ajax_ = null;
    };
    return Stream;
})();
<|endoftext|>


<commit_before>var armyc2 = armyc2 || {};
/** namespace */
armyc2.c2sd = armyc2.c2sd || {};
armyc2.c2sd.renderer = armyc2.c2sd.renderer || {};

armyc2.c2sd.renderer.MilStdIconRenderer = (function () {

    var MilStdAttributes = armyc2.c2sd.renderer.utilities.MilStdAttributes,
        SymbolUtilities = armyc2.c2sd.renderer.utilities.SymbolUtilities,
        UnitDefTable = armyc2.c2sd.renderer.utilities.UnitDefTable,
        SymbolDefTable = armyc2.c2sd.renderer.utilities.SymbolDefTable,
        RendererSettings = armyc2.c2sd.renderer.utilities.RendererSettings,
        SinglePointRenderer = armyc2.c2sd.renderer.SinglePointRenderer,
        TacticalGraphicIconRenderer = armyc2.c2sd.renderer.TacticalGraphicIconRenderer,
        initialized = false;

    try
    {
        if(initialized === false)
        {
            //load in xml files
            UnitDefTable.init();
            SymbolDefTable.init();
            armyc2.c2sd.renderer.utilities.SinglePointLookup.init();
            armyc2.c2sd.renderer.utilities.UnitFontLookup.init();
            armyc2.c2sd.renderer.utilities.TacticalGraphicLookup.init();

            if(UnitDefTable.hasSymbolMap(RendererSettings.Symbology_2525Bch2_USAS_13_14)===false)
            {//if 2525B info isn't loaded, make C the rendering default.
                RendererSettings.setSymbologyStandard(RendererSettings.Symbology_2525C);
            }

            initialized = true;
        }
    }
    catch(err)
    {
        err.message += " - MilStdIconRenderer failed to initialize";
        armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdIconRenderer","Init",err);
    }

    function renderTacticalMultipointIcon(symbolID, modifiers)
    {
        var lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
        if(modifiers[MilStdAttributes.LineColor] !== undefined )
        {
            lineColor = modifiers[MilStdAttributes.LineColor];
        }
        var size = RendererSettings.getDefaultPixelSize();//40;
        if(modifiers[MilStdAttributes.PixelSize] !== undefined )
        {
            size = modifiers[MilStdAttributes.PixelSize];
        }

        var ii = TacticalGraphicIconRenderer.getIcon(symbolID, size, lineColor);
        return ii;
    }

return{

    CanRender: function(){

    },
    Render: function(symbolID, modifiers){
        if(!(modifiers === null))
        {
            modifiers = {};
        }
        var symStd = 0;
        if(modifiers[MilStdAttributes.SymbologyStandard])
        {
            symStd = modifiers[MilStdAttributes.SymbologyStandard];
        }
        else
        {
            symStd = RendererSettings.getSymbologyStandard();
            modifiers[MilStdAttributes.SymbologyStandard] = symStd;
        }

        var basicID = SymbolUtilities.getBasicSymbolID(symbolID);

        if(SymbolUtilities.isTacticalGraphic(symbolID))
        {
            var sd = SymbolDefTable.getSymbolDef(basicID,symStd);
            if(sd === null)
            {
                symbolID = SymbolUtilities.reconcileSymbolID(symbolID);
                basicID = SymbolUtilities.getBasicSymbolID(symbolID);
                sd = SymbolDefTable.getSymbolDef(basicID);
            }

            if(sd !== null && sd.drawCategory === SymbolDefTable.DRAW_CATEGORY_POINT)
            {
                return armyc2.c2sd.renderer.SinglePointRenderer.renderSPTG(symbolID, modifiers);
            }
            else
            {
                return renderTacticalMultipointIcon(symbolID,modifiers);
            }
        }
        else if(UnitDefTable.hasUnitDef(basicID,symStd))
        {
            return SinglePointRenderer.renderUnit(symbolID, modifiers);
        }
        else if(SymbolUtilities.is3dAirspace(symbolID))
        {
            return renderTacticalMultipointIcon(symbolID, modifiers);
        }
        else
        {
            symbolID = SymbolUtilities.reconcileSymbolID(symbolID,false);
            return SinglePointRenderer.renderUnit(symbolID, modifiers);
        }
    }
};
}());
<commit_msg>fixed typo that broke modifiers<commit_after>var armyc2 = armyc2 || {};
/** namespace */
armyc2.c2sd = armyc2.c2sd || {};
armyc2.c2sd.renderer = armyc2.c2sd.renderer || {};

armyc2.c2sd.renderer.MilStdIconRenderer = (function () {

    var MilStdAttributes = armyc2.c2sd.renderer.utilities.MilStdAttributes,
        SymbolUtilities = armyc2.c2sd.renderer.utilities.SymbolUtilities,
        UnitDefTable = armyc2.c2sd.renderer.utilities.UnitDefTable,
        SymbolDefTable = armyc2.c2sd.renderer.utilities.SymbolDefTable,
        RendererSettings = armyc2.c2sd.renderer.utilities.RendererSettings,
        SinglePointRenderer = armyc2.c2sd.renderer.SinglePointRenderer,
        TacticalGraphicIconRenderer = armyc2.c2sd.renderer.TacticalGraphicIconRenderer,
        initialized = false;

    try
    {
        if(initialized === false)
        {
            //load in xml files
            UnitDefTable.init();
            SymbolDefTable.init();
            armyc2.c2sd.renderer.utilities.SinglePointLookup.init();
            armyc2.c2sd.renderer.utilities.UnitFontLookup.init();
            armyc2.c2sd.renderer.utilities.TacticalGraphicLookup.init();

            if(UnitDefTable.hasSymbolMap(RendererSettings.Symbology_2525Bch2_USAS_13_14)===false)
            {//if 2525B info isn't loaded, make C the rendering default.
                RendererSettings.setSymbologyStandard(RendererSettings.Symbology_2525C);
            }

            initialized = true;
        }
    }
    catch(err)
    {
        err.message += " - MilStdIconRenderer failed to initialize";
        armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdIconRenderer","Init",err);
    }

    function renderTacticalMultipointIcon(symbolID, modifiers)
    {
        var lineColor = SymbolUtilities.getLineColorOfAffiliation(symbolID);
        if(modifiers[MilStdAttributes.LineColor] !== undefined )
        {
            lineColor = modifiers[MilStdAttributes.LineColor];
        }
        var size = RendererSettings.getDefaultPixelSize();//40;
        if(modifiers[MilStdAttributes.PixelSize] !== undefined )
        {
            size = modifiers[MilStdAttributes.PixelSize];
        }

        var ii = TacticalGraphicIconRenderer.getIcon(symbolID, size, lineColor);
        return ii;
    }

return{

    CanRender: function(){

    },
    Render: function(symbolID, modifiers){
        if(!(modifiers))
        {
            modifiers = {};
        }
        var symStd = 0;
        if(modifiers[MilStdAttributes.SymbologyStandard])
        {
            symStd = modifiers[MilStdAttributes.SymbologyStandard];
        }
        else
        {
            symStd = RendererSettings.getSymbologyStandard();
            modifiers[MilStdAttributes.SymbologyStandard] = symStd;
        }

        var basicID = SymbolUtilities.getBasicSymbolID(symbolID);

        if(SymbolUtilities.isTacticalGraphic(symbolID))
        {
            var sd = SymbolDefTable.getSymbolDef(basicID,symStd);
            if(sd === null)
            {
                symbolID = SymbolUtilities.reconcileSymbolID(symbolID);
                basicID = SymbolUtilities.getBasicSymbolID(symbolID);
                sd = SymbolDefTable.getSymbolDef(basicID);
            }

            if(sd !== null && sd.drawCategory === SymbolDefTable.DRAW_CATEGORY_POINT)
            {
                return armyc2.c2sd.renderer.SinglePointRenderer.renderSPTG(symbolID, modifiers);
            }
            else
            {
                return renderTacticalMultipointIcon(symbolID,modifiers);
            }
        }
        else if(UnitDefTable.hasUnitDef(basicID,symStd))
        {
            return SinglePointRenderer.renderUnit(symbolID, modifiers);
        }
        else if(SymbolUtilities.is3dAirspace(symbolID))
        {
            return renderTacticalMultipointIcon(symbolID, modifiers);
        }
        else
        {
            symbolID = SymbolUtilities.reconcileSymbolID(symbolID,false);
            return SinglePointRenderer.renderUnit(symbolID, modifiers);
        }
    }
};
}());
<|endoftext|>