<commit_before>const {DatabaseTypes: {JSONArrayColumn}} = require('isomorphic-core');

module.exports = (sequelize, Sequelize) => {
  return sequelize.define('thread', {
    id: { type: Sequelize.STRING(65), primaryKey: true },
    accountId: { type: Sequelize.STRING, allowNull: false },
    version: Sequelize.INTEGER,
    remoteThreadId: Sequelize.STRING,
    subject: Sequelize.STRING(500),
    snippet: Sequelize.STRING(255),
    unreadCount: {
      type: Sequelize.INTEGER,
      get: function get() { return this.getDataValue('unreadCount') || 0 },
    },
    starredCount: {
      type: Sequelize.INTEGER,
      get: function get() { return this.getDataValue('starredCount') || 0 },
    },
    firstMessageDate: Sequelize.DATE,
    lastMessageDate: Sequelize.DATE,
    lastMessageReceivedDate: Sequelize.DATE,
    lastMessageSentDate: Sequelize.DATE,
    participants: JSONArrayColumn('participants'),
    hasAttachments: {type: Sequelize.BOOLEAN, defaultValue: false},
  }, {
    indexes: [
      { fields: ['subject'] },
      { fields: ['remoteThreadId'] },
    ],
    classMethods: {
      MAX_THREAD_LENGTH: 500,
      requiredAssociationsForJSON: ({Folder, Label, Message}) => {
        return [
          {model: Folder},
          {model: Label},
          {
            model: Message,
            attributes: ['id'],
          },
        ]
      },
      associate: ({Thread, Folder, ThreadFolder, Label, ThreadLabel, Message, Reference}) => {
        Thread.belongsToMany(Folder, {through: ThreadFolder})
        Thread.belongsToMany(Label, {through: ThreadLabel})
        Thread.hasMany(Message, {onDelete: 'cascade', hooks: true})
        // TODO: what is the desired cascade behaviour for references?
        Thread.hasMany(Reference)
      },
    },
    instanceMethods: {
      async updateLabelsAndFolders() {
        const messages = await this.getMessages({attributes: ['id', 'folderId']});
        const labelIds = new Set()
        const folderIds = new Set()

        await Promise.all(messages.map(async (msg) => {
          const labels = await msg.getLabels({attributes: ['id']})
          labels.forEach(({id}) => labelIds.add(id));
          folderIds.add(msg.folderId)
        }));

        await Promise.all([
          this.setLabels(Array.from(labelIds)),
          this.setFolders(Array.from(folderIds)),
        ]);

        return this.save();
      },

      // Updates the attributes that don't require an external set to prevent
      // duplicates. Currently includes starred/unread counts, various date
      // values, and snippet. Does not save the thread.
      _updateSimpleMessageAttributes(message) {
        // Update starred/unread counts
        this.starredCount += message.starred ? 1 : 0;
        this.unreadCount += message.unread ? 1 : 0;

        // Update dates/snippet
        if (!this.lastMessageDate || (message.date > this.lastMessageDate)) {
          this.lastMessageDate = message.date;
          this.snippet = message.snippet;
        }
        if (!this.firstMessageDate || (message.date < this.firstMessageDate)) {
          this.firstMessageDate = message.date;
        }

        // Figure out if the message is sent or received and update more dates
        const isSent = (
          message.folder.role === 'sent' ||
          !!message.labels.find(l => l.role === 'sent')
        );

        if (isSent && ((message.date > this.lastMessageSentDate) || !this.lastMessageSentDate)) {
          this.lastMessageSentDate = message.date;
        }
        if (((message.date > this.lastMessageReceivedDate) || !this.lastMessageReceivedDate)) {
          this.lastMessageReceivedDate = message.date;
        }
      },

      async updateFromMessages({db, messages, recompute, transaction} = {}) {
        if (!(messages instanceof Array)) {
          throw new Error('Thread.updateFromMessages() expected an array of messages')
        }
        if (!(this.folders instanceof Array) || !(this.labels instanceof Array)) {
          throw new Error('Thread.updateFromMessages() expected .folders and .labels to be inflated arrays')
        }

        let _messages = messages;
        if (recompute) {
          if (!db) {
            throw new Error('Cannot recompute thread attributes without a database reference.')
          }
          const {Label, Folder, File} = db;
          _messages = await this.getMessages({
            include: [{model: Label}, {model: Folder}, {model: File}],
            attributes: {exclude: ['body']},
          });
          if (_messages.length === 0) {
            return this.destroy();
          }

          this.folders = [];
          this.labels = [];
          this.participants = [];
          this.unreadCount = 0;
          this.starredCount = 0;
          this.hasAttachments = false;
          this.snippet = null;
          this.lastMessageDate = null;
          this.firstMessageDate = null;
          this.lastMessageSentDate = null;
          this.lastMessageReceivedDate = null;
        }

        const folders = new Set(this.folders);
        const labels = new Set(this.labels);
        const participantEmails = new Set(this.participants.map(p => p.email));

        for (const message of _messages) {
          if (!(message.labels instanceof Array)) {
            throw new Error("Expected message.labels to be an inflated array.");
          }
          if (!message.folder) {
            throw new Error("Expected message.folder value to be present.");
          }

          folders.add(message.folder)
          message.labels.forEach(label => labels.add(label))

          this._updateSimpleMessageAttributes(message);

          const {to, cc, bcc, from} = message;
          to.concat(cc, bcc, from).forEach(participant => {
            if (participantEmails.has(participant.email)) {
              return;
            }
            participantEmails.add(participant.email)
            this.participants.push(participant)
          })

          // message.files only needs to be inflated if we're recomputing
          // the thread. Otherwise, .hasAttachments is set after we run
          // extractFiles on each message.
          if (!this.hasAttachments && message.files instanceof Array) {
            this.hasAttachments = message.files.some(f => !f.contentId);
          }
        }

        // Setting folders and labels cannot be done on a thread without an id
        let thread = this;
        if (!this.id) {
          thread = await this.save({transaction});
        }

        await thread.setFolders(Array.from(folders), {transaction})
        await thread.setLabels(Array.from(labels), {transaction})
        return thread.save({transaction});
      },

      toJSON() {
        if (!(this.labels instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where labels were not eagerly loaded.")
        }
        if (!(this.folders instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where folders were not eagerly loaded.")
        }
        if (!(this.messages instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where messages were not eagerly loaded. (Only need the IDs!)")
        }

        const response = {
          id: `${this.id}`,
          object: 'thread',
          folders: this.folders.map(f => f.toJSON()),
          labels: this.labels.map(l => l.toJSON()),
          account_id: this.accountId,
          participants: this.participants,
          subject: this.subject,
          snippet: this.snippet,
          unread: this.unreadCount > 0,
          starred: this.starredCount > 0,
          has_attachments: this.hasAttachments,
          last_message_timestamp: this.lastMessageDate ? this.lastMessageDate.getTime() / 1000.0 : null,
          last_message_sent_timestamp: this.lastMessageSentDate ? this.lastMessageSentDate.getTime() / 1000.0 : null,
          last_message_received_timestamp: this.lastMessageReceivedDate ? this.lastMessageReceivedDate.getTime() / 1000.0 : null,
        };

        const expanded = this.messages[0] ? !!this.messages[0].accountId : false;
        if (expanded) {
          response.messages = this.messages;
        } else {
          response.message_ids = this.messages.map(m => m.id);
        }

        return response;
      },
    },
  });
};
<commit_msg>[local-sync] Make sure thread is saved before updating folders/labels<commit_after>const {DatabaseTypes: {JSONArrayColumn}} = require('isomorphic-core');

module.exports = (sequelize, Sequelize) => {
  return sequelize.define('thread', {
    id: { type: Sequelize.STRING(65), primaryKey: true },
    accountId: { type: Sequelize.STRING, allowNull: false },
    version: Sequelize.INTEGER,
    remoteThreadId: Sequelize.STRING,
    subject: Sequelize.STRING(500),
    snippet: Sequelize.STRING(255),
    unreadCount: {
      type: Sequelize.INTEGER,
      get: function get() { return this.getDataValue('unreadCount') || 0 },
    },
    starredCount: {
      type: Sequelize.INTEGER,
      get: function get() { return this.getDataValue('starredCount') || 0 },
    },
    firstMessageDate: Sequelize.DATE,
    lastMessageDate: Sequelize.DATE,
    lastMessageReceivedDate: Sequelize.DATE,
    lastMessageSentDate: Sequelize.DATE,
    participants: JSONArrayColumn('participants'),
    hasAttachments: {type: Sequelize.BOOLEAN, defaultValue: false},
  }, {
    indexes: [
      { fields: ['subject'] },
      { fields: ['remoteThreadId'] },
    ],
    classMethods: {
      MAX_THREAD_LENGTH: 500,
      requiredAssociationsForJSON: ({Folder, Label, Message}) => {
        return [
          {model: Folder},
          {model: Label},
          {
            model: Message,
            attributes: ['id'],
          },
        ]
      },
      associate: ({Thread, Folder, ThreadFolder, Label, ThreadLabel, Message, Reference}) => {
        Thread.belongsToMany(Folder, {through: ThreadFolder})
        Thread.belongsToMany(Label, {through: ThreadLabel})
        Thread.hasMany(Message, {onDelete: 'cascade', hooks: true})
        // TODO: what is the desired cascade behaviour for references?
        Thread.hasMany(Reference)
      },
    },
    instanceMethods: {
      async updateLabelsAndFolders() {
        const messages = await this.getMessages({attributes: ['id', 'folderId']});
        const labelIds = new Set()
        const folderIds = new Set()

        await Promise.all(messages.map(async (msg) => {
          const labels = await msg.getLabels({attributes: ['id']})
          labels.forEach(({id}) => labelIds.add(id));
          folderIds.add(msg.folderId)
        }));

        await Promise.all([
          this.setLabels(Array.from(labelIds)),
          this.setFolders(Array.from(folderIds)),
        ]);

        return this.save();
      },

      // Updates the attributes that don't require an external set to prevent
      // duplicates. Currently includes starred/unread counts, various date
      // values, and snippet. Does not save the thread.
      _updateSimpleMessageAttributes(message) {
        // Update starred/unread counts
        this.starredCount += message.starred ? 1 : 0;
        this.unreadCount += message.unread ? 1 : 0;

        // Update dates/snippet
        if (!this.lastMessageDate || (message.date > this.lastMessageDate)) {
          this.lastMessageDate = message.date;
          this.snippet = message.snippet;
        }
        if (!this.firstMessageDate || (message.date < this.firstMessageDate)) {
          this.firstMessageDate = message.date;
        }

        // Figure out if the message is sent or received and update more dates
        const isSent = (
          message.folder.role === 'sent' ||
          !!message.labels.find(l => l.role === 'sent')
        );

        if (isSent && ((message.date > this.lastMessageSentDate) || !this.lastMessageSentDate)) {
          this.lastMessageSentDate = message.date;
        }
        if (((message.date > this.lastMessageReceivedDate) || !this.lastMessageReceivedDate)) {
          this.lastMessageReceivedDate = message.date;
        }
      },

      async updateFromMessages({db, messages, recompute, transaction} = {}) {
        if (!(messages instanceof Array)) {
          throw new Error('Thread.updateFromMessages() expected an array of messages')
        }
        if (!(this.folders instanceof Array) || !(this.labels instanceof Array)) {
          throw new Error('Thread.updateFromMessages() expected .folders and .labels to be inflated arrays')
        }

        let _messages = messages;
        if (recompute) {
          if (!db) {
            throw new Error('Cannot recompute thread attributes without a database reference.')
          }
          const {Label, Folder, File} = db;
          _messages = await this.getMessages({
            include: [{model: Label}, {model: Folder}, {model: File}],
            attributes: {exclude: ['body']},
          });
          if (_messages.length === 0) {
            return this.destroy();
          }

          this.folders = [];
          this.labels = [];
          this.participants = [];
          this.unreadCount = 0;
          this.starredCount = 0;
          this.hasAttachments = false;
          this.snippet = null;
          this.lastMessageDate = null;
          this.firstMessageDate = null;
          this.lastMessageSentDate = null;
          this.lastMessageReceivedDate = null;
        }

        const folderIds = new Set(this.folders.map(f => f.id));
        const labelIds = new Set(this.labels.map(l => l.id));
        const participantEmails = new Set(this.participants.map(p => p.email));

        for (const message of _messages) {
          if (!(message.labels instanceof Array)) {
            throw new Error("Expected message.labels to be an inflated array.");
          }
          if (!message.folder) {
            throw new Error("Expected message.folder value to be present.");
          }

          folderIds.add(message.folder.id)
          message.labels.forEach(label => labelIds.add(label.id))

          this._updateSimpleMessageAttributes(message);

          const {to, cc, bcc, from} = message;
          to.concat(cc, bcc, from).forEach(participant => {
            if (participantEmails.has(participant.email)) {
              return;
            }
            participantEmails.add(participant.email)
            this.participants.push(participant)
          })

          // message.files only needs to be inflated if we're recomputing
          // the thread. Otherwise, .hasAttachments is set after we run
          // extractFiles on each message.
          if (!this.hasAttachments && message.files instanceof Array) {
            this.hasAttachments = message.files.some(f => !f.contentId);
          }
        }

        // Setting folders and labels cannot be done on a thread without an id
        const savedThread = await this.save({transaction});

        await Promise.all([
          savedThread.setFolders(Array.from(folderIds), {transaction}),
          savedThread.setLabels(Array.from(labelIds), {transaction}),
        ])
        return savedThread.save({transaction});
      },

      toJSON() {
        if (!(this.labels instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where labels were not eagerly loaded.")
        }
        if (!(this.folders instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where folders were not eagerly loaded.")
        }
        if (!(this.messages instanceof Array)) {
          throw new Error("Thread.toJSON called on a thread where messages were not eagerly loaded. (Only need the IDs!)")
        }

        const response = {
          id: `${this.id}`,
          object: 'thread',
          folders: this.folders.map(f => f.toJSON()),
          labels: this.labels.map(l => l.toJSON()),
          account_id: this.accountId,
          participants: this.participants,
          subject: this.subject,
          snippet: this.snippet,
          unread: this.unreadCount > 0,
          starred: this.starredCount > 0,
          has_attachments: this.hasAttachments,
          last_message_timestamp: this.lastMessageDate ? this.lastMessageDate.getTime() / 1000.0 : null,
          last_message_sent_timestamp: this.lastMessageSentDate ? this.lastMessageSentDate.getTime() / 1000.0 : null,
          last_message_received_timestamp: this.lastMessageReceivedDate ? this.lastMessageReceivedDate.getTime() / 1000.0 : null,
        };

        const expanded = this.messages[0] ? !!this.messages[0].accountId : false;
        if (expanded) {
          response.messages = this.messages;
        } else {
          response.message_ids = this.messages.map(m => m.id);
        }

        return response;
      },
    },
  });
};
<|endoftext|>


<commit_before>/*
 * Class cowboy.InputFile
 * Make an input[type=file]
 *
 * TODO : Support Multiple Files
 *        Automaticaly put sizes in errors messages
 */
cowboy.InputFile = new Class({
	Implements: cowboy.Options,
	options: {
		minSize: 4000,
		minSizeMessage: "",
		maxSize: 5000000,
		maxSizeMessage: "",
		requiredType: null,
		requiredTypeMessage: "File type is not correct",
	}
	, initialize: function(input, options) {
		var _this = this;
		this.input = input;
		this.options = Object.merge(this.options, options);

		// Set Options and overload options by properties in the input element
		this.setElementOptions(this.options, input);

		this.options.minSizeMessage = "File size needs to be more than " + ((this.options.minSize > 1000000) ? String(Math.round(this.options.minSize / 1000000)) + "Mo" : String(this.options.minSize / 1000) + "Ko");
		this.options.maxSizeMessage = "File size needs to be less than " + ((this.options.maxSize > 1000000) ? String(Math.round(this.options.maxSize / 1000000)) + "Mo" : String(this.options.maxSize / 1000) + "Ko");

		// Rebuild the Element
		var inputFile = new Element('div', {"Class": "inputfile"});

		// Inject the original input file into the contener "inputFile"
		inputFile.inject(this.input, 'after');
		this.input.inject(inputFile);

		// Create the fake input file
		var fakeInputFileContener = new Element('div', {"Class": "fakeinputfile"});
		this.fakeInputFile = new Element('input', {"type": "text","readonly": "readonly"});
		var icon = new Element('span', {"Class": "directory"});
		fakeInputFileContener.inject(inputFile);
		this.fakeInputFile.inject(fakeInputFileContener);
		icon.inject(fakeInputFileContener);

		// Add Event to control the value
		this.input.addEvent('change', _this._check.bind(_this));

		// Add Events on fake input and icon to focus the input
    	this.fakeInputFile.addEvent('focus', function (e) {
    		e.stop();
    		_this.input.focus();
    		_this.input.click();
    		$$('html')[0].focus();
    	});
    	icon.addEvent('click', function () { _this.input.click(); });
	}
	, _check: function() {
		// with FileAPI
		if (window.File && window.Blob) {
			var file = this.input.files[0];

			// Check Type
			if ((this.options.requiredType == null || file.type == this.options.requiredType || this.options.requiredType.contains(file.type))
				 && file.size >= this.options.minSize && file.size <= this.options.maxSize) {
				this.fakeInputFile.value = file.name; // Show filename
				this.fakeInputFile.removeClass('log-error').addClass('log-validated');
			}
			// Show Warnings
			else {
				if (this.options.requiredType != null && file.type != this.options.requiredType || !this.options.requiredType.contains(file.type)) {
					this.fakeInputFile.value = this.options.requiredTypeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size < this.options.minSize) {
					this.fakeInputFile.value = this.options.minSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size > this.options.maxSize) {
					this.fakeInputFile.value = this.options.maxSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
			}
		}

		// Fallback for old browsers
		else if (this.value) this.fakeInputFile.value = e.value;
	}
});
<commit_msg>Patch to solve bugs with default required type and min/max size<commit_after>/*
 * Class cowboy.InputFile
 * Make an input[type=file]
 *
 * TODO : Support Multiple Files
 *        Automaticaly put sizes in errors messages
 */
cowboy.InputFile = new Class({
	Implements: cowboy.Options,
	options: {
		minSize: 4000,
		minSizeMessage: "",
		maxSize: 5000000,
		maxSizeMessage: "",
		requiredType: null,
		requiredTypeMessage: "File type is not correct",
	}
	, initialize: function(input, options) {
		var _this = this;
		this.input = input;
		this.options = Object.merge(this.options, options);

		// Set Options and overload options by properties in the input element
		this.setElementOptions(this.options, input);

		this.options.minSizeMessage = "File size needs to be more than " + ((this.options.minSize > 1000000) ? String(Math.round(this.options.minSize / 1000000)) + "Mo" : String(Math.round(this.options.minSize / 1000)) + "Ko");
		this.options.maxSizeMessage = "File size needs to be less than " + ((this.options.maxSize > 1000000) ? String(Math.round(this.options.maxSize / 1000000)) + "Mo" : String(Math.round(this.options.maxSize / 1000)) + "Ko");

		// Rebuild the Element
		var inputFile = new Element('div', {"Class": "inputfile"});

		// Inject the original input file into the contener "inputFile"
		inputFile.inject(this.input, 'after');
		this.input.inject(inputFile);

		// Create the fake input file
		var fakeInputFileContener = new Element('div', {"Class": "fakeinputfile"});
		this.fakeInputFile = new Element('input', {"type": "text","readonly": "readonly"});
		var icon = new Element('span', {"Class": "directory"});
		fakeInputFileContener.inject(inputFile);
		this.fakeInputFile.inject(fakeInputFileContener);
		icon.inject(fakeInputFileContener);

		// Add Event to control the value
		this.input.addEvent('change', _this._check.bind(_this));

		// Add Events on fake input and icon to focus the input
    	this.fakeInputFile.addEvent('focus', function (e) {
    		e.stop();
    		_this.input.focus();
    		_this.input.click();
    		$$('html')[0].focus();
    	});
    	icon.addEvent('click', function () { _this.input.click(); });
	}
	, _check: function() {
		// with FileAPI
		if (window.File && window.Blob) {
			var file = this.input.files[0];

			// Check Type
			if ((this.options.requiredType == null || file.type == this.options.requiredType || this.options.requiredType.contains(file.type))
				 && file.size >= this.options.minSize && file.size <= this.options.maxSize) {
				this.fakeInputFile.value = file.name; // Show filename
				this.fakeInputFile.removeClass('log-error').addClass('log-validated');
			}
			// Show Warnings
			else {
				if (this.options.requiredType != null && (file.type != this.options.requiredType || !this.options.requiredType.contains(file.type))) {
					this.fakeInputFile.value = this.options.requiredTypeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size < this.options.minSize) {
					this.fakeInputFile.value = this.options.minSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
				if (file.size > this.options.maxSize) {
					this.fakeInputFile.value = this.options.maxSizeMessage;
					this.fakeInputFile.removeClass('log-validated').addClass('log-error');
				}
			}
		}

		// Fallback for old browsers
		else if (this.value) this.fakeInputFile.value = e.value;
	}
});
<|endoftext|>


<commit_before>(function (widget, utils) {
    var diameter = 600;

    var margin = {top: 10, right: 0, bottom: 30, left: 50},
        width = diameter - margin.left - margin.right,
        height = diameter - margin.top - margin.bottom;

    var x = d3.time.scale()
            .range([0, width]);

    var y = d3.scale.linear()
            .range([height, 0]);

    var y2 = d3.scale.linear()
            .domain([0, 24 * 60 * 60 * 1000])
            .range([height, 0]);

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

    var line = d3.svg.line()
            .interpolate("basis")
            .x(function(d) { return x(d.day); })
            .y(function(d) { return y(d.duration || 0); });

    var svg = widget.create("Fail duration",
                            "Average duration of pipeline failure vs. green phases",
                           "/failphases.csv")
            .svg(diameter)
            .attr('class', 'failphases');

    var g = svg
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var durationInMinutes = function (duration) {
        return duration / (60 * 1000);
    };

    var timeOfDay = function (date) {
        return (date.getTime() - (date.getTimezoneOffset() * 60 * 1000)) % (24 * 60 * 60 * 1000);
    };

    var startOfDay = function (date) {
        return new Date(date.getFullYear(), date.getMonth(), date.getDate());
    };

    var endOfDay = function (date) {
        var nextDay = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);

        return new Date(nextDay.getTime() - 1);
    };

    var phasesByDay = function (start, end) {
        var phases = [],
            startDate = new Date(start),
            endDate = new Date(end),
            endOfCurrentDay = endOfDay(startDate);

        while (endOfCurrentDay < endDate) {
            phases.push({
                start: startDate,
                end: endOfCurrentDay
            });

            startDate = new Date(endOfCurrentDay.getTime() + 1);
            endOfCurrentDay = endOfDay(startDate);
        }

        phases.push({
            start: startDate,
            end: endDate
        });

        return phases;
    };

    var flatten = function (listOfLists) {
        return listOfLists.reduce(function (a, b) { return a.concat(b); });
    };

    var calculatePhasesByDay = function (data) {
        var lastEntry;

        return flatten(data.map(function (entry) {
            var greenPhases = [],
                start = entry.start;

            if (lastEntry) {
                greenPhases = phasesByDay(lastEntry.end + 1, entry.start - 1).map(function (phase) {
                    phase.color = 'green';
                    phase.duration = entry.start - lastEntry.end;
                    return phase;
                });
            }

            lastEntry = entry;

            return greenPhases.concat(phasesByDay(entry.start, entry.end).map(function (phase) {
                phase.color = 'red';
                phase.culprits = entry.culprits;
                phase.duration = entry.end - entry.start;
                return phase;
            }));
        }));
    };

    var calculatePhases = function (data) {
        var lastPhase;

        return data.map(function (phase) {
            var calculatedPhase = {
                end: phase.end
            };

            if (lastPhase) {
                calculatedPhase.previousGreenPhaseDuration = phase.start - lastPhase.end;
            }
            calculatedPhase.redPhaseDuration = phase.end - phase.start;

            lastPhase = phase;

            return calculatedPhase;
        });
    };

    var aggregatePhaseDurationByDay = function (phases) {
        var phasesByDay = d3.nest()
                .key(function (d) {
                    var date = new Date(d.end);
                    return new Date(date.getFullYear(), date.getMonth(), date.getDate()).valueOf();
                })
                .entries(phases);

        return phasesByDay.map(function (e) {
            return {
                day: new Date(parseInt(e.key)),
                redDuration: d3.mean(e.values.map(function (v) { return v.redPhaseDuration; }), durationInMinutes),
                greenDuration: d3.mean(e.values.map(function (v) { return v.previousGreenPhaseDuration; }), durationInMinutes)
            };
        });
    };

    d3.json('/failphases', function (_, data) {
        var phaseDurationByDay = aggregatePhaseDurationByDay(calculatePhases(data));

        x.domain(d3.extent(phaseDurationByDay, function(d) { return d.day; }));
        y.domain(d3.extent(phaseDurationByDay, function(d) { return d.redDuration; }));

        g.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        g.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Duration [minutes]");

        g.selectAll('rect')
            .data(calculatePhasesByDay(data))
            .enter()
            .append('rect')
            .attr('x', function (d) {
                return x(startOfDay(d.start));
            })
            .attr('width', function (d) {
                // TODO this is constant, make it so
                return x(endOfDay(d.start)) - x(startOfDay(d.start));
            })
            .attr('y', function (d) {
                return y2(timeOfDay(d.end));
            })
            .attr('height', function (d) {
                return y2(timeOfDay(d.start)) - y2(timeOfDay(d.end));
            })
            .attr('fill', function (d) {
                return d.color;
            })
            .attr('title', function (d) {
                var duration = utils.formatTimeInMs(d.duration);
                if (d.color === 'red') {
                    return duration + '\n' + d.culprits.join(', ');
                }
                return duration;
            });

        g.selectAll('.redLine')
            .data([phaseDurationByDay.map(function (d) { return {day: d.day, duration: d.redDuration}; })])
            .enter()
            .append("path")
            .attr("d", line)
            .attr('class', 'redLine');

        g.selectAll('.greenLine')
            .data([phaseDurationByDay.map(function (d) { return {day: d.day, duration: d.greenDuration}; })])
            .enter()
            .append("path")
            .attr("d", line)
            .attr('class', 'greenLine');

    });
}(widget, utils));
<commit_msg>Disable average failure phase for now, until it shows something meaningful. Show axis for time of day<commit_after>(function (widget, utils) {
    var diameter = 600;

    var margin = {top: 10, right: 0, bottom: 30, left: 50},
        width = diameter - margin.left - margin.right,
        height = diameter - margin.top - margin.bottom;

    var x = d3.time.scale()
            .range([0, width]);

    var y = d3.scale.linear()
            .range([height, 0]);

    var y2 = d3.scale.linear()
            .domain([0, 24])
            .range([height, 0]);

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

    var y2Axis = d3.svg.axis()
            .scale(y2)
            .orient("left");

    var line = d3.svg.line()
            .interpolate("basis")
            .x(function(d) { return x(d.day); })
            .y(function(d) { return y(d.duration || 0); });

    var svg = widget.create("Fail phases",
                            "Pipeline failure vs. green phases",
                           "/failphases.csv")
            .svg(diameter)
            .attr('class', 'failphases');

    var g = svg
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var durationInMinutes = function (duration) {
        return duration / (60 * 1000);
    };

    var timeOfDay = function (date) {
        return (date.getTime() - (date.getTimezoneOffset() * 60 * 1000)) % (24 * 60 * 60 * 1000) / (60 * 60 * 1000);
    };

    var startOfDay = function (date) {
        return new Date(date.getFullYear(), date.getMonth(), date.getDate());
    };

    var endOfDay = function (date) {
        var nextDay = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);

        return new Date(nextDay.getTime() - 1);
    };

    var phasesByDay = function (start, end) {
        var phases = [],
            startDate = new Date(start),
            endDate = new Date(end),
            endOfCurrentDay = endOfDay(startDate);

        while (endOfCurrentDay < endDate) {
            phases.push({
                start: startDate,
                end: endOfCurrentDay
            });

            startDate = new Date(endOfCurrentDay.getTime() + 1);
            endOfCurrentDay = endOfDay(startDate);
        }

        phases.push({
            start: startDate,
            end: endDate
        });

        return phases;
    };

    var flatten = function (listOfLists) {
        return listOfLists.reduce(function (a, b) { return a.concat(b); });
    };

    var calculatePhasesByDay = function (data) {
        var lastEntry;

        return flatten(data.map(function (entry) {
            var greenPhases = [],
                start = entry.start;

            if (lastEntry) {
                greenPhases = phasesByDay(lastEntry.end + 1, entry.start - 1).map(function (phase) {
                    phase.color = 'green';
                    phase.duration = entry.start - lastEntry.end;
                    return phase;
                });
            }

            lastEntry = entry;

            return greenPhases.concat(phasesByDay(entry.start, entry.end).map(function (phase) {
                phase.color = 'red';
                phase.culprits = entry.culprits;
                phase.duration = entry.end - entry.start;
                return phase;
            }));
        }));
    };

    var calculatePhases = function (data) {
        var lastPhase;

        return data.map(function (phase) {
            var calculatedPhase = {
                end: phase.end
            };

            if (lastPhase) {
                calculatedPhase.previousGreenPhaseDuration = phase.start - lastPhase.end;
            }
            calculatedPhase.redPhaseDuration = phase.end - phase.start;

            lastPhase = phase;

            return calculatedPhase;
        });
    };

    var aggregatePhaseDurationByDay = function (phases) {
        var phasesByDay = d3.nest()
                .key(function (d) {
                    var date = new Date(d.end);
                    return new Date(date.getFullYear(), date.getMonth(), date.getDate()).valueOf();
                })
                .entries(phases);

        return phasesByDay.map(function (e) {
            return {
                day: new Date(parseInt(e.key)),
                redDuration: d3.mean(e.values.map(function (v) { return v.redPhaseDuration; }), durationInMinutes),
                greenDuration: d3.mean(e.values.map(function (v) { return v.previousGreenPhaseDuration; }), durationInMinutes)
            };
        });
    };

    d3.json('/failphases', function (_, data) {
        var phaseDurationByDay = aggregatePhaseDurationByDay(calculatePhases(data));

        x.domain(d3.extent(phaseDurationByDay, function(d) { return d.day; }));
        y.domain(d3.extent(phaseDurationByDay, function(d) { return d.redDuration; }));

        g.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        // g.append("g")
        //     .attr("class", "y axis")
        //     .call(yAxis)
        //     .append("text")
        //     .attr("transform", "rotate(-90)")
        //     .attr("y", 6)
        //     .attr("dy", ".71em")
        //     .style("text-anchor", "end")
        //     .text("Duration [minutes]");

        g.append("g")
            .attr("class", "y axis")
            .call(y2Axis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Time of the day");

        g.selectAll('rect')
            .data(calculatePhasesByDay(data))
            .enter()
            .append('rect')
            .attr('x', function (d) {
                return x(startOfDay(d.start));
            })
            .attr('width', function (d) {
                // TODO this is constant, make it so
                return x(endOfDay(d.start)) - x(startOfDay(d.start));
            })
            .attr('y', function (d) {
                return y2(timeOfDay(d.end));
            })
            .attr('height', function (d) {
                return y2(timeOfDay(d.start)) - y2(timeOfDay(d.end));
            })
            .attr('fill', function (d) {
                return d.color;
            })
            .attr('title', function (d) {
                var duration = utils.formatTimeInMs(d.duration);
                if (d.color === 'red') {
                    return duration + '\n' + d.culprits.join(', ');
                }
                return duration;
            });

        // g.selectAll('.redLine')
        //     .data([phaseDurationByDay.map(function (d) { return {day: d.day, duration: d.redDuration}; })])
        //     .enter()
        //     .append("path")
        //     .attr("d", line)
        //     .attr('class', 'redLine');

        // g.selectAll('.greenLine')
        //     .data([phaseDurationByDay.map(function (d) { return {day: d.day, duration: d.greenDuration}; })])
        //     .enter()
        //     .append("path")
        //     .attr("d", line)
        //     .attr('class', 'greenLine');

    });
}(widget, utils));
<|endoftext|>


<commit_before>/*
 * loquat-core test / prim.Result
 * copyright (c) 2016 Susisu
 */

"use strict";

describe(".Result", () => {
    require("./Result/constructor.js");
});
<commit_msg>[core] Fix test is not loaded<commit_after>/*
 * loquat-core test / prim.Result
 * copyright (c) 2016 Susisu
 */

"use strict";

describe(".Result", () => {
    require("./Result/constructor.js");
    require("./Result/equal.js");
});
<|endoftext|>


<commit_before>/*global describe, it, browser, require */

describe('popover', function () {
    'use strict';

    it('should match the baseline popover screenshot when it has a title', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-title a')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_title',
                selector: '#screenshot-popover-title'
            })
            .call(done);
    });

    it('should match the baseline popover screenshot when it does not have a title', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-no-title a')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_no_title',
                selector: '#screenshot-popover-no-title'
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position top', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-top button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_top',
                selector: '#screenshot-popover-top'
            })
            .call(done);
    });

    it('should match the baseline popover screenshot with position bottom', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-bottom button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_bottom',
                selector: '#screenshot-popover-bottom'
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position left', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-left button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_left',
                selector: '#screenshot-popover-left'
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position right', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-right button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_right',
                selector: '#screenshot-popover-right'
            })
            .call(done);
    });

});
<commit_msg>added checkAccessbility<commit_after>/*global describe, it, browser, require */

describe('popover', function () {
    'use strict';

    it('should match the baseline popover screenshot when it has a title', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-title a')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_title',
                selector: '#screenshot-popover-title',
                checkAccessibility: true
            })
            .call(done);
    });

    it('should match the baseline popover screenshot when it does not have a title', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-no-title a')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_no_title',
                selector: '#screenshot-popover-no-title',
                checkAccessibility: true
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position top', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-top button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_top',
                selector: '#screenshot-popover-top',
                checkAccessibility: true
            })
            .call(done);
    });

    it('should match the baseline popover screenshot with position bottom', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-bottom button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_bottom',
                selector: '#screenshot-popover-bottom',
                checkAccessibility: true
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position left', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-left button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_left',
                selector: '#screenshot-popover-left',
                checkAccessibility: true
            })
            .call(done);

    });

    it('should match the baseline popover screenshot with position right', function (done) {
        var common = require('../common');

        browser
            .setupTest('/popover/fixtures/test.full.html')
            .click('#screenshot-popover-right button')
            .compareScreenshot({
                prefix: common.getPrefix(browser),
                screenshotName: 'popover_right',
                selector: '#screenshot-popover-right',
                checkAccessibility: true
            })
            .call(done);
    });

});
<|endoftext|>


<commit_before>/*
 * jQuery plugin: fieldSelection - v0.1.0 - last change: 2006-12-16
 * (c) 2006 Alex Brem <alex@0xab.cd> - http://blog.0xab.cd
 */

(function() {
	var fieldSelection = {
		getSelection: function() {
			var e = this.jquery ? this[0] : this;
			return (
				/* mozilla / dom 3.0 */
				('selectionStart' in e && function() {
					var l = e.selectionEnd - e.selectionStart;
					return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) };
				}) ||
				/* exploder */
				(document.selection && function() {
					e.focus();
					var r = document.selection.createRange();
					if (r == null) {
						return { start: 0, end: e.value.length, length: 0 }
					}
					var re = e.createTextRange();
					var rc = re.duplicate();
					re.moveToBookmark(r.getBookmark());
					rc.setEndPoint('EndToStart', re);
					return { start: rc.text.length, end: rc.text.length + r.text.length, length: r.text.length, text: r.text };
				}) ||
				/* browser not supported */
				function() {
					return { start: 0, end: e.value.length, length: 0 };
				}
			)();
		},
		replaceSelection: function() {
			var e = this.jquery ? this[0] : this;
			var text = arguments[0] || '';
			return (
				/* mozilla / dom 3.0 */
				('selectionStart' in e && function() {
					e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length);
					return this;
				}) ||
				/* exploder */
				(document.selection && function() {
					e.focus();
					document.selection.createRange().text = text;
					return this;
				}) ||
				/* browser not supported */
				function() {
					e.value += text;
					return this;
				}
			)();
		}
	};
	jQuery.each(fieldSelection, function(i) { jQuery.fn[i] = this; });
})();

// -------------------------------------------------------------------
// markItUp!
// -------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// -------------------------------------------------------------------
// MarkDown tags example
// http://en.wikipedia.org/wiki/Markdown
// http://daringfireball.net/projects/markdown/
// -------------------------------------------------------------------
// Feel free to add more tags
// -------------------------------------------------------------------\

var focused;
var edit_content;
var getIdFromPath = function(path){
    var id;
    $.each(AVAILABLE_CONTENT_TYPES, function(i){
        if(this.path == '/'+path.replace('.','/')+'/'){
            id = i;
            return;
        }
    });
    return id;
}

MARKITUP_SETTINGS = {
    previewParserPath:    BASE_URL + 'nm/editor-preview/',
    previewParserVar:   "text",
	previewPosition: 'afterArea',
    onShiftEnter:		{keepDefault:false, openWith:'\n\n'},
    markupSet: [
        { name: gettext('Italic'), className: 'italic', key: 'I', openWith: '*', closeWith: '*' },
        { name: gettext('Bold'), className: 'bold', key: 'B', openWith: '**', closeWith: '**' },
        { separator: '---------------' },
        { name: gettext('Link'), className: 'url', key: 'L', openWith:'[', closeWith:']([![Url:!:http://]!] "[![Title]!]")', placeHolder: 'Text odkazu' },
        { separator: '---------------' },
        { name: gettext('Head 1'), className: 'h1', key:'1', placeHolder: 'Nadpis 1. úrovně', closeWith: function(markItUp) { return miu.markdownTitle(markItUp, '=') } },
        { name: gettext('Head 2'), className: 'h2', key:'2', placeHolder: 'Nadpis 2. úrovně', closeWith: function(markItUp) { return miu.markdownTitle(markItUp, '-') } },
        { name: gettext('Head 3'), className: 'h3', key:'3', placeHolder: 'Nadpis 3. úrovně', openWith: '### ' },
        { separator: '---------------' },
        { name: gettext('List unordered'), className: 'list-bullet', openWith: '- ' },
        { name: gettext('List ordered'), className: 'list-numeric', openWith:function(markItUp) {
            return markItUp.line+'. ';
        }},
        { separator: '---------------' },
        { name: gettext('Quote'), className: 'quote', openWith: '> ' },
        { separator: '---------------' },
        { name: gettext('Photo'), className: 'photo', call: function(){
            $('#rich-box').dialog('open');
            $('#id_box_obj_ct').val(getIdFromPath('photos.photo')).trigger('change');// 20 is value for photos.photo in the select box
            $('#lookup_id_box_obj_id').trigger('click');
        }},
        { name: gettext('Gallery'), className: 'gallery', call: function(){
            $('#rich-box').dialog('open');
            $('#id_box_obj_ct').val(getIdFromPath('galleries.gallery')).trigger('change');// 37 is value for galleries.gallery
        }},
        { name: gettext('Box'), className: 'box', call: function(){
            $('#rich-box').dialog('open');
			// Edit box
			if(focused){
				var range = focused.getSelection();
				var content = focused.val();
				if(content.match(/\{% box(.|\n)+\{% endbox %\}/g) && range.start != -1){
					var start = content.substring(0,range.start).lastIndexOf('{% box');
					var end = content.indexOf('{% endbox %}',range.end);
					if(start != -1 && end != -1 && content.substring(start,range.start).indexOf('{% endbox %}') == -1){
						var box = content.substring(start-6,end+12);
						edit_content = box;
						var id = box.replace(/^.+pk (\d+) (.|\n)+$/,'$1');
						var mode = box.replace(/^.+box (\w+) for(.|\n)+$/,'$1');
						var type = box.replace(/^.+for (\w+\.\w+) (.|\n)+$/,'$1');
						var params = box.replace(/^.+%\}\n?((.|\n)*)\{% endbox %\}$/,'$1');
						$('#id_box_obj_ct').val(getIdFromPath(type)).trigger('change');
						$('#id_box_obj_id').val(id);
						if(type == 'photos.photo'){
							if(box.indexOf('show_title:1') != -1){
								$('#id_box_photo_meta_show_title').attr('checked','checked');
							} else $('#id_box_photo_meta_show_title').removeAttr('checked');
							if(box.indexOf('show_author:1') != -1){
								$('#id_box_photo_meta_show_author').attr('checked','checked');
							} else $('#id_box_photo_meta_show_author').removeAttr('checked');
							if(box.indexOf('show_description:1') != -1){
								$('#id_box_photo_meta_show_description').attr('checked','checked');
							} else $('#id_box_photo_meta_show_description').removeAttr('checked');
							if(box.indexOf('show_detail:1') != -1){
								$('#id_box_photo_meta_show_detail').attr('checked','checked');
							} else $('#id_box_photo_meta_show_detail').removeAttr('checked');
							params = params.replace(/show_title:\d/,'').replace(/show_author:\d/,'').replace(/show_description:\d/,'').replace(/show_detail:\d/,'').replace(/\n{2,}/g,'\n').replace(/\s{2,}/g,' ');
							if(mode.indexOf('inline_velka') != -1){
								$('#id_box_photo_size').val('velka')
							} else if(mode.indexOf('inline_standard') != -1){
								$('#id_box_photo_size').val('standard')
							} else if(mode.indexOf('inline_mala') != -1){
								$('#id_box_photo_size').val('mala')
							}
							if(mode.indexOf('ctverec') != -1){
								$('#id_box_photo_format').val('ctverec')
							} else if(mode.indexOf('obdelnik_sirka') != -1){
								$('#id_box_photo_format').val('obdelnik_sirka')
							} else if(mode.indexOf('obdelnik_vyska') != -1){
								$('#id_box_photo_format').val('obdelnik_vyska')
							} else if(mode.indexOf('nudle_sirka') != -1){
								$('#id_box_photo_format').val('nudle_sirka')
							} else if(mode.indexOf('nudle_vyska') != -1){
								$('#id_box_photo_format').val('nudle_vyska')
							}
						}
						$('#id_box_obj_params').val(params);
					}
				}
			}
        }},
        { separator: '---------------' },
        { name: gettext('Preview'), call: 'preview', className: 'preview'}
    ]
}

$(function(){
    var getTypeFromPath = function(id){
        var path = AVAILABLE_CONTENT_TYPES[id].path;
        return path.substring(1,path.length - 1).replace('/','.');
    }
    if(!$('#rich-box').length){
        $('

').hide().appendTo('body');
        $('#rich-box').load(BASE_URL+'nm/editor-box/', function(){
            $('#id_box_obj_ct').bind('change', function(){
                if(getTypeFromPath($('#id_box_obj_ct').val()) == 'photos.photo'){
                    $('#rich-photo-format').show();
                } else {
                    $('#rich-photo-format').hide();
                }
            });
            $('#lookup_id_box_obj_id').bind('click', function(e){
                e.preventDefault();
                open_overlay(getTypeFromPath($('#id_box_obj_ct').val()), function(id){
                    $('#id_box_obj_id').val(id);
                });
            });
            $('#rich-object').bind('submit', function(e){
                e.preventDefault();
                if($('#id_box_obj_ct').val()){
                    var type = getTypeFromPath($('#id_box_obj_ct').val());
                    if(!!type){
                        var id = $('#id_box_obj_id').val() || '0';
                        var params = $('#id_box_obj_params').val().replace(/\n+/g, ' ');
                        // Add format and size info for photo
						var addon = '';
                        if(getTypeFromPath($('#id_box_obj_ct').val()) == 'photos.photo'){
                            addon = '_'+$('#id_box_photo_size').val()+'_'+$('#id_box_photo_format').val();
							// Add extra parameters
							$('.photo-meta input[type=checkbox]:checked','#rich-photo-format').each(function(){
								params += ((params) ? '\n' : '') + $(this).attr('name').replace('box_photo_meta_','') + ':1';
							});
                        }
                        // Insert code
						if(!edit_content){
	                        $.markItUp({
	                            openWith:'{% box inline'+addon+' for '+type+' with pk '+$('#id_box_obj_id').val()+' %}'+((params) ? '\n'+params+'\n' : '')+'{% endbox %}'
	                        });
						} else if(focused){
							var old = focused.val();
							focused.val(old.replace(edit_content,'{% box inline'+addon+' for '+type+' with pk '+$('#id_box_obj_id').val()+' %}'+((params) ? '\n'+params+'\n' : '')+'{% endbox %}'))
							edit_content = '';
						}
                        // Reset and close dialog
                        $('#rich-object').trigger('reset');
                        $('#rich-box').dialog('close');
                        $('#id_box_obj_ct').trigger('change');
                    }
                }
            });
        });
        $('#rich-box').dialog({
            modal: false,
            autoOpen: false,
            width: 420,
            height: 360
        });
    }
    $('.rich_text_area').markItUp(MARKITUP_SETTINGS).focus(function(){
		focused = $(this);
	});
});

// mIu nameSpace to avoid conflict.
miu = {
    markdownTitle: function(markItUp, char) {
        heading = '';
        n = $.trim(markItUp.selection||markItUp.placeHolder).length;
        for(i = 0; i < n; i++) {
            heading += char;
        }
        return '\n'+heading;
    }
}
<commit_msg>Rich textarea fix<commit_after>/*
 * jQuery plugin: fieldSelection - v0.1.0 - last change: 2006-12-16
 * (c) 2006 Alex Brem <alex@0xab.cd> - http://blog.0xab.cd
 */

(function() {
	var fieldSelection = {
		getSelection: function() {
			var e = this.jquery ? this[0] : this;
			return (
				/* mozilla / dom 3.0 */
				('selectionStart' in e && function() {
					var l = e.selectionEnd - e.selectionStart;
					return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) };
				}) ||
				/* exploder */
				(document.selection && function() {
					e.focus();
					var r = document.selection.createRange();
					if (r == null) {
						return { start: 0, end: e.value.length, length: 0 }
					}
					var re = e.createTextRange();
					var rc = re.duplicate();
					re.moveToBookmark(r.getBookmark());
					rc.setEndPoint('EndToStart', re);
					return { start: rc.text.length, end: rc.text.length + r.text.length, length: r.text.length, text: r.text };
				}) ||
				/* browser not supported */
				function() {
					return { start: 0, end: e.value.length, length: 0 };
				}
			)();
		},
		replaceSelection: function() {
			var e = this.jquery ? this[0] : this;
			var text = arguments[0] || '';
			return (
				/* mozilla / dom 3.0 */
				('selectionStart' in e && function() {
					e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length);
					return this;
				}) ||
				/* exploder */
				(document.selection && function() {
					e.focus();
					document.selection.createRange().text = text;
					return this;
				}) ||
				/* browser not supported */
				function() {
					e.value += text;
					return this;
				}
			)();
		}
	};
	jQuery.each(fieldSelection, function(i) { jQuery.fn[i] = this; });
})();

// -------------------------------------------------------------------
// markItUp!
// -------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// -------------------------------------------------------------------
// MarkDown tags example
// http://en.wikipedia.org/wiki/Markdown
// http://daringfireball.net/projects/markdown/
// -------------------------------------------------------------------
// Feel free to add more tags
// -------------------------------------------------------------------\

var focused;
var edit_content;
var getIdFromPath = function(path){
    var id;
    $.each(AVAILABLE_CONTENT_TYPES, function(i){
        if(this.path == '/'+path.replace('.','/')+'/'){
            id = i;
            return;
        }
    });
    return id;
}

MARKITUP_SETTINGS = {
    previewParserPath:    BASE_URL + 'nm/editor-preview/',
    previewParserVar:   "text",
	previewPosition: 'afterArea',
    onShiftEnter:		{keepDefault:false, openWith:'\n\n'},
    markupSet: [
        { name: gettext('Italic'), className: 'italic', key: 'I', openWith: '*', closeWith: '*' },
        { name: gettext('Bold'), className: 'bold', key: 'B', openWith: '**', closeWith: '**' },
        { separator: '---------------' },
        { name: gettext('Link'), className: 'url', key: 'L', openWith:'[', closeWith:']([![Url:!:http://]!] "[![Title]!]")', placeHolder: 'Text odkazu' },
        { separator: '---------------' },
        { name: gettext('Head 1'), className: 'h1', key:'1', placeHolder: 'Nadpis 1. úrovně', closeWith: function(markItUp) { return miu.markdownTitle(markItUp, '=') } },
        { name: gettext('Head 2'), className: 'h2', key:'2', placeHolder: 'Nadpis 2. úrovně', closeWith: function(markItUp) { return miu.markdownTitle(markItUp, '-') } },
        { name: gettext('Head 3'), className: 'h3', key:'3', placeHolder: 'Nadpis 3. úrovně', openWith: '### ' },
        { separator: '---------------' },
        { name: gettext('List unordered'), className: 'list-bullet', openWith: '- ' },
        { name: gettext('List ordered'), className: 'list-numeric', openWith:function(markItUp) {
            return markItUp.line+'. ';
        }},
        { separator: '---------------' },
        { name: gettext('Quote'), className: 'quote', openWith: '> ' },
        { separator: '---------------' },
        { name: gettext('Photo'), className: 'photo', call: function(){
            $('#rich-box').dialog('open');
            $('#id_box_obj_ct').val(getIdFromPath('photos.photo')).trigger('change');// 20 is value for photos.photo in the select box
            $('#lookup_id_box_obj_id').trigger('click');
        }},
        { name: gettext('Gallery'), className: 'gallery', call: function(){
            $('#rich-box').dialog('open');
            $('#id_box_obj_ct').val(getIdFromPath('galleries.gallery')).trigger('change');// 37 is value for galleries.gallery
        }},
        { name: gettext('Box'), className: 'box', call: function(){
            $('#rich-box').dialog('open');
			// Edit box
			if(focused){
				var range = focused.getSelection();
				var content = focused.val();
				if(content.match(/\{% box(.|\n)+\{% endbox %\}/g) && range.start != -1){
					var start = content.substring(0,range.start).lastIndexOf('{% box');
					var end = content.indexOf('{% endbox %}',range.end);
					if(start != -1 && end != -1 && content.substring(start,range.start).indexOf('{% endbox %}') == -1){
						var box = content.substring(start,end+12);
						edit_content = box;
						var id = box.replace(/^.+pk (\d+) (.|\n)+$/,'$1');
						var mode = box.replace(/^.+box (\w+) for(.|\n)+$/,'$1');
						var type = box.replace(/^.+for (\w+\.\w+) (.|\n)+$/,'$1');
						var params = box.replace(/^.+%\}\n?((.|\n)*)\{% endbox %\}$/,'$1');
						$('#id_box_obj_ct').val(getIdFromPath(type)).trigger('change');
						$('#id_box_obj_id').val(id);
						if(type == 'photos.photo'){
							if(box.indexOf('show_title:1') != -1){
								$('#id_box_photo_meta_show_title').attr('checked','checked');
							} else $('#id_box_photo_meta_show_title').removeAttr('checked');
							if(box.indexOf('show_author:1') != -1){
								$('#id_box_photo_meta_show_author').attr('checked','checked');
							} else $('#id_box_photo_meta_show_author').removeAttr('checked');
							if(box.indexOf('show_description:1') != -1){
								$('#id_box_photo_meta_show_description').attr('checked','checked');
							} else $('#id_box_photo_meta_show_description').removeAttr('checked');
							if(box.indexOf('show_detail:1') != -1){
								$('#id_box_photo_meta_show_detail').attr('checked','checked');
							} else $('#id_box_photo_meta_show_detail').removeAttr('checked');
							params = params.replace(/show_title:\d/,'').replace(/show_author:\d/,'').replace(/show_description:\d/,'').replace(/show_detail:\d/,'').replace(/\n{2,}/g,'\n').replace(/\s{2,}/g,' ');
							if(mode.indexOf('inline_velka') != -1){
								$('#id_box_photo_size').val('velka')
							} else if(mode.indexOf('inline_standard') != -1){
								$('#id_box_photo_size').val('standard')
							} else if(mode.indexOf('inline_mala') != -1){
								$('#id_box_photo_size').val('mala')
							}
							if(mode.indexOf('ctverec') != -1){
								$('#id_box_photo_format').val('ctverec')
							} else if(mode.indexOf('obdelnik_sirka') != -1){
								$('#id_box_photo_format').val('obdelnik_sirka')
							} else if(mode.indexOf('obdelnik_vyska') != -1){
								$('#id_box_photo_format').val('obdelnik_vyska')
							} else if(mode.indexOf('nudle_sirka') != -1){
								$('#id_box_photo_format').val('nudle_sirka')
							} else if(mode.indexOf('nudle_vyska') != -1){
								$('#id_box_photo_format').val('nudle_vyska')
							}
						}
						$('#id_box_obj_params').val(params);
					}
				}
			}
        }},
        { separator: '---------------' },
        { name: gettext('Preview'), call: 'preview', className: 'preview'}
    ]
}

$(function(){
    var getTypeFromPath = function(id){
        var path = AVAILABLE_CONTENT_TYPES[id].path;
        return path.substring(1,path.length - 1).replace('/','.');
    }
    if(!$('#rich-box').length){
        $('

').hide().appendTo('body');
        $('#rich-box').load(BASE_URL+'nm/editor-box/', function(){
            $('#id_box_obj_ct').bind('change', function(){
                if(getTypeFromPath($('#id_box_obj_ct').val()) == 'photos.photo'){
                    $('#rich-photo-format').show();
                } else {
                    $('#rich-photo-format').hide();
                }
            });
            $('#lookup_id_box_obj_id').bind('click', function(e){
                e.preventDefault();
                open_overlay(getTypeFromPath($('#id_box_obj_ct').val()), function(id){
                    $('#id_box_obj_id').val(id);
                });
            });
            $('#rich-object').bind('submit', function(e){
                e.preventDefault();
                if($('#id_box_obj_ct').val()){
                    var type = getTypeFromPath($('#id_box_obj_ct').val());
                    if(!!type){
                        var id = $('#id_box_obj_id').val() || '0';
                        var params = $('#id_box_obj_params').val().replace(/\n+/g, ' ');
                        // Add format and size info for photo
						var addon = '';
                        if(getTypeFromPath($('#id_box_obj_ct').val()) == 'photos.photo'){
                            addon = '_'+$('#id_box_photo_size').val()+'_'+$('#id_box_photo_format').val();
							// Add extra parameters
							$('.photo-meta input[type=checkbox]:checked','#rich-photo-format').each(function(){
								params += ((params) ? '\n' : '') + $(this).attr('name').replace('box_photo_meta_','') + ':1';
							});
                        }
                        // Insert code
						if(!edit_content){
	                        $.markItUp({
	                            openWith:'{% box inline'+addon+' for '+type+' with pk '+$('#id_box_obj_id').val()+' %}'+((params) ? '\n'+params+'\n' : '')+'{% endbox %}'
	                        });
						} else if(focused){
							var old = focused.val();
							focused.val(old.replace(edit_content,'{% box inline'+addon+' for '+type+' with pk '+$('#id_box_obj_id').val()+' %}'+((params) ? '\n'+params+'\n' : '')+'{% endbox %}'))
							edit_content = '';
						}
                        // Reset and close dialog
                        $('#rich-object').trigger('reset');
                        $('#rich-box').dialog('close');
                        $('#id_box_obj_ct').trigger('change');
                    }
                }
            });
        });
        $('#rich-box').dialog({
            modal: false,
            autoOpen: false,
            width: 420,
            height: 360
        });
    }
    $('.rich_text_area').markItUp(MARKITUP_SETTINGS).focus(function(){
		focused = $(this);
	});
});

// mIu nameSpace to avoid conflict.
miu = {
    markdownTitle: function(markItUp, char) {
        heading = '';
        n = $.trim(markItUp.selection||markItUp.placeHolder).length;
        for(i = 0; i < n; i++) {
            heading += char;
        }
        return '\n'+heading;
    }
}
<|endoftext|>


<commit_before>'use strict';

var __extends = function (d, b) {
    for (var p in b) {
        if (b.hasOwnProperty(p)) {
            d[p] = b[p];
        }
    }
    function __() {
        /*jshint validthis:true */
        this.constructor = d;
    }
    __.prototype = b.prototype;
    d.prototype = new __();
};

var cp = require('child_process');
var _ = require('lodash');
var XQLintWorker = null;

/*jshint -W079 */
var Range = require('atom').Range;
var linterPath = atom.packages.getLoadedPackage('linter').path;
var Linter = require(linterPath + '/lib/linter');

module.exports = (function(_super) {

    XQLintWorker = cp.fork(__dirname + '/worker.js');
    process.on('exit', function() {
        XQLintWorker.kill();
    });

    function JSONiqLinter(editor){
        _super.call(this, editor);
    }
    __extends(JSONiqLinter, _super);
    JSONiqLinter.syntax = ['source.jq', 'source.xq'];
    JSONiqLinter.prototype.linterName = 'xqlint';

    JSONiqLinter.prototype.lintFile = function(filePath, callback){
        //var self = this;
        var editor = atom.workspace.getActiveTextEditor();
        var cb = function (markers) {
            XQLintWorker.removeListener('message', cb);
            callback(_.chain(markers).map(function(marker){
                return {
                    line: marker.pos.sl + 1,
                    col: marker.pos.sc + 1,
                    level: marker.level,
                    message: marker.message,
                    linter: 'xqlint',
                    range: new Range(
                        [marker.pos.sl, marker.pos.sc],
                        [marker.pos.el, marker.pos.ec]
                    )
                };
            }).value());
        };
        XQLintWorker.on('message', cb);

        XQLintWorker.send({
            method: 'run',
            text: editor.getText(),
            fileName: editor.getPath(),
            options: {},
            config: {}
        });
    };

    return JSONiqLinter;
})(Linter);<commit_msg>:bug: fixes #10<commit_after>'use strict';

var __extends = function (d, b) {
    for (var p in b) {
        if (b.hasOwnProperty(p)) {
            d[p] = b[p];
        }
    }
    function __() {
        /*jshint validthis:true */
        this.constructor = d;
    }
    __.prototype = b.prototype;
    d.prototype = new __();
};

var cp = require('child_process');
var _ = require('lodash');
var XQLintWorker = null;

/*jshint -W079 */
var Range = require('atom').Range;
var linterPath = atom.packages.getLoadedPackage('linter').path;
var Linter = require(linterPath + '/lib/linter');

module.exports = (function(_super) {

    XQLintWorker = cp.fork(__dirname + '/worker.js');
    process.on('exit', function() {
        XQLintWorker.kill();
    });

    function JSONiqLinter(editor){
        _super.call(this, editor);
    }
    __extends(JSONiqLinter, _super);
    JSONiqLinter.syntax = ['source.jq', 'source.xq'];
    JSONiqLinter.prototype.linterName = 'xqlint';

    JSONiqLinter.prototype.lintFile = function(filePath, callback){
        //var self = this;
        var editor = atom.workspace.getActiveTextEditor();
        if(!editor) {
            return;
        }
        var cb = function (markers) {
            XQLintWorker.removeListener('message', cb);
            callback(_.chain(markers).map(function(marker){
                return {
                    line: marker.pos.sl + 1,
                    col: marker.pos.sc + 1,
                    level: marker.level,
                    message: marker.message,
                    linter: 'xqlint',
                    range: new Range(
                        [marker.pos.sl, marker.pos.sc],
                        [marker.pos.el, marker.pos.ec]
                    )
                };
            }).value());
        };
        XQLintWorker.on('message', cb);

        XQLintWorker.send({
            method: 'run',
            text: editor.getText(),
            fileName: editor.getPath(),
            options: {},
            config: {}
        });
    };

    return JSONiqLinter;
})(Linter);<|endoftext|>


<commit_before>ZBase.registerView((function() {

  var kBasePath = "/a/logviewer/";

  var query_mgr;
  var logfiles;
  var default_end_time = (new Date()).getTime() * 1000;
  var next_page_time;
  var pagination_history = [];
  var datepicker;

  var init = function(params) {
    $.showLoader();
    query_mgr = EventSourceHandler();

    $.httpGet("/api/v1/logfiles", function(r) {
      render();

      if (r.status == 200) {
        logfiles = JSON.parse(r.response).logfile_definitions;
        updateQuery(params.path);
      } else {
        renderError("Server Error");
      }

      $.hideLoader();
    });
  };

  var destroy = function() {
    query_mgr.closeAll();
  };

  var updateQuery = function(url) {
    setQueryParams(url);
    executeQuery();
  }

  var executeQuery = function() {
    showLoadingBar(0);

    var params = getQueryParams();
    params.limit = 100;

    var url = "/api/v1/logfiles/scan?" + $.buildQueryString(params);
    var query = query_mgr.get("logfile_query", url);

    query.addEventListener("message", function(e) {
      var data = JSON.parse(e.data);
      var result = data.result;

      if (result.length > 0) {
        showLoadingBar(data.rows_scanned);
        renderResult(result);
      }

      if (data.status == "finished") {
        query_mgr.close("logfile_query");
        hideLoadingBar();

        next_page_time = result[result.length - 1].time;
      }
    });

    query.addEventListener("error", function(e) {
      query_mgr.close("logfile_query");
      hideLoadingBar();
    });
  };

  var getQueryParams = function() {
    var params = {};

    // param: logfile
    params.logfile = $(".zbase_logviewer z-dropdown.logfile_control").getValue();

    // param: time
    var time_control = $(".zbase_logviewer .time_control");
    var time = parseInt(time_control.getAttribute("data-timestamp"), 10) * 1000;
    if (time != default_end_time) {
      params.time = time;
    }

    // param: filter
    params.filter_type = $(".zbase_logviewer .filter_type_control").getValue();
    params.filter = $(".zbase_logviewer .filter_control").getValue();

    // param: columns
    params.columns = $(".zbase_logviewer .columns_control").getValue();

    return params;
  };

  var setQueryParams = function(url) {
    // param: logfile
    var logfile = UrlUtil.getPath(url).substr(kBasePath.length);
    setLogfileParam(logfile);
    setLogfileName(logfile);

    // param: end time
    var end_time = UrlUtil.getParamValue(url, "time");
    setTimeParam(end_time);

    // param: filter type
    var filter_type = UrlUtil.getParamValue(url, "filter_type");
    var filter = UrlUtil.getParamValue(url, "filter");
    setFilterParam(filter_type, filter);

    // param: columns
    var columns = UrlUtil.getParamValue(url, "columns");
    setColumnsParam(logfile, columns);

    // param: raw
    var raw = UrlUtil.getParamValue(url, "raw");

    //pagination
    setPagination();

    // "showing historic data" hint
    var is_historical = end_time && end_time != default_end_time;
    setHistoricalDataHint(is_historical);
  };

  var setLogfileParam = function(logfile) {
    var items = [];
    logfiles.forEach(function(logfile) {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = logfile.name;
      item.setAttribute("data-value", logfile.name);
      items.push(item);
    });

    var dropdown = $(".zbase_logviewer z-dropdown.logfile_control");
    dropdown.setDropdownItems(items);
    dropdown.setValue([logfile]);
  };

  var setTimeParam = function(end_time) {
    if (typeof end_time == "string") {
      end_time = parseInt(end_time, 10);
    }

    if (!end_time) {
      end_time = default_end_time;
    }

    var time_control = $(".zbase_logviewer .time_control");
    datepicker.setTime(Math.floor(end_time));
  };

  var setFilterParam = function(filter_type, filter) {
    if (!filter_type) {
      filter_type = "sql";
    }

    $(".zbase_logviewer .filter_type_control").setValue([filter_type]);
    $(".zbase_logviewer .filter_control").setValue(filter);
  }

  var setColumnsParam = function(logfile, columns_str) {
    if (!columns_str) {
      columns_str = "__raw__";
    }

    var columns = listLogfileColumns(logfile);
    var items = [];

    {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = "<z-checkbox></z-checkbox> " + "Raw Logline";
      item.setAttribute("data-value", "__raw__");
      items.push(item);
    }

    columns.forEach(function(column) {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = "<z-checkbox></z-checkbox> " + column;
      item.setAttribute("data-value", column);
      items.push(item);
    });

    var dropdown = $(".zbase_logviewer .columns_control");
    dropdown.setDropdownItems(items);
    dropdown.setValue(columns_str.split(","));
  }

  var setLogfileName = function(logfile) {
    $(".zbase_logviewer .logfile_name_crumb").innerHTML = logfile;
  }

  var setPagination = function() {
    var prev_elem = $(".zbase_logviewer .z-pager .prev");

    if (pagination_history.length == 0) {
      prev_elem.setAttribute("data-disabled", true);
    } else {
      prev_elem.removeAttribute("data-disabled");
    }
  }

  var setHistoricalDataHint = function(is_historic) {
    var elem = $(".zbase_logviewer .go_to_recent");
    if (is_historic) {
      elem.classList.remove("hidden");
    } else {
      elem.classList.add("hidden");
    }
  }

  var getQueryURL = function(params) {
    var url = kBasePath + params.logfile;
    delete params.logfile;
    url += "?" + $.buildQueryString(params);
    return url;
  }

  var submitControls = function() {
    next_page_time = null;
    pagination_history = [];

    var url = getQueryURL(getQueryParams());
    $.navigateTo(url);
  }

  var goToMostRecentPage = function() {
    next_page_time = null;
    pagination_history = [];
    default_end_time = (new Date()).getTime() * 1000;
    setTimeParam(default_end_time);

    var params = getQueryParams();
    var url = getQueryURL(params);

    $.navigateTo(url);
  }

  var goToNextPage = function() {
    if (!next_page_time) {
      return;
    }

    var params = getQueryParams();
    params.time = next_page_time;
    var url = getQueryURL(params);

    pagination_history.push(url);
    $.navigateTo(url);
  };

  var goToPreviousPage = function() {
    var url = pagination_history.pop();

    if (url) {
      $.navigateTo(url);
    }
  };

  var findLogfileDefinition = function(logfile_name) {
    for (var i = 0; i < logfiles.length; ++i) {
      if (logfiles[i].name == logfile_name) {
        return logfiles[i];
      }
    }

    return null;
  }

  var listLogfileColumns = function(logfile_name) {
    var logfile_def = findLogfileDefinition(logfile_name);
    if (!logfile_def) {
      $.fatalError();
      return null;
    }

    var columns = [];
    for (var i = 0; i < logfile_def.source_fields.length; ++i) {
      columns.push(logfile_def.source_fields[i].name);
    }

    for (var i = 0; i < logfile_def.row_fields.length; ++i) {
      columns.push(logfile_def.row_fields[i].name);
    }

    return columns;
  }

  var render = function() {
    var page = $.getTemplate("views/logviewer", "zbase_logviewer_main_tpl");
    datepicker = DateTimePicker($(".time_control", page));

    $(".logfile_control", page).addEventListener("change", submitControls);
    $(".filter_type_control", page).addEventListener("change", submitControls);
    $(".columns_control", page).addEventListener("change", submitControls);
    $(".time_control", page).addEventListener("change", submitControls);
    $(".z-pager .next", page).addEventListener("click", goToNextPage);
    $(".z-pager .prev", page).addEventListener("click", goToPreviousPage);
    $(".go_to_recent a", page).addEventListener("click", goToMostRecentPage);
    $(".filter_control", page).addEventListener("change", submitControls);
    $(".time_control", page).addEventListener(
      "z-datetimepicker-change", submitControls);
    $(".filter_control", page).addEventListener("keyup", function(e) {
      if (e.keyCode == 13) submitControls();
    });

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderResult = function(result) {
    var logtable = LogfileTable(result);
    logtable.render($(".zbase_logviewer .table_container"));
  }

  var renderError = function(error) {
    var error_msg = $.getTemplate(
        "views/logviewer",
        "zbase_logviewer_error_msg_tpl");

    $(".error_text", error_msg).innerHTML = error;
    $.replaceContent($(".zbase_logviewer .table_container"), error_msg);
  }

  var showLoadingBar = function(num_rows) {
    $(".zbase_logviewer").classList.add("loading");
    var elem = $(".zbase_logviewer .loglines_loading_bar");
    elem.classList.remove("hidden");
    $(".loading_bar_info", elem).style.visibility =
        (num_rows > 0 ? "visible" : "hidden");
    $(".num_rows", elem).innerHTML = num_rows;
  };

  var hideLoadingBar = function() {
    $(".zbase_logviewer").classList.remove("loading");
    $(".zbase_logviewer .loglines_loading_bar").classList.add("hidden");
  };

  return {
    name: "logviewer",
    loadView: init,
    unloadView: destroy,
    handleNavigationChange: updateQuery
  };

})());
<commit_msg>logviewer: set time<commit_after>ZBase.registerView((function() {

  var kBasePath = "/a/logviewer/";

  var query_mgr;
  var logfiles;
  var default_end_time = (new Date()).getTime() * 1000;
  var next_page_time;
  var pagination_history = [];
  var datepicker;

  var init = function(params) {
    $.showLoader();
    query_mgr = EventSourceHandler();

    $.httpGet("/api/v1/logfiles", function(r) {
      render();

      if (r.status == 200) {
        logfiles = JSON.parse(r.response).logfile_definitions;
        updateQuery(params.path);
      } else {
        renderError("Server Error");
      }

      $.hideLoader();
    });
  };

  var destroy = function() {
    query_mgr.closeAll();
  };

  var updateQuery = function(url) {
    setQueryParams(url);
    executeQuery();
  }

  var executeQuery = function() {
    showLoadingBar(0);

    var params = getQueryParams();
    params.limit = 100;

    var url = "/api/v1/logfiles/scan?" + $.buildQueryString(params);
    var query = query_mgr.get("logfile_query", url);

    query.addEventListener("message", function(e) {
      var data = JSON.parse(e.data);
      var result = data.result;

      if (result.length > 0) {
        showLoadingBar(data.rows_scanned);
        renderResult(result);
      }

      if (data.status == "finished") {
        query_mgr.close("logfile_query");
        hideLoadingBar();

        next_page_time = result[result.length - 1].time;
      }
    });

    query.addEventListener("error", function(e) {
      query_mgr.close("logfile_query");
      hideLoadingBar();
    });
  };

  var getQueryParams = function() {
    var params = {};

    // param: logfile
    params.logfile = $(".zbase_logviewer z-dropdown.logfile_control").getValue();

    // param: time
    var time_control = $(".zbase_logviewer .time_control");
    var time = parseInt(time_control.getAttribute("data-timestamp"), 10) * 1000;
    if (time != default_end_time) {
      params.time = time;
    }

    // param: filter
    params.filter_type = $(".zbase_logviewer .filter_type_control").getValue();
    params.filter = $(".zbase_logviewer .filter_control").getValue();

    // param: columns
    params.columns = $(".zbase_logviewer .columns_control").getValue();

    return params;
  };

  var setQueryParams = function(url) {
    // param: logfile
    var logfile = UrlUtil.getPath(url).substr(kBasePath.length);
    setLogfileParam(logfile);
    setLogfileName(logfile);

    // param: end time
    var end_time = UrlUtil.getParamValue(url, "time");
    setTimeParam(end_time);

    // param: filter type
    var filter_type = UrlUtil.getParamValue(url, "filter_type");
    var filter = UrlUtil.getParamValue(url, "filter");
    setFilterParam(filter_type, filter);

    // param: columns
    var columns = UrlUtil.getParamValue(url, "columns");
    setColumnsParam(logfile, columns);

    // param: raw
    var raw = UrlUtil.getParamValue(url, "raw");

    //pagination
    setPagination();

    // "showing historic data" hint
    var is_historical = end_time && end_time != default_end_time;
    setHistoricalDataHint(is_historical);
  };

  var setLogfileParam = function(logfile) {
    var items = [];
    logfiles.forEach(function(logfile) {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = logfile.name;
      item.setAttribute("data-value", logfile.name);
      items.push(item);
    });

    var dropdown = $(".zbase_logviewer z-dropdown.logfile_control");
    dropdown.setDropdownItems(items);
    dropdown.setValue([logfile]);
  };

  var setTimeParam = function(end_time) {
    if (typeof end_time == "string") {
      end_time = parseInt(end_time, 10);
    }

    if (!end_time) {
      end_time = default_end_time;
    }

    var time_control = $(".zbase_logviewer .time_control");
    datepicker.setTime(Math.floor(end_time / 1000));
  };

  var setFilterParam = function(filter_type, filter) {
    if (!filter_type) {
      filter_type = "sql";
    }

    $(".zbase_logviewer .filter_type_control").setValue([filter_type]);
    $(".zbase_logviewer .filter_control").setValue(filter);
  }

  var setColumnsParam = function(logfile, columns_str) {
    if (!columns_str) {
      columns_str = "__raw__";
    }

    var columns = listLogfileColumns(logfile);
    var items = [];

    {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = "<z-checkbox></z-checkbox> " + "Raw Logline";
      item.setAttribute("data-value", "__raw__");
      items.push(item);
    }

    columns.forEach(function(column) {
      var item = document.createElement("z-dropdown-item");
      item.innerHTML = "<z-checkbox></z-checkbox> " + column;
      item.setAttribute("data-value", column);
      items.push(item);
    });

    var dropdown = $(".zbase_logviewer .columns_control");
    dropdown.setDropdownItems(items);
    dropdown.setValue(columns_str.split(","));
  }

  var setLogfileName = function(logfile) {
    $(".zbase_logviewer .logfile_name_crumb").innerHTML = logfile;
  }

  var setPagination = function() {
    var prev_elem = $(".zbase_logviewer .z-pager .prev");

    if (pagination_history.length == 0) {
      prev_elem.setAttribute("data-disabled", true);
    } else {
      prev_elem.removeAttribute("data-disabled");
    }
  }

  var setHistoricalDataHint = function(is_historic) {
    var elem = $(".zbase_logviewer .go_to_recent");
    if (is_historic) {
      elem.classList.remove("hidden");
    } else {
      elem.classList.add("hidden");
    }
  }

  var getQueryURL = function(params) {
    var url = kBasePath + params.logfile;
    delete params.logfile;
    url += "?" + $.buildQueryString(params);
    return url;
  }

  var submitControls = function() {
    next_page_time = null;
    pagination_history = [];

    var url = getQueryURL(getQueryParams());
    $.navigateTo(url);
  }

  var goToMostRecentPage = function() {
    next_page_time = null;
    pagination_history = [];
    default_end_time = (new Date()).getTime() * 1000;
    setTimeParam(default_end_time);

    var params = getQueryParams();
    var url = getQueryURL(params);

    $.navigateTo(url);
  }

  var goToNextPage = function() {
    if (!next_page_time) {
      return;
    }

    var params = getQueryParams();
    params.time = next_page_time;
    var url = getQueryURL(params);

    pagination_history.push(url);
    $.navigateTo(url);
  };

  var goToPreviousPage = function() {
    var url = pagination_history.pop();

    if (url) {
      $.navigateTo(url);
    }
  };

  var findLogfileDefinition = function(logfile_name) {
    for (var i = 0; i < logfiles.length; ++i) {
      if (logfiles[i].name == logfile_name) {
        return logfiles[i];
      }
    }

    return null;
  }

  var listLogfileColumns = function(logfile_name) {
    var logfile_def = findLogfileDefinition(logfile_name);
    if (!logfile_def) {
      $.fatalError();
      return null;
    }

    var columns = [];
    for (var i = 0; i < logfile_def.source_fields.length; ++i) {
      columns.push(logfile_def.source_fields[i].name);
    }

    for (var i = 0; i < logfile_def.row_fields.length; ++i) {
      columns.push(logfile_def.row_fields[i].name);
    }

    return columns;
  }

  var render = function() {
    var page = $.getTemplate("views/logviewer", "zbase_logviewer_main_tpl");
    datepicker = DateTimePicker($(".time_control", page));

    $(".logfile_control", page).addEventListener("change", submitControls);
    $(".filter_type_control", page).addEventListener("change", submitControls);
    $(".columns_control", page).addEventListener("change", submitControls);
    $(".time_control", page).addEventListener("change", submitControls);
    $(".z-pager .next", page).addEventListener("click", goToNextPage);
    $(".z-pager .prev", page).addEventListener("click", goToPreviousPage);
    $(".go_to_recent a", page).addEventListener("click", goToMostRecentPage);
    $(".filter_control", page).addEventListener("change", submitControls);
    $(".time_control", page).addEventListener(
      "z-datetimepicker-change", submitControls);
    $(".filter_control", page).addEventListener("keyup", function(e) {
      if (e.keyCode == 13) submitControls();
    });

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderResult = function(result) {
    var logtable = LogfileTable(result);
    logtable.render($(".zbase_logviewer .table_container"));
  }

  var renderError = function(error) {
    var error_msg = $.getTemplate(
        "views/logviewer",
        "zbase_logviewer_error_msg_tpl");

    $(".error_text", error_msg).innerHTML = error;
    $.replaceContent($(".zbase_logviewer .table_container"), error_msg);
  }

  var showLoadingBar = function(num_rows) {
    $(".zbase_logviewer").classList.add("loading");
    var elem = $(".zbase_logviewer .loglines_loading_bar");
    elem.classList.remove("hidden");
    $(".loading_bar_info", elem).style.visibility =
        (num_rows > 0 ? "visible" : "hidden");
    $(".num_rows", elem).innerHTML = num_rows;
  };

  var hideLoadingBar = function() {
    $(".zbase_logviewer").classList.remove("loading");
    $(".zbase_logviewer .loglines_loading_bar").classList.add("hidden");
  };

  return {
    name: "logviewer",
    loadView: init,
    unloadView: destroy,
    handleNavigationChange: updateQuery
  };

})());
<|endoftext|>


<commit_before>"use strict"

const createDataReader = require('../createDataReader')

module.exports = (args) => {
  const reader = createDataReader(args)

  const loadAnim = () => {
    const start = reader.readWord()
    const finish = reader.readWord()
    const delay = reader.readWord()
    const mode = reader.readWord()

    return {
      start,
      finish,
      delay,
      mode,
    }
  }

  const load = () => {
    const version = reader.readWord()
    const palette = reader.readByteArray(256 * 3)
    const numtiles = reader.readWord()
    const vsp0 = reader.readByteArray(numtiles * 16 * 16)

    let va0 = []
    for (let i = 0; i < 100; i++) {
      va0.push(loadAnim())
    }

    return {
      version,
      palette,
      numtiles,
      vsp0,
      va0,
    }
  }

  return {
    load
  }
}<commit_msg>declarative verge1 vsp loader<commit_after>"use strict"

const createDataReader = require('../createDataReader')
const {readFormat, T} = require('../readFormat')

module.exports = (args) => {
  const reader = createDataReader(args)

  const V1_VSPANIM = {
    start: T.u16,
    finish: T.u16,
    delay: T.u16,
    mode: T.u16,
  }

  const V1_VSP = {
    version: T.u16,
    palette: T.list(T.u8, 256 * 3),
    numtiles: T.u16,
    vsp0: T.list(T.u8, ({record}) => record.numtiles * 16 * 16),
    va0: T.list(V1_VSPANIM, 100),
  }

  return {
    load: () => readFormat({format: V1_VSP, reader})
  }
}<|endoftext|>