<commit_before>import { find, findOne, ready, on, fire } from 'domassist';
import scrollTriggers from 'scroll-triggers';
import smoothScroll from 'smooth-scroller';

function init(el) {
  if (!el) {
    el = find('[data-toc]');
    el.forEach(e => init(e));
    return;
  }

  if (!el) {
    return;
  }

  const container = el.dataset.tocContainer ?
    findOne(el.dataset.tocContainer) | document.body : document.body;
  const selectors = el.dataset.toc.split(',').map(s => s.trim());
  const tocItems = [];
  const offset = el.dataset.tocOffset ? parseInt(el.dataset.tocOffset, 10) : 1;
  let i = 1;

  // Building dict
  selectors.forEach(selector => {
    const items = find(selector, container);

    items.forEach(item => {
      // Keep the id if already there
      const index = item.id || `toc-${i++}`;
      const text = item.dataset.tocTitle ?
        item.dataset.tocTitle.trim() : item.textContent.trim();
      const sanitizedClassName = selector.replace(/((:+[\w-\d]*)|[^A-z0-9-\s])/g, '').replace(/\s{2,}/g, '').trim();
      const className = `toc-${sanitizedClassName}`;

      // Set it if none
      if (item.id !== index) {
        item.id = index;
      }

      tocItems.push({ index, text, className });
    });
  });

  let html = '
';
  const triggerOptions = [];

  // Building markup
  tocItems.forEach((item, j) => {
    const nextEl = tocItems[j + 1];
    const options = {
      el: `.toc-li-${j}`,
      start: `#${item.index}`,
      position: 'top',
      positionEnd: 'top',
      className: 'toc-visible'
    };
    html += `\n<li class="toc-li-${j} ${item.className}"><a href="#${item.index}">${item.text}</a></li>`;

    if (nextEl) {
      options.end = `#${nextEl.index}`;
    }

    triggerOptions.push(options);
  });

  html += '
';

  el.innerHTML = html;
  const tocs = find('li', el);
  const anchors = find('a', el);

  // Setting up scroll triggers and smooth scroll
  scrollTriggers(triggerOptions);
  smoothScroll(anchors, offset);

  // Pause scroll triggers while smoothscrolling
  on(anchors, 'smoothscroll:start', () => {
    fire(tocs, 'scrolltriggers:pause');
  });

  on(anchors, 'smoothscroll:end', () => {
    fire(tocs, 'scrolltriggers:resume');
  });
}

export default init;

ready(init);
<commit_msg>Update sanitize class regexp<commit_after>import { find, findOne, ready, on, fire } from 'domassist';
import scrollTriggers from 'scroll-triggers';
import smoothScroll from 'smooth-scroller';

function init(el) {
  if (!el) {
    el = find('[data-toc]');
    el.forEach(e => init(e));
    return;
  }

  if (!el) {
    return;
  }

  const container = el.dataset.tocContainer ?
    findOne(el.dataset.tocContainer) | document.body : document.body;
  const selectors = el.dataset.toc.split(',').map(s => s.trim());
  const tocItems = [];
  const offset = el.dataset.tocOffset ? parseInt(el.dataset.tocOffset, 10) : 1;
  let i = 1;

  // Building dict
  selectors.forEach(selector => {
    const items = find(selector, container);

    items.forEach(item => {
      // Keep the id if already there
      const index = item.id || `toc-${i++}`;
      const text = item.dataset.tocTitle ?
      item.dataset.tocTitle.trim() : item.textContent.trim();
      const sanitizedClassName = selector.replace(/((:+[\w-\d]*)|[^A-z0-9-\s])/g, ' ').replace(/\s{2,}/g, ' ').trim();
      const className = `toc-${sanitizedClassName}`;

      // Set it if none
      if (item.id !== index) {
        item.id = index;
      }

      tocItems.push({ index, text, className });
    });
  });

  let html = '
';
  const triggerOptions = [];

  // Building markup
  tocItems.forEach((item, j) => {
    const nextEl = tocItems[j + 1];
    const options = {
      el: `.toc-li-${j}`,
      start: `#${item.index}`,
      position: 'top',
      positionEnd: 'top',
      className: 'toc-visible'
    };
    html += `\n<li class="toc-li-${j} ${item.className}"><a href="#${item.index}">${item.text}</a></li>`;

    if (nextEl) {
      options.end = `#${nextEl.index}`;
    }

    triggerOptions.push(options);
  });

  html += '
';

  el.innerHTML = html;
  const tocs = find('li', el);
  const anchors = find('a', el);

  // Setting up scroll triggers and smooth scroll
  scrollTriggers(triggerOptions);
  smoothScroll(anchors, offset);

  // Pause scroll triggers while smoothscrolling
  on(anchors, 'smoothscroll:start', () => {
    fire(tocs, 'scrolltriggers:pause');
  });

  on(anchors, 'smoothscroll:end', () => {
    fire(tocs, 'scrolltriggers:resume');
  });
}

export default init;

ready(init);
<|endoftext|>


<commit_before>'use strict';

// Define some constants
const electron   = require('electron');
const ipc        = require('electron').ipcMain;
const app        = electron.app;
const path       = require('path');
const fs         = require('fs');
const appMenuEn  = require('./menu_en');
const appMenuDe  = require('./menu_de');
const storage    = require('./storage');
const acURL      = storage.get('acURL') || 'https://my.activecollab.com/';

// Require download component
require('electron-dl')();

let locale;
let mainWindow;
let isQuitting = false;

// Function for creating the main window
function createMainWindow()
{
	// Open window with default size or last window state
	const lastWindowState = storage.get('lastWindowState') || {width: 1024, height: 768};

	// Check if window was opened fullscreen
	const isFullscreen = storage.get('isFullscreen') || false;

	// Create new browser window
	const win = new electron.BrowserWindow(
	{
		title: app.getName(),
		show: false,
		x: lastWindowState.x,
		y: lastWindowState.y,
		width: lastWindowState.width,
		height: lastWindowState.height,
		icon: process.platform === 'linux' && path.join(__dirname, 'media', 'Icon.png'),
		minWidth: 800,
		minHeight: 600,
		titleBarStyle: 'default',
		webPreferences:
		{
			nodeIntegration: false,
			preload: path.join(__dirname, 'browser.js'),
			webSecurity: true,
			plugins: false
		}

	});

	// Window close callback
	win.on('close', function(e)
	{
		if (process.platform == 'darwin' && !isQuitting)
		{
			e.preventDefault();
    		win.hide();

  		}
		else
		{
			app.quit();

		}

	});

	win.loadURL(acURL);
	win.setFullScreen(isFullscreen);

	return win;

}

// App ready callback
app.on('ready', function()
{
	locale = app.getLocale();
	mainWindow = createMainWindow();

	const page = mainWindow.webContents;

	// Set application menu based on locale
	switch (locale)
	{
		case 'de': // German
			electron.Menu.setApplicationMenu(appMenuDe);
			break;

		default: // Defaults to English
			electron.Menu.setApplicationMenu(appMenuEn);

	}

	// Document ready callback
	page.on('dom-ready', function()
	{
		mainWindow.show();

	});

	// New window callback
	page.on('new-window', function(e, url)
	{
		if (/(.*)\.activecollab\.com/.test(url))
		{
			mainWindow.loadURL(url);
		}
		else
		{
			e.preventDefault();
			electron.shell.openExternal(url);
		}
	});

});

// App activate callback
app.on('activate', function()
{
	mainWindow.show();

});

// App before quit callback
app.on('before-quit', function()
{
	isQuitting = true;

	if (!mainWindow.isFullScreen())
	{
		storage.set('lastWindowState', mainWindow.getBounds());
		storage.set('isFullscreen', false);

	}
	else
	{
		storage.set('isFullscreen', true);

	}

});
<commit_msg>Fixed Active Collab account selection links (this time for real)<commit_after>'use strict';

// Define some constants
const electron   = require('electron');
const ipc        = require('electron').ipcMain;
const app        = electron.app;
const path       = require('path');
const fs         = require('fs');
const appMenuEn  = require('./menu_en');
const appMenuDe  = require('./menu_de');
const storage    = require('./storage');
const acURL      = storage.get('acURL') || 'https://my.activecollab.com/';

// Require download component
require('electron-dl')();

let locale;
let mainWindow;
let isQuitting = false;

// Function for creating the main window
function createMainWindow()
{
	// Open window with default size or last window state
	const lastWindowState = storage.get('lastWindowState') || {width: 1024, height: 768};

	// Check if window was opened fullscreen
	const isFullscreen = storage.get('isFullscreen') || false;

	// Create new browser window
	const win = new electron.BrowserWindow(
	{
		title: app.getName(),
		show: false,
		x: lastWindowState.x,
		y: lastWindowState.y,
		width: lastWindowState.width,
		height: lastWindowState.height,
		icon: process.platform === 'linux' && path.join(__dirname, 'media', 'Icon.png'),
		minWidth: 800,
		minHeight: 600,
		titleBarStyle: 'default',
		webPreferences:
		{
			nodeIntegration: false,
			preload: path.join(__dirname, 'browser.js'),
			webSecurity: true,
			plugins: false
		}

	});

	// Window close callback
	win.on('close', function(e)
	{
		if (process.platform == 'darwin' && !isQuitting)
		{
			e.preventDefault();
    		win.hide();

  		}
		else
		{
			app.quit();

		}

	});

	win.loadURL(acURL);
	win.setFullScreen(isFullscreen);

	return win;

}

// App ready callback
app.on('ready', function()
{
	locale = app.getLocale();
	mainWindow = createMainWindow();

	const page = mainWindow.webContents;

	// Set application menu based on locale
	switch (locale)
	{
		case 'de': // German
			electron.Menu.setApplicationMenu(appMenuDe);
			break;

		default: // Defaults to English
			electron.Menu.setApplicationMenu(appMenuEn);

	}

	// Document ready callback
	page.on('dom-ready', function()
	{
		mainWindow.show();

	});

	// New window callback
	page.on('new-window', function(e, url)
	{
		e.preventDefault();

		if (/my\.activecollab\.com/.test(url))
		{
			// Internal links
			mainWindow.loadURL(url);

		}
		else
		{
			// External link
			electron.shell.openExternal(url);

		}

	});

});

// App activate callback
app.on('activate', function()
{
	mainWindow.show();

});

// App before quit callback
app.on('before-quit', function()
{
	isQuitting = true;

	if (!mainWindow.isFullScreen())
	{
		storage.set('lastWindowState', mainWindow.getBounds());
		storage.set('isFullscreen', false);

	}
	else
	{
		storage.set('isFullscreen', true);

	}

});
<|endoftext|>


<commit_before>var ui = (function () {

var exports = {};

var actively_scrolling = false;

exports.have_scrolled_away_from_top = true;

exports.actively_scrolling = function () {
    return actively_scrolling;
};

// What, if anything, obscures the home tab?

exports.replace_emoji_with_text = function (element) {
    element.find(".emoji").replaceWith(function () {
        return $(this).attr("alt");
    });
};

function update_message_in_all_views(message_id, callback) {
    _.each([message_list.all, home_msg_list, message_list.narrowed], function (list) {
        if (list === undefined) {
            return;
        }
        var row = list.get_row(message_id);
        if (row === undefined) {
            // The row may not exist, e.g. if you do an action on a message in
            // a narrowed view
            return;
        }
        callback(row);
    });
}

exports.find_message = function (message_id) {
    // Try to find the message object. It might be in the narrow list
    // (if it was loaded when narrowed), or only in the message_list.all
    // (if received from the server while in a different narrow)
    var message;
    _.each([message_list.all, home_msg_list, message_list.narrowed], function (msg_list) {
        if (msg_list !== undefined && message === undefined) {
            message = msg_list.get(message_id);
        }
    });
    return message;
};

exports.update_starred = function (message_id, starred) {
    // Update the message object pointed to by the various message
    // lists.
    var message = exports.find_message(message_id);

    // If it isn't cached in the browser, no need to do anything
    if (message === undefined) {
        return;
    }

    unread_ops.mark_message_as_read(message);

    message.starred = starred;

    // Avoid a full re-render, but update the star in each message
    // table in which it is visible.
    update_message_in_all_views(message_id, function update_row(row) {
        var elt = row.find(".star");
        if (starred) {
            elt.addClass("icon-vector-star").removeClass("icon-vector-star-empty").removeClass("empty-star");
        } else {
            elt.removeClass("icon-vector-star").addClass("icon-vector-star-empty").addClass("empty-star");
        }
        var title_state = message.starred ? "Unstar" : "Star";
        elt.attr("title", title_state + " this message");
    });
};

var local_messages_to_show = [];
var show_message_timestamps = _.throttle(function () {
    _.each(local_messages_to_show, function (message_id) {
        update_message_in_all_views(message_id, function update_row(row) {
            row.find('.message_time').toggleClass('notvisible', false);
        });
    });
    local_messages_to_show = [];
}, 100);

exports.show_local_message_arrived = function (message_id) {
    local_messages_to_show.push(message_id);
    show_message_timestamps();
};

exports.show_message_failed = function (message_id, failed_msg) {
    // Failed to send message, so display inline retry/cancel
    update_message_in_all_views(message_id, function update_row(row) {
        var failed_div = row.find('.message_failed');
        failed_div.toggleClass('notvisible', false);
        failed_div.find('.failed_text').attr('title', failed_msg);
    });
};

exports.show_failed_message_success = function (message_id) {
    // Previously failed message succeeded
    update_message_in_all_views(message_id, function update_row(row) {
        row.find('.message_failed').toggleClass('notvisible', true);
    });
};

$(document).ready(function () {

    function info_overlay_close_modal() {
        $(".informational-overlays").removeClass("show");
    }

    modals.set_close_handler("informationalOverlays", info_overlay_close_modal);

    var info_overlay_toggle = components.toggle({
        name: "info-overlay-toggle",
        selected: 0,
        values: [
            { label: "Keyboard shortcuts", key: "keyboard-shortcuts" },
            { label: "Message formatting", key: "markdown-help" },
            { label: "Search operators", key: "search-operators" },
        ],
        callback: function (name, key) {
            $(".overlay-modal").hide();
            $("#" + key).show();
            $("#" + key).find(".modal-body").focus();
        },
    }).get();

    $(".informational-overlays .overlay-tabs")
        .append($(info_overlay_toggle).addClass("large"));
});

exports.show_info_overlay = function (target) {
    var el = {
        overlay: $(".informational-overlays"),
    };

    if (!el.overlay.hasClass("show")) {
        $(el.overlay).addClass("show");
    }

    if (target) {
        components.toggle.lookup("info-overlay-toggle").goto(target);
    }
};

var loading_more_messages_indicator_showing = false;
exports.show_loading_more_messages_indicator = function () {
    if (! loading_more_messages_indicator_showing) {
        loading.make_indicator($('#loading_more_messages_indicator'),
                                    {abs_positioned: true});
        loading_more_messages_indicator_showing = true;
        floating_recipient_bar.hide();
    }
};

exports.hide_loading_more_messages_indicator = function () {
    if (loading_more_messages_indicator_showing) {
        loading.destroy_indicator($("#loading_more_messages_indicator"));
        loading_more_messages_indicator_showing = false;
    }
};

/* EXPERIMENTS */

/* This method allows an advanced user to use the console
 * to switch the application to span full width of the browser.
 */
exports.switchToFullWidth = function () {
    $("#full-width-style").remove();
    $('head').append('<style id="full-width-style" type="text/css">' +
                         '#home .alert-bar, .recipient-bar-content, #compose-container, .app-main, .header-main { max-width: none; }' +
                     '</style>');
    return ("Switched to full width");
};

/* END OF EXPERIMENTS */

function scroll_finished() {
    actively_scrolling = false;

    if ($('#home').hasClass('active')) {
        if (!pointer.suppress_scroll_pointer_update) {
            message_viewport.keep_pointer_in_view();
        } else {
            pointer.suppress_scroll_pointer_update = false;
        }
        floating_recipient_bar.update();
        if (message_viewport.scrollTop() === 0 &&
            ui.have_scrolled_away_from_top) {
            ui.have_scrolled_away_from_top = false;
            message_fetch.load_more_messages(current_msg_list);
        } else if (!ui.have_scrolled_away_from_top) {
            ui.have_scrolled_away_from_top = true;
        }
        // When the window scrolls, it may cause some messages to
        // enter the screen and become read.  Calling
        // unread_ops.process_visible will update necessary
        // data structures and DOM elements.
        setTimeout(unread_ops.process_visible, 0);
    }
}

var scroll_timer;
function scroll_finish() {
    actively_scrolling = true;
    clearTimeout(scroll_timer);
    scroll_timer = setTimeout(scroll_finished, 100);
}

// Save the compose content cursor position and restore when we
// shift-tab back in (see hotkey.js).
var saved_compose_cursor = 0;

$(function () {
    message_viewport.message_pane.scroll($.throttle(50, function () {
        unread_ops.process_visible();
        scroll_finish();
    }));

    $('#new_message_content').blur(function () {
        saved_compose_cursor = $(this).caret();
    });

    // on the end of the modified-message fade in, remove the fade-in-message class.
    var animationEnd = "webkitAnimationEnd oanimationend msAnimationEnd animationend";
    $("body").on(animationEnd, ".fade-in-message", function () {
        $(this).removeClass("fade-in-message");
    });
});

exports.restore_compose_cursor = function () {
    $('#new_message_content')
        .focus()
        .caret(saved_compose_cursor);
};

$(function () {
    if (window.bridge !== undefined) {
        // Disable "spellchecking" in our desktop app. The "spellchecking"
        // in our Mac app is actually autocorrect, and frustrates our
        // users.
        $("#new_message_content").attr('spellcheck', 'false');
        // Modify the zephyr mirroring error message in our desktop
        // app, since it doesn't work from the desktop version.
        $("#webathena_login_menu").hide();
        $("#normal-zephyr-mirror-error-text").addClass("notdisplayed");
        $("#desktop-zephyr-mirror-error-text").removeClass("notdisplayed");
    }
});

return exports;
}());

if (typeof module !== 'undefined') {
    module.exports = ui;
}
<commit_msg>Use modal.open_overlay() for info overlays.<commit_after>var ui = (function () {

var exports = {};

var actively_scrolling = false;

exports.have_scrolled_away_from_top = true;

exports.actively_scrolling = function () {
    return actively_scrolling;
};

// What, if anything, obscures the home tab?

exports.replace_emoji_with_text = function (element) {
    element.find(".emoji").replaceWith(function () {
        return $(this).attr("alt");
    });
};

function update_message_in_all_views(message_id, callback) {
    _.each([message_list.all, home_msg_list, message_list.narrowed], function (list) {
        if (list === undefined) {
            return;
        }
        var row = list.get_row(message_id);
        if (row === undefined) {
            // The row may not exist, e.g. if you do an action on a message in
            // a narrowed view
            return;
        }
        callback(row);
    });
}

exports.find_message = function (message_id) {
    // Try to find the message object. It might be in the narrow list
    // (if it was loaded when narrowed), or only in the message_list.all
    // (if received from the server while in a different narrow)
    var message;
    _.each([message_list.all, home_msg_list, message_list.narrowed], function (msg_list) {
        if (msg_list !== undefined && message === undefined) {
            message = msg_list.get(message_id);
        }
    });
    return message;
};

exports.update_starred = function (message_id, starred) {
    // Update the message object pointed to by the various message
    // lists.
    var message = exports.find_message(message_id);

    // If it isn't cached in the browser, no need to do anything
    if (message === undefined) {
        return;
    }

    unread_ops.mark_message_as_read(message);

    message.starred = starred;

    // Avoid a full re-render, but update the star in each message
    // table in which it is visible.
    update_message_in_all_views(message_id, function update_row(row) {
        var elt = row.find(".star");
        if (starred) {
            elt.addClass("icon-vector-star").removeClass("icon-vector-star-empty").removeClass("empty-star");
        } else {
            elt.removeClass("icon-vector-star").addClass("icon-vector-star-empty").addClass("empty-star");
        }
        var title_state = message.starred ? "Unstar" : "Star";
        elt.attr("title", title_state + " this message");
    });
};

var local_messages_to_show = [];
var show_message_timestamps = _.throttle(function () {
    _.each(local_messages_to_show, function (message_id) {
        update_message_in_all_views(message_id, function update_row(row) {
            row.find('.message_time').toggleClass('notvisible', false);
        });
    });
    local_messages_to_show = [];
}, 100);

exports.show_local_message_arrived = function (message_id) {
    local_messages_to_show.push(message_id);
    show_message_timestamps();
};

exports.show_message_failed = function (message_id, failed_msg) {
    // Failed to send message, so display inline retry/cancel
    update_message_in_all_views(message_id, function update_row(row) {
        var failed_div = row.find('.message_failed');
        failed_div.toggleClass('notvisible', false);
        failed_div.find('.failed_text').attr('title', failed_msg);
    });
};

exports.show_failed_message_success = function (message_id) {
    // Previously failed message succeeded
    update_message_in_all_views(message_id, function update_row(row) {
        row.find('.message_failed').toggleClass('notvisible', true);
    });
};

$(document).ready(function () {

    var info_overlay_toggle = components.toggle({
        name: "info-overlay-toggle",
        selected: 0,
        values: [
            { label: "Keyboard shortcuts", key: "keyboard-shortcuts" },
            { label: "Message formatting", key: "markdown-help" },
            { label: "Search operators", key: "search-operators" },
        ],
        callback: function (name, key) {
            $(".overlay-modal").hide();
            $("#" + key).show();
            $("#" + key).find(".modal-body").focus();
        },
    }).get();

    $(".informational-overlays .overlay-tabs")
        .append($(info_overlay_toggle).addClass("large"));
});

exports.show_info_overlay = function (target) {
    var overlay = $(".informational-overlays");

    if (!overlay.hasClass("show")) {
        modals.open_overlay({
            name:  'informationalOverlays',
            overlay: overlay,
            on_close: function () {},
        });
    }

    if (target) {
        components.toggle.lookup("info-overlay-toggle").goto(target);
    }
};

var loading_more_messages_indicator_showing = false;
exports.show_loading_more_messages_indicator = function () {
    if (! loading_more_messages_indicator_showing) {
        loading.make_indicator($('#loading_more_messages_indicator'),
                                    {abs_positioned: true});
        loading_more_messages_indicator_showing = true;
        floating_recipient_bar.hide();
    }
};

exports.hide_loading_more_messages_indicator = function () {
    if (loading_more_messages_indicator_showing) {
        loading.destroy_indicator($("#loading_more_messages_indicator"));
        loading_more_messages_indicator_showing = false;
    }
};

/* EXPERIMENTS */

/* This method allows an advanced user to use the console
 * to switch the application to span full width of the browser.
 */
exports.switchToFullWidth = function () {
    $("#full-width-style").remove();
    $('head').append('<style id="full-width-style" type="text/css">' +
                         '#home .alert-bar, .recipient-bar-content, #compose-container, .app-main, .header-main { max-width: none; }' +
                     '</style>');
    return ("Switched to full width");
};

/* END OF EXPERIMENTS */

function scroll_finished() {
    actively_scrolling = false;

    if ($('#home').hasClass('active')) {
        if (!pointer.suppress_scroll_pointer_update) {
            message_viewport.keep_pointer_in_view();
        } else {
            pointer.suppress_scroll_pointer_update = false;
        }
        floating_recipient_bar.update();
        if (message_viewport.scrollTop() === 0 &&
            ui.have_scrolled_away_from_top) {
            ui.have_scrolled_away_from_top = false;
            message_fetch.load_more_messages(current_msg_list);
        } else if (!ui.have_scrolled_away_from_top) {
            ui.have_scrolled_away_from_top = true;
        }
        // When the window scrolls, it may cause some messages to
        // enter the screen and become read.  Calling
        // unread_ops.process_visible will update necessary
        // data structures and DOM elements.
        setTimeout(unread_ops.process_visible, 0);
    }
}

var scroll_timer;
function scroll_finish() {
    actively_scrolling = true;
    clearTimeout(scroll_timer);
    scroll_timer = setTimeout(scroll_finished, 100);
}

// Save the compose content cursor position and restore when we
// shift-tab back in (see hotkey.js).
var saved_compose_cursor = 0;

$(function () {
    message_viewport.message_pane.scroll($.throttle(50, function () {
        unread_ops.process_visible();
        scroll_finish();
    }));

    $('#new_message_content').blur(function () {
        saved_compose_cursor = $(this).caret();
    });

    // on the end of the modified-message fade in, remove the fade-in-message class.
    var animationEnd = "webkitAnimationEnd oanimationend msAnimationEnd animationend";
    $("body").on(animationEnd, ".fade-in-message", function () {
        $(this).removeClass("fade-in-message");
    });
});

exports.restore_compose_cursor = function () {
    $('#new_message_content')
        .focus()
        .caret(saved_compose_cursor);
};

$(function () {
    if (window.bridge !== undefined) {
        // Disable "spellchecking" in our desktop app. The "spellchecking"
        // in our Mac app is actually autocorrect, and frustrates our
        // users.
        $("#new_message_content").attr('spellcheck', 'false');
        // Modify the zephyr mirroring error message in our desktop
        // app, since it doesn't work from the desktop version.
        $("#webathena_login_menu").hide();
        $("#normal-zephyr-mirror-error-text").addClass("notdisplayed");
        $("#desktop-zephyr-mirror-error-text").removeClass("notdisplayed");
    }
});

return exports;
}());

if (typeof module !== 'undefined') {
    module.exports = ui;
}
<|endoftext|>


<commit_before>'use strict'

const Compression = require('compression-webpack-plugin')
const Analyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const MemoryFS = require('memory-fs')
const gzipSize = require('gzip-size')
const webpack = require('webpack')
const Uglify = require('uglifyjs-webpack-plugin')
const path = require('path')
const fs = require('fs')
const os = require('os')

const promisify = require('./promisify')

const WEBPACK_EMPTY_PROJECT = 293

function projectName (opts, files) {
  if (opts.bundle) {
    return `${ opts.bundle }.js`
  } else if (files.length === 1) {
    return path.basename(files[0])
  } else {
    return `${ path.basename(path.dirname(files[0])) }.js`
  }
}

function getConfig (files, opts) {
  const config = {
    entry: files,
    output: {
      filename: projectName(opts, files)
    },
    module: {
      rules: [
        { test: /\.(png|jpg|svg)$/, use: 'file-loader' }
      ]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')
      }),
      new Uglify({ sourceMap: false })
    ]
  }

  config.plugins.push(new Compression({ asset: '[path].gz' }))

  if (opts.analyzer) {
    config.output.path = path.join(os.tmpdir(), `size-limit-${ Date.now() }`)
    config.plugins.push(new Analyzer({
      openAnalyzer: opts.analyzer === 'server',
      analyzerMode: opts.analyzer,
      defaultSizes: 'gzip'
    }))
  }

  return config
}

function runWebpack (config, opts) {
  return promisify(done => {
    const compiler = webpack(config)
    if (!opts.analyzer) {
      compiler.outputFileSystem = new MemoryFS()
    }
    compiler.run(done)
  })
}

/**
 * Return size of project files with all dependencies and after UglifyJS
 * and gzip.
 *
 * @param {string|string[]} files Files to get size.
 * @param {object} [opts] Extra options.
 * @param {"server"|"static"|false} [opts.analyzer=false] Show package
 *                                                        content in browser.
 * @param {true|false} [opts.webpack=true] Pack files by webpack.
 * @param {string} [opts.bundle] Bundle name for Analyzer mode.
 *
 * @return {Promise} Promise with size of files
 *
 * @example
 * const getSize = require('size-limit')
 *
 * const index = path.join(__dirname, 'index.js')
 * const extra = path.join(__dirname, 'extra.js')
 *
 * getSize([index, extra]).then(size => {
 *   if (size > 1 * 1024 * 1024) {
 *     console.error('Project become bigger than 1MB')
 *   }
 * })
 */
function getSize (files, opts) {
  if (typeof files === 'string') files = [files]
  if (!opts) opts = { }

  if (opts.webpack === false) {
    return Promise.all(files.map(file => {
      return promisify(done => fs.readFile(file, 'utf8', done)).then(bytes => {
        return promisify(done => gzipSize(bytes, done))
      })
    })).then(sizes => {
      return sizes.reduce((all, size) => all + size, 0)
    })
  } else {
    return runWebpack(getConfig(files, opts), opts).then(stats => {
      if (stats.hasErrors()) {
        throw new Error(stats.toString('errors-only'))
      }

      const name = `${ stats.compilation.outputOptions.filename }.gz`
      const assets = stats.toJson().assets
      const size = assets.find(i => i.name === name).size

      return size - WEBPACK_EMPTY_PROJECT
    })
  }
}

module.exports = getSize
<commit_msg>Added support for CSS and CSS modules<commit_after>'use strict'

const Compression = require('compression-webpack-plugin')
const Analyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const MemoryFS = require('memory-fs')
const gzipSize = require('gzip-size')
const webpack = require('webpack')
const Uglify = require('uglifyjs-webpack-plugin')
const path = require('path')
const fs = require('fs')
const os = require('os')

const promisify = require('./promisify')

const WEBPACK_EMPTY_PROJECT = 293

function projectName (opts, files) {
  if (opts.bundle) {
    return `${ opts.bundle }.js`
  } else if (files.length === 1) {
    return path.basename(files[0])
  } else {
    return `${ path.basename(path.dirname(files[0])) }.js`
  }
}

function getConfig (files, opts) {
  const config = {
    entry: files,
    output: {
      filename: projectName(opts, files)
    },
    module: {
      rules: [
        { test: /\.(png|jpg|svg)$/, use: 'file-loader' },
        {
          test: /\.css$/,
          exclude: /\.module\.css$/,
          use: [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                minimize: true,
                modules: false
              }
            }
          ]
        },
        {
          test: /\.module\.css$/,
          use: [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                minimize: true,
                modules: true
              }
            }
          ]
        }
      ]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')
      }),
      new Uglify({ sourceMap: false })
    ]
  }

  config.plugins.push(new Compression({ asset: '[path].gz' }))

  if (opts.analyzer) {
    config.output.path = path.join(os.tmpdir(), `size-limit-${ Date.now() }`)
    config.plugins.push(new Analyzer({
      openAnalyzer: opts.analyzer === 'server',
      analyzerMode: opts.analyzer,
      defaultSizes: 'gzip'
    }))
  }

  return config
}

function runWebpack (config, opts) {
  return promisify(done => {
    const compiler = webpack(config)
    if (!opts.analyzer) {
      compiler.outputFileSystem = new MemoryFS()
    }
    compiler.run(done)
  })
}

/**
 * Return size of project files with all dependencies and after UglifyJS
 * and gzip.
 *
 * @param {string|string[]} files Files to get size.
 * @param {object} [opts] Extra options.
 * @param {"server"|"static"|false} [opts.analyzer=false] Show package
 *                                                        content in browser.
 * @param {true|false} [opts.webpack=true] Pack files by webpack.
 * @param {string} [opts.bundle] Bundle name for Analyzer mode.
 *
 * @return {Promise} Promise with size of files
 *
 * @example
 * const getSize = require('size-limit')
 *
 * const index = path.join(__dirname, 'index.js')
 * const extra = path.join(__dirname, 'extra.js')
 *
 * getSize([index, extra]).then(size => {
 *   if (size > 1 * 1024 * 1024) {
 *     console.error('Project become bigger than 1MB')
 *   }
 * })
 */
function getSize (files, opts) {
  if (typeof files === 'string') files = [files]
  if (!opts) opts = { }

  if (opts.webpack === false) {
    return Promise.all(files.map(file => {
      return promisify(done => fs.readFile(file, 'utf8', done)).then(bytes => {
        return promisify(done => gzipSize(bytes, done))
      })
    })).then(sizes => {
      return sizes.reduce((all, size) => all + size, 0)
    })
  } else {
    return runWebpack(getConfig(files, opts), opts).then(stats => {
      if (stats.hasErrors()) {
        throw new Error(stats.toString('errors-only'))
      }

      const name = `${ stats.compilation.outputOptions.filename }.gz`
      const assets = stats.toJson().assets
      const size = assets.find(i => i.name === name).size

      return size - WEBPACK_EMPTY_PROJECT
    })
  }
}

module.exports = getSize
<|endoftext|>


<commit_before>$('#st_form').submit(function(e) {
    e.preventDefault();
    $('#loading').show();

    $('#topic').empty();
    var val = $("#st_input", this).val();
    var url = "/cgi-bin/StalkerBotCGI.py";

    console.log(val);

    function htmlEncode(str)
    {
        str = str.replace(/&/g, "&");
        str = str.replace(/>/g, ">");
        str = str.replace(/</g, "<");
        str = str.replace(/"/g, """);
        str = str.replace(/'/g, "'");
        return str;
    }

    $.ajax({
        url: url,
        dataType: 'json',
        data:{ userid:val},
        success:function(data) {
            console.log(data);
            var blockCount = 0;

            $.each(data, function(index, element) {
                // element has format ['tag', ['sentiment1'(,'sentiment2',...)]]
		$.each(element[0], function(index, tag) {
                    // tag = element[0];
                    sentimentList = element[1];
                    commentText = htmlEncode(element[2]);
                    commentLink = element[3];
                    articleLink = element[4];
                    console.log(element, tag, sentimentList);

                    $.each(sentimentList, function(index, sentiment) {
			sentimentAdj = {"Confidence" : "confident",
					"Anxiety"    : "anxious",
					"Compassion" : "compassionate",
					"Hostility"  : "hostile",
					"Depression" : "depressed",
					"Happiness"  : "happy"};

			if (blockCount >= 5) {
                            $('#topic').append('

');
                            blockCount = 0;
			}

			var li = $('

' + tag + '
'
			    + '
'
			    + sentimentAdj[sentiment] + '

');
			console.log(li.val());
			$('#topic').append(li);
			blockCount++;
                    });
                });
            });
            $('.hn_link').bt({
                padding: 20,
                width: 275,
                spikeLength: 20,
                spikeGirth: 20,
                cornerRadius: 20,
                fill: 'rgba(0, 0, 0, .8)',
                strokeWidth: 3,
                strokeStyle: '#ef4136',
                cssStyles: {color: '#FFF'},
                positions: ['right', 'left']
            });
        },
        complete: function() {
            $('#loading').hide();
        }
    });
});

<commit_msg>Introduced spacing between article faces on web page.<commit_after>$('#st_form').submit(function(e) {
    e.preventDefault();
    $('#loading').show();

    $('#topic').empty();
    var val = $("#st_input", this).val();
    var url = "/cgi-bin/StalkerBotCGI.py";

    console.log(val);

    function htmlEncode(str)
    {
        str = str.replace(/&/g, "&");
        str = str.replace(/>/g, ">");
        str = str.replace(/</g, "<");
        str = str.replace(/"/g, """);
        str = str.replace(/'/g, "'");
        return str;
    }

    $.ajax({
        url: url,
        dataType: 'json',
        data:{ userid:val},
        success:function(data) {
            console.log(data);
            var blockCount = 0;

            $.each(data, function(index, element) {
                // element has format ['tag', ['sentiment1'(,'sentiment2',...)]]
		$.each(element[0], function(index, tag) {
                    // tag = element[0];
                    sentimentList = element[1];
                    commentText = htmlEncode(element[2]);
                    commentLink = element[3];
                    articleLink = element[4];
                    console.log(element, tag, sentimentList);

                    $.each(sentimentList, function(index, sentiment) {
			sentimentAdj = {"Confidence" : "confident",
					"Anxiety"    : "anxious",
					"Compassion" : "compassionate",
					"Hostility"  : "hostile",
					"Depression" : "depressed",
					"Happiness"  : "happy"};

			if (blockCount >= 5) {
                            $('#topic').append('

');
                           blockCount = 0;
			}

//			var li = $('

'
			var li = $('

'
                            + tag + '
'
			    + '
'
			    + sentimentAdj[sentiment] + '

');
			console.log(li.val());
			$('#topic').append(li);
			blockCount++;
                    });
                });
                $('#topic').append('

');
                $('#topic').append('

');
                blockCount = 0;
            });
            $('.hn_link').bt({
                padding: 20,
                width: 275,
                spikeLength: 20,
                spikeGirth: 20,
                cornerRadius: 20,
                fill: 'rgba(0, 0, 0, .8)',
                strokeWidth: 3,
                strokeStyle: '#ef4136',
                cssStyles: {color: '#FFF'},
                positions: ['right', 'left']
            });
        },
        complete: function() {
            $('#loading').hide();
        }
    });
});

<|endoftext|>


<commit_before>'use static';

var _         = require('lodash');
var Bluebird  = require('bluebird');
var fs        = require('fs');
var Migration = require('./lib/migration');
var path      = require('path');
var redefine  = require('redefine');

var Umzug = module.exports = redefine.Class({
  constructor: function (options) {
    this.options = _.assign({
      storage:        'json',
      storageOptions: {},
      upName:         'up',
      downName:       'down'
    }, options);

    this.options.migrations = _.assign({
      params:  [],
      path:    path.resolve(process.cwd(), 'migrations'),
      pattern: /^\d+[\w-]+\.js$/,
      wrap:    function (fun) { return fun; }
    }, this.options.migrations);

    this.storage = this._initStorage();
  },

  execute: function (options) {
    var self = this;

    options = _.assign({
      migrations: [],
      method:     'up'
    }, options || {});

    return Bluebird
      .map(options.migrations, function (migration) {
        return self._findMigration(migration);
      })
      .then(function (migrations) {
        return _.assign(options, { migrations: migrations });
      })
      .then(function (options) {
        return Bluebird.each(options.migrations, function (migration) {
          return self
            ._wasExecuted(migration)
            .catch(function () {
              return false;
            })
            .then(function (executed) {
              return (typeof executed === 'undefined') ? true : executed;
            })
            .tap(function (executed) {
              if (!executed || (options.method === 'down')) {
                var fun    = (migration[options.method] || Bluebird.resolve);
                var params = self.options.migrations.params;

                if (typeof params === 'function') {
                  params = params();
                }

                return fun.apply(migration, params);
              }
            })
            .then(function (executed) {
              if (!executed && (options.method === 'up')) {
                return Bluebird.resolve(self.storage.logMigration(migration.file));
              } else if (options.method === 'down') {
                return Bluebird.resolve(self.storage.unlogMigration(migration.file));
              }
            });
        });
      });
  },

  executed: function () {
    return Bluebird.resolve(this.storage.executed()).bind(this).map(function (file) {
      return new Migration(file);
    });
  },

  pending: function () {
    return this
      ._findMigrations()
      .bind(this)
      .then(function (all) {
        return Bluebird.join(all, this.executed());
      })
      .spread(function (all, executed) {
        var executedFiles = executed.map(function (migration) {
          return migration.file;
        });

        return all.filter(function (migration) {
          return executedFiles.indexOf(migration.file) === -1;
        }).sort(function (a, b) {
          if (a.file > b.file) {
            return 1;
          } else  if (a.file < b.file) {
            return -1;
          } else {
            return 0;
          }
        });
      });
  },

  up: function (options) {
    if (typeof options === 'string') {
      return this.up([ options ]);
    } else if (Array.isArray(options)) {
      return Bluebird.resolve(options).bind(this)
        .map(function (migration) {
          return this._findMigration(migration)
        })
        .then(function (migrations) {
          return this._arePending(migrations);
        })
        .then(function () {
          return this.up({ migrations: options });
        });
    }

    options = _.assign({
      to:         null,
      migrations: null
    }, options || {});

    if (options.migrations) {
      return this.execute({ migrations: options.migrations, method: 'up' });
    } else {
      return this.pending().bind(this)
        .then(function (migrations) {
          return this._findMigrationsUntilMatch(options.to, migrations);
        })
        .then(function (migrationFiles) {
          return this.up({ migrations: migrationFiles });
        });
    }
  },

  down: function (options) {
    var getExecuted = function () {
      return this.executed().bind(this).then(function(migrations) {
        return migrations.reverse();
      });
    }.bind(this);

    if (typeof options === 'undefined') {
      return getExecuted().bind(this).then(function (migrations) {
        return migrations[0] ? this.down(migrations[0].file) : Bluebird.resolve([]);
      });
    } else if (typeof options === 'string') {
      return this.down([ options ]);
    } else if (Array.isArray(options)) {
      return Bluebird.resolve(options).bind(this)
        .map(function (migration) {
          return this._findMigration(migration)
        })
        .then(function (migrations) {
          return this._wereExecuted(migrations);
        })
        .then(function () {
          return this.down({ migrations: options });
        });
    }

    options = _.assign({
      to:         null,
      migrations: null
    }, options || {});

    if (options.migrations) {
      return this.execute({ migrations: options.migrations, method: 'down' });
    } else {
      return getExecuted().bind(this)
        .then(function (migrations) {
          return this._findMigrationsUntilMatch(options.to, migrations);
        })
        .then(function (migrationFiles) {
          return this.down({ migrations: migrationFiles });
        });
    }
  },

  _initStorage: function () {
    var Storage;

    try {
      Storage = require(__dirname + '/lib/storages/' + this.options.storage);
    } catch (e) {
      // We have not been able to find the storage locally.
      // Let's try to require a module instead.
    }

    try {
      Storage = Storage || require(this.options.storage);
    } catch (e) {
      throw new Error('Unable to resolve the storage: ' + this.options.storage);
    }

    return new Storage(this.options);
  },

  _findMigrations: function () {
    return Bluebird
      .promisify(fs.readdir)(this.options.migrations.path)
      .bind(this)
      .filter(function (file) {
        return this.options.migrations.pattern.test(file);
      })
      .map(function (file) {
        return path.resolve(this.options.migrations.path, file);
      })
      .map(function (path) {
        return new Migration(path, this.options);
      });
  },

  _findMigration: function (needle) {
    return this
      ._findMigrations()
      .then(function (migrations) {
        return migrations.filter(function (migration) {
          return migration.testFileName(needle);
        })[0];
      })
      .then(function (migration) {
        if (migration) {
          return migration;
        } else {
          return Bluebird.reject(new Error('Unable to find migration: ' + needle));
        }
      });
  },

  _wasExecuted: function (_migration) {
    return this.executed().filter(function (migration) {
      return migration.testFileName(_migration.file);
    }).then(function(migrations) {
      if (migrations[0]) {
        return Bluebird.resolve();
      } else {
        return Bluebird.reject(new Error('Migration was not executed: ' + _migration.file));
      }
    });
  },

  _wereExecuted: function (migrationNames) {
    return Bluebird
      .resolve(migrationNames)
      .bind(this)
      .map(function (migration) {
        return this._wasExecuted(migration);
      });
  },

  _isPending: function (_migration) {
    return this.pending().filter(function (migration) {
      return migration.testFileName(_migration.file);
    }).then(function(migrations) {
      if (migrations[0]) {
        return Bluebird.resolve();
      } else {
        return Bluebird.reject(new Error('Migration is not pending: ' + _migration.file));
      }
    });
  },

  _arePending: function (migrationNames) {
    return Bluebird
      .resolve(migrationNames)
      .bind(this)
      .map(function (migration) {
        return this._isPending(migration);
      });
  },

  _findMigrationsUntilMatch: function (to, migrations) {
    return Bluebird.resolve(migrations)
      .map(function (migration) { return migration.file })
      .reduce(function (acc, migration) {
        if (acc.add) {
          acc.migrations.push(migration);

          if (to && (migration.indexOf(to) === 0)) {
            // Stop adding the migrations once the final migration
            // has been added.
            acc.add = false;
          }
        }

        return acc;
      }, { migrations: [], add: true })
      .get('migrations');
  }
});
<commit_msg>added ActiveRecord like logging messages for each executed migration<commit_after>'use static';

var _         = require('lodash');
var Bluebird  = require('bluebird');
var fs        = require('fs');
var Migration = require('./lib/migration');
var path      = require('path');
var redefine  = require('redefine');

var Umzug = module.exports = redefine.Class({
  constructor: function (options) {
    this.options = _.assign({
      storage:        'json',
      storageOptions: {},
      upName:         'up',
      downName:       'down'
    }, options);

    this.options.migrations = _.assign({
      params:  [],
      path:    path.resolve(process.cwd(), 'migrations'),
      pattern: /^\d+[\w-]+\.js$/,
      wrap:    function (fun) { return fun; }
    }, this.options.migrations);

    this.storage = this._initStorage();
  },

  execute: function (options) {
    var self = this;

    options = _.assign({
      migrations: [],
      method:     'up'
    }, options || {});

    return Bluebird
      .map(options.migrations, function (migration) {
        return self._findMigration(migration);
      })
      .then(function (migrations) {
        return _.assign(options, { migrations: migrations });
      })
      .then(function (options) {
        return Bluebird.each(options.migrations, function (migration) {
          var name = path.basename(migration.file, path.extname(migration.file));
          var startTime;
          return self
            ._wasExecuted(migration)
            .catch(function () {
              return false;
            })
            .then(function (executed) {
              return (typeof executed === 'undefined') ? true : executed;
            })
            .tap(function (executed) {
              if (!executed || (options.method === 'down')) {
                var fun    = (migration[options.method] || Bluebird.resolve);
                var params = self.options.migrations.params;

                if (typeof params === 'function') {
                  params = params();
                }

                if (options.method === 'up') {
                  console.log("== " + name + ": migrating =======");
                } else {
                  console.log("== " + name + ": reverting =======");
                }

                startTime = new Date();

                return fun.apply(migration, params);
              }
            })
            .then(function (executed) {
              if (!executed && (options.method === 'up')) {
                return Bluebird.resolve(self.storage.logMigration(migration.file));
              } else if (options.method === 'down') {
                return Bluebird.resolve(self.storage.unlogMigration(migration.file));
              }
            })
            .tap(function () {
              var duration = ((new Date() - startTime) / 1000).toFixed(3);
              if (options.method === 'up') {
                console.log("== " + name + ": migrated (" + duration +  "s)\n");
              } else {
                console.log("== " + name + ": reverted (" + duration +  "s)\n");
              }
            });
        });
      });
  },

  executed: function () {
    return Bluebird.resolve(this.storage.executed()).bind(this).map(function (file) {
      return new Migration(file);
    });
  },

  pending: function () {
    return this
      ._findMigrations()
      .bind(this)
      .then(function (all) {
        return Bluebird.join(all, this.executed());
      })
      .spread(function (all, executed) {
        var executedFiles = executed.map(function (migration) {
          return migration.file;
        });

        return all.filter(function (migration) {
          return executedFiles.indexOf(migration.file) === -1;
        }).sort(function (a, b) {
          if (a.file > b.file) {
            return 1;
          } else  if (a.file < b.file) {
            return -1;
          } else {
            return 0;
          }
        });
      });
  },

  up: function (options) {
    if (typeof options === 'string') {
      return this.up([ options ]);
    } else if (Array.isArray(options)) {
      return Bluebird.resolve(options).bind(this)
        .map(function (migration) {
          return this._findMigration(migration)
        })
        .then(function (migrations) {
          return this._arePending(migrations);
        })
        .then(function () {
          return this.up({ migrations: options });
        });
    }

    options = _.assign({
      to:         null,
      migrations: null
    }, options || {});

    if (options.migrations) {
      return this.execute({ migrations: options.migrations, method: 'up' });
    } else {
      return this.pending().bind(this)
        .then(function (migrations) {
          return this._findMigrationsUntilMatch(options.to, migrations);
        })
        .then(function (migrationFiles) {
          return this.up({ migrations: migrationFiles });
        });
    }
  },

  down: function (options) {
    var getExecuted = function () {
      return this.executed().bind(this).then(function(migrations) {
        return migrations.reverse();
      });
    }.bind(this);

    if (typeof options === 'undefined') {
      return getExecuted().bind(this).then(function (migrations) {
        return migrations[0] ? this.down(migrations[0].file) : Bluebird.resolve([]);
      });
    } else if (typeof options === 'string') {
      return this.down([ options ]);
    } else if (Array.isArray(options)) {
      return Bluebird.resolve(options).bind(this)
        .map(function (migration) {
          return this._findMigration(migration)
        })
        .then(function (migrations) {
          return this._wereExecuted(migrations);
        })
        .then(function () {
          return this.down({ migrations: options });
        });
    }

    options = _.assign({
      to:         null,
      migrations: null
    }, options || {});

    if (options.migrations) {
      return this.execute({ migrations: options.migrations, method: 'down' });
    } else {
      return getExecuted().bind(this)
        .then(function (migrations) {
          return this._findMigrationsUntilMatch(options.to, migrations);
        })
        .then(function (migrationFiles) {
          return this.down({ migrations: migrationFiles });
        });
    }
  },

  _initStorage: function () {
    var Storage;

    try {
      Storage = require(__dirname + '/lib/storages/' + this.options.storage);
    } catch (e) {
      // We have not been able to find the storage locally.
      // Let's try to require a module instead.
    }

    try {
      Storage = Storage || require(this.options.storage);
    } catch (e) {
      throw new Error('Unable to resolve the storage: ' + this.options.storage);
    }

    return new Storage(this.options);
  },

  _findMigrations: function () {
    return Bluebird
      .promisify(fs.readdir)(this.options.migrations.path)
      .bind(this)
      .filter(function (file) {
        return this.options.migrations.pattern.test(file);
      })
      .map(function (file) {
        return path.resolve(this.options.migrations.path, file);
      })
      .map(function (path) {
        return new Migration(path, this.options);
      });
  },

  _findMigration: function (needle) {
    return this
      ._findMigrations()
      .then(function (migrations) {
        return migrations.filter(function (migration) {
          return migration.testFileName(needle);
        })[0];
      })
      .then(function (migration) {
        if (migration) {
          return migration;
        } else {
          return Bluebird.reject(new Error('Unable to find migration: ' + needle));
        }
      });
  },

  _wasExecuted: function (_migration) {
    return this.executed().filter(function (migration) {
      return migration.testFileName(_migration.file);
    }).then(function(migrations) {
      if (migrations[0]) {
        return Bluebird.resolve();
      } else {
        return Bluebird.reject(new Error('Migration was not executed: ' + _migration.file));
      }
    });
  },

  _wereExecuted: function (migrationNames) {
    return Bluebird
      .resolve(migrationNames)
      .bind(this)
      .map(function (migration) {
        return this._wasExecuted(migration);
      });
  },

  _isPending: function (_migration) {
    return this.pending().filter(function (migration) {
      return migration.testFileName(_migration.file);
    }).then(function(migrations) {
      if (migrations[0]) {
        return Bluebird.resolve();
      } else {
        return Bluebird.reject(new Error('Migration is not pending: ' + _migration.file));
      }
    });
  },

  _arePending: function (migrationNames) {
    return Bluebird
      .resolve(migrationNames)
      .bind(this)
      .map(function (migration) {
        return this._isPending(migration);
      });
  },

  _findMigrationsUntilMatch: function (to, migrations) {
    return Bluebird.resolve(migrations)
      .map(function (migration) { return migration.file })
      .reduce(function (acc, migration) {
        if (acc.add) {
          acc.migrations.push(migration);

          if (to && (migration.indexOf(to) === 0)) {
            // Stop adding the migrations once the final migration
            // has been added.
            acc.add = false;
          }
        }

        return acc;
      }, { migrations: [], add: true })
      .get('migrations');
  }
});
<|endoftext|>


<commit_before>/**
 * --------------------------------------------------------------------------
 * html-inflect
 * Cleanup, modify, and save messy HTML
 * @author Evan Yamanishi
 * @license GPL-3.0
 * --------------------------------------------------------------------------
 */

'use strict';

const assert = require('assert');
const changeTag = require('./action/changeTag');
const removeAttributes = require('./action/removeAttributes');
const removeElement = require('./action/removeElement');
const setSemantics = require('./action/setSemantics');

const NAME = 'html-inflect';
const VERSION = '2.0.0';

class Inflect {
    constructor(doc) {
        try {
            if (document instanceof HTMLDocument) this.doc = document;
        } catch (err) {
            assert(typeof doc === 'object', 'A document object is required');
            this.doc = doc;
        }
        this.count = {};
    }

    get name() {
        return NAME;
    }

    get version() {
        return VERSION;
    }

    runTask(task) {
        assert(task.constructor === Object, 'Task must be an object');
        assert(task.selector, 'A selector is required');
        assert(typeof task.action === 'function' ||
            typeof Inflect[task.action] === 'function',
            `${task.action} is not a valid function`);

        return new Promise((resolve, reject) => {
            Array.from(this.doc.querySelectorAll(task.selector)).forEach((el) => {
                let fn = (typeof Inflect[task.action] === 'function') ?
                    Inflect[task.action] :
                    task.action;
                fn(el, task.parameter)
                    .then((result) => {
                        result = result || fn.name;
                        this._processResults(result).then((res) => resolve(res));
                    });
            });
        }).then((result) => this._processResults(result));
    }

    runTasks(tasks) {
        return new Promise((resolve, reject) => {
            this._async(tasks, 0).then(() => resolve());
        });
    }

    _async(taskArr, index) {
        return new Promise((resolve, reject) => {
            this.runTask(taskArr[index]).then(() => {
                index++;
                if (index < taskArr.length) {
                    this._async(taskArr, index).then(() => resolve());
                } else {
                    resolve();
                }
            });
        });
    }

    _processResults(result) {
        return new Promise((resolve, reject) => {
            if (!result) resolve();
            switch (result.constructor) {
                case Array:
                    if (typeof result[1] === 'string') {
                        this._incrementCount(result[1]);
                        resolve(result[0]);
                    } else {
                        this.runTasks(result).then(() => resolve());
                    }
                    break;
                case Object:
                    this.runTask(result).then(() => resolve());
                    break;
                case String:
                    this._incrementCount(result);
                    resolve();
                    break;
                default:
                    resolve();
            }
        });
    }

    _incrementCount(key) {
        this.count[key] = (this.count[key] === undefined) ?
            1 :
            this.count[key] + 1;
    }

    static changeTag(el, newTag) {
        return changeTag(el, newTag);
    }

    static removeAttributes(el, ...attributes) {
        return removeAttributes(el, ...attributes);
    }

    static removeContainer(el) {
        return removeElement(el, true);
    }

    static removeElement(el, keepChildren) {
        return removeElement(el, keepChildren);
    }

    static removeParent(el) {
        return removeElement(el.parentNode, true);
    }

    static setEpubType(el, ...types) {
        return setSemantics(el, 'epub\:type', ...types);
    }

    static setRole(el, ...roles) {
        return setSemantics(el, 'role', ...roles);
    }
}

module.exports = Inflect;
<commit_msg>removed redundant constants<commit_after>/**
 * --------------------------------------------------------------------------
 * html-inflect
 * Cleanup, modify, and save messy HTML
 * @author Evan Yamanishi
 * @license GPL-3.0
 * --------------------------------------------------------------------------
 */

'use strict';

const assert = require('assert');
const changeTag = require('./action/changeTag');
const removeAttributes = require('./action/removeAttributes');
const removeElement = require('./action/removeElement');
const setSemantics = require('./action/setSemantics');

class Inflect {
    constructor(doc) {
        try {
            if (document instanceof HTMLDocument) this.doc = document;
        } catch (err) {
            assert(typeof doc === 'object', 'A document object is required');
            this.doc = doc;
        }
        this.count = {};
    }
    }

    runTask(task) {
        assert(task.constructor === Object, 'Task must be an object');
        assert(task.selector, 'A selector is required');
        assert(typeof task.action === 'function' ||
            typeof Inflect[task.action] === 'function',
            `${task.action} is not a valid function`);

        return new Promise((resolve, reject) => {
            Array.from(this.doc.querySelectorAll(task.selector)).forEach((el) => {
                let fn = (typeof Inflect[task.action] === 'function') ?
                    Inflect[task.action] :
                    task.action;
                fn(el, task.parameter)
                    .then((result) => {
                        result = result || fn.name;
                        this._processResults(result).then((res) => resolve(res));
                    });
            });
        }).then((result) => this._processResults(result));
    }

    runTasks(tasks) {
        return new Promise((resolve, reject) => {
            this._async(tasks, 0).then(() => resolve());
        });
    }

    _async(taskArr, index) {
        return new Promise((resolve, reject) => {
            this.runTask(taskArr[index]).then(() => {
                index++;
                if (index < taskArr.length) {
                    this._async(taskArr, index).then(() => resolve());
                } else {
                    resolve();
                }
            });
        });
    }

    _processResults(result) {
        return new Promise((resolve, reject) => {
            if (!result) resolve();
            switch (result.constructor) {
                case Array:
                    if (typeof result[1] === 'string') {
                        this._incrementCount(result[1]);
                        resolve(result[0]);
                    } else {
                        this.runTasks(result).then(() => resolve());
                    }
                    break;
                case Object:
                    this.runTask(result).then(() => resolve());
                    break;
                case String:
                    this._incrementCount(result);
                    resolve();
                    break;
                default:
                    resolve();
            }
        });
    }

    _incrementCount(key) {
        this.count[key] = (this.count[key] === undefined) ?
            1 :
            this.count[key] + 1;
    }

    static changeTag(el, newTag) {
        return changeTag(el, newTag);
    }

    static removeAttributes(el, ...attributes) {
        return removeAttributes(el, ...attributes);
    }

    static removeContainer(el) {
        return removeElement(el, true);
    }

    static removeElement(el, keepChildren) {
        return removeElement(el, keepChildren);
    }

    static removeParent(el) {
        return removeElement(el.parentNode, true);
    }

    static setEpubType(el, ...types) {
        return setSemantics(el, 'epub\:type', ...types);
    }

    static setRole(el, ...roles) {
        return setSemantics(el, 'role', ...roles);
    }
}

module.exports = Inflect;
<|endoftext|>


<commit_before>/**
 * @module ogs.geo
 */

/**
 * Create a new instance of class command
 *
 * @class
 * @returns {geoModule.command}
 */
geoModule.command = function() {

  if (!(this instanceof geoModule.command)) {
    return new geoModule.command();
  }
  ogs.vgl.command.call(this);

  return this;
};

inherit(geoModule.command, ogs.vgl.command);

/**
 * Event types
 */
geoModule.command.updateEvent = "updateEvent";
geoModule.command.addLayerEvent = "addLayerEvent";
geoModule.command.removeLayerEvent = "removeLayerEvent";
geoModule.command.toggleLayerEvent = "toggleLayerEvent";
geoModule.command.selectLayerEvent = "selectLayerEvent";
geoModule.command.unselectLayerEvent = "unselectLayerEvent";
geoModule.command.updateZoomEvent = "updateZoomEvent";
geoModule.command.resizeEvent = "resizeEvent";<commit_msg>Geo updated<commit_after>/**
 * @module ogs.geo
 */

/**
 * Create a new instance of class command
 *
 * @class
 * @returns {geoModule.command}
 */
/*global geoModule, ogs, inherit*/
/*jslint devel: true, eqeq: true, forin: true, newcap: true, plusplus: true, todo: true, indent: 2 */
geoModule.command = function() {
  "use strict";
  if (!(this instanceof geoModule.command)) {
    return new geoModule.command();
  }
  ogs.vgl.command.call(this);

  return this;
};

inherit(geoModule.command, ogs.vgl.command);

/**
 * Event types
 */
geoModule.command.updateEvent = "updateEvent";
geoModule.command.addLayerEvent = "addLayerEvent";
geoModule.command.removeLayerEvent = "removeLayerEvent";
geoModule.command.toggleLayerEvent = "toggleLayerEvent";
geoModule.command.selectLayerEvent = "selectLayerEvent";
geoModule.command.unselectLayerEvent = "unselectLayerEvent";
geoModule.command.updateZoomEvent = "updateZoomEvent";
geoModule.command.resizeEvent = "resizeEvent";
<|endoftext|>


<commit_before>var path = require('path');

var express = require('express');
var app = express();

var compress = require('compression');
var layouts = require('express-ejs-layouts');

app.set('layout');
app.set('view engine', 'ejs');
app.set('view options', {layout:'layout'});
app.set('views', path.join(process.cwd(), '/server/views'));

app.use(compress());
app.use(layouts);
app.use("/client", express.static(path.join(process.cwd(), '/client')));

var env = {
  production: process.env['NODE_ENV'] === 'production'
};

app.get('/*', function(req, res) {
  res.render('index', {
    env: env
  });
});

var port = Number(process.env.PORT || 3001);
app.listen(port, function () {
  console.log('server running at localhost:3001, go refresh and see magic');
});

if (env.production === false) {
  var webpack = require('webpack');
  var WebpackDevServer = require('webpack-dev-server');
  var webpackConfig = require('./webpack.dev.config');

  new WebpackDevServer(webpack(webpackConfig), {
    publicPath: '/client/',

    contentBase: './client/',

    inline: true,

    hot: true,

    stats: {
      colors: true
    },

    historyApiFallback: true,

    headers: {
      'Access-Control-Allow-Origin': 'http://localhost:3001',
      'Access-Control-Allow-Headers': 'X-Requested-With'
    }
  }).listen(3000, 'localhost', function (err, result) {
    if (err) {
      console.log(err);
    }

    console.log('webpack dev server listening on localhost:3000');
  });
}
<commit_msg>Remove `x-powered-by` http header<commit_after>var path = require('path');

var express = require('express');
var app = express();

var compress = require('compression');
var layouts = require('express-ejs-layouts');

app.set('layout');
app.set('view engine', 'ejs');
app.set('view options', {layout:'layout'});
app.set('views', path.join(process.cwd(), '/server/views'));

app.use(compress());
app.use(layouts);
app.use("/client", express.static(path.join(process.cwd(), '/client')));

app.disable('x-powered-by');

var env = {
  production: process.env['NODE_ENV'] === 'production'
};

app.get('/*', function(req, res) {
  res.render('index', {
    env: env
  });
});

var port = Number(process.env.PORT || 3001);
app.listen(port, function () {
  console.log('server running at localhost:3001, go refresh and see magic');
});

if (env.production === false) {
  var webpack = require('webpack');
  var WebpackDevServer = require('webpack-dev-server');
  var webpackConfig = require('./webpack.dev.config');

  new WebpackDevServer(webpack(webpackConfig), {
    publicPath: '/client/',

    contentBase: './client/',

    inline: true,

    hot: true,

    stats: {
      colors: true
    },

    historyApiFallback: true,

    headers: {
      'Access-Control-Allow-Origin': 'http://localhost:3001',
      'Access-Control-Allow-Headers': 'X-Requested-With'
    }
  }).listen(3000, 'localhost', function (err, result) {
    if (err) {
      console.log(err);
    }

    console.log('webpack dev server listening on localhost:3000');
  });
}
<|endoftext|>


<commit_before>'use strict'

const Stream = require('./lib/Stream');

// factory
module.exports = adapter => {

    if (!adapter.read || !adapter.mod) {
        throw new Error('Flow: No "mod" or "read" methods on adapter.');
    }

    const scope = {
        env: adapter.env,
        mod: adapter.mod,
        read: adapter.read,

        // cache must have "get", "set" and "reset" methods
        cache: adapter.cache,

        // reset cache
        reset: () => {

            if (typeof adapter.reset === 'function') {
                adapter.reset();
            }

            adapter.cache.reset();
        }
    };

    return scope.flow = (event, options) => {
        return Stream(scope, event, options);
    };
};
<commit_msg>get env as a separate argument<commit_after>'use strict'

const Stream = require('./lib/Stream');

// factory
module.exports = (env, adapter) => {

    if (!adapter.read || !adapter.mod) {
        throw new Error('Flow: No "mod" or "read" methods on adapter.');
    }

    const scope = {
        env: env || {},
        mod: adapter.mod,
        read: adapter.read,

        // cache must have "get", "set" and "reset" methods
        cache: adapter.cache,

        // reset cache
        reset: () => {

            if (typeof adapter.reset === 'function') {
                adapter.reset();
            }

            adapter.cache.reset();
        }
    };

    return scope.flow = (event, options) => {
        return Stream(scope, event, options);
    };
};
<|endoftext|>


<commit_before>// Include monitoring and alerting. This is also used to keep the dyno from idling.
require('newrelic');

// If environment variables aren't defined, load the .env file
if (!process.env.SLACK_API_TOKEN) require('dotenv').config();

//For avoidong Heroku $PORT error
var express = require('express');
var app     = express();
app.set('port', (process.env.PORT || 5000));
app.get('/', function(request, response) {
    var result = 'App is running';
    response.send(result);
}).listen(app.get('port'), function() {
    console.log('App is running, server is listening on port ', app.get('port'));
});

// Required modules
var RtmClient = require('@slack/client').RtmClient;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;
var WebClient = require('@slack/client').WebClient;
var Client = require('node-rest-client').Client;

// Global variables
var client = new Client({port: process.env.PORT});
var token = process.env.SLACK_API_TOKEN || '';
var apikey = process.env.TICKETMASTER_API_KEY || '';
var rtm = new RtmClient(token);
var web = new WebClient(token);

// Data object for the web.chat.postMessage call
var msgdata = {
	username: (process.env.DEV) ? "apibot-dev" : "apibot",
	icon_emoji: (process.env.DEV) ? ":bug:" : ":bee:"
};

// Display variables
console.log("Slack Token: " + process.env.SLACK_API_TOKEN + " | Ticketmaster Key: " + process.env.TICKETMASTER_API_KEY + " | Port: " + process.env.PORT);

function sendHelpMenu(message) {
	msgdata.attachments = [{
        "color": "#B7C9D3",
        "title": "Get this help menu",
		"text": "`\\` or `\\ help`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Count all events in the API",
		"text": "`\\ count`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Count all events sourced by Ticketmaster",
		"text": "`\\ count ticketmaster`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Count all events sourced by Universe in Great Britain",
		"text": "`\\ count universe GB`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Search events by keyword",
		"text": "`\\ search event Adele`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Get event details by ID",
		"text": "`\\ get event Z7r9jZ1AvOYAP`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Get event details by source ID",
		"text": "`\\ get:source event 1500508BE50D4ED5`",
		"mrkdwn_in": ["text"]
	}];
    web.chat.postMessage(message.channel, "Hello! I'm your <http://developer.ticketmaster.com|Ticketmaster API> assistant. Here's a few examples of what I can do:", msgdata);
}

function sendEventCard(message, url, data) {
	if (data.name) {
		var attr, ven, seg, loc = "N/A";
		if (data.classifications && data.classifications.length) {
			seg = data.classifications[0].segment.name;
		}
		if (data._embedded && data._embedded.attractions && data._embedded.attractions.length) {
			attr = "<" + data._embedded.attractions[0].url + "|" + data._embedded.attractions[0].name + ">";
		}
		if (data._embedded && data._embedded.venues && data._embedded.venues.length) {
			ven = "<" + data._embedded.venues[0].url + "|" + data._embedded.venues[0].name + ">";
			loc = data._embedded.venues[0].city.name + ", " + data._embedded.venues[0].state.stateCode + " " + data._embedded.venues[0].postalCode + "\n" + data._embedded.venues[0].country.name;

		}
		msgdata.attachments = [{
            "color": "#768692",
			"title": "<" + data.url + "|" + data.name + "> ",
			"image_url": data.images[0].url,
			"mrkdwn_in": ["text"]
    	}, {
			"color": "#768692",
			"fields": [{
				"title": "Event ID",
				"value": data.id,
				"short": true
			}, {
				"title": "Source ID",
				"value": data.source.id,
				"short": true
			}, {
				"title": "Source",
				"value": data.source.name,
				"short": true
			}, {
				"title": "Attraction",
				"value": attr,
				"short": true
			}, {
				"title": "Venues",
				"value": ven,
				"short": true
			}, {
				"title": "Segment",
				"value": seg,
				"short": true
			}, {
				"title": "Location",
				"value": loc,
				"short": true
			}, {
				"title": "Status",
				"value": (data.active) ? 'Active' : 'Inactive',
				"short": true
			}]
    	}];
		web.chat.postMessage(message.channel, "Here's the event I found: (<"+ url.replace(process.env.TICKETMASTER_API_KEY, "") + "|api call>)", msgdata);
	} else {
		web.chat.postMessage(message.channel, "Hmm, something went wrong. #BlameSylvain. Here's the API call I made: " + url.replace(process.env.TICKETMASTER_API_KEY, ""), msgdata);
	}
}

function handleRtmMessage(message) { // listening in on the messages in the channels that added me!
	if (message.type == "message" && message.text && message.text.substring(0, 1) == "\\") { // Making sure they're asking me to do something!
		console.log('Message:', message);
		msgdata.attachments = [];
		// rtm.sendMessage('...', message.channel);
		// Analyze the command
		var arr = message.text.split(' ');
		if (arr[1]) {
			switch(arr[1]) {
			case 'count':
				var url = "https://app.ticketmaster.com/discovery/v2/events.json?apikey="+ apikey +"&size=1";
				if (arr[2]) {
					url += "&source=" + arr[2];
				}
				if (arr[3]) {
					url += "&countryCode=" + arr[3];
				}
				var source = arr[2] || 'The entire marketplace';
				client.get(url, function (data) {
					if (data.page) {
						var msg = source + ' has a total of *' + data.page.totalElements + '* events';
						if (arr[3]) {
							msg += " in " + arr[3];
						}
						web.chat.postMessage(message.channel, msg, msgdata);
					} else {
						web.chat.postMessage(message.channel, "Hmm, something went wrong. #BlameSylvain. Here's the <" + url.replace(process.env.TICKETMASTER_API_KEY, "") + "|API call> I made", msgdata);
					}
				});
				break;
			case 'search':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events.json?keyword=" + arr[3] + "&view=internal&size=1&apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data._embedded.events[0]);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event ID", msgdata);
						}
						break;
					case 'attr':
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'get':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events/" + arr[3] + ".json?view=internal&apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event ID", msgdata);
						}
						break;
					case 'attr':
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'get:source':
			case 'legacy':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events/legacy/" + arr[3] + ".json?apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event source ID", msgdata);
						}
						break;
					case 'attr':
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'help':
				sendHelpMenu(message);
				break;
			case 'list:sources':
				msgdata.attachments = [{
					"color": "#768692",
					"fields": [{
						"title": "Ticketmaster",
						"value": "All Host markets",
						"short": true
					}, {
						"title": "Universe",
						"value": "All markets",
						"short": true
					}, {
						"title": "Ticketmaster Resale (TMR)",
						"value": "All markets",
						"short": true
					}, {
						"title": "FrontGate",
						"value": "All markets",
						"short": true
					}]
		    	}];
				web.chat.postMessage(message.channel, "", msgdata);
			}
		} else {
			sendHelpMenu(message);
		}
	}
}

// Start the bot!
rtm.start();
rtm.on(RTM_EVENTS.MESSAGE, handleRtmMessage);
<commit_msg>Add support for get attraction details<commit_after>// Include monitoring and alerting. This is also used to keep the dyno from idling.
require('newrelic');

// If environment variables aren't defined, load the .env file
if (!process.env.SLACK_API_TOKEN) require('dotenv').config();

//For avoidong Heroku $PORT error
var express = require('express');
var app     = express();
app.set('port', (process.env.PORT || 5000));
app.get('/', function(request, response) {
    var result = 'App is running';
    response.send(result);
}).listen(app.get('port'), function() {
    console.log('App is running, server is listening on port ', app.get('port'));
});

// Required modules
var RtmClient = require('@slack/client').RtmClient;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;
var WebClient = require('@slack/client').WebClient;
var Client = require('node-rest-client').Client;

// Global variables
var client = new Client({port: process.env.PORT});
var token = process.env.SLACK_API_TOKEN || '';
var apikey = process.env.TICKETMASTER_API_KEY || '';
var rtm = new RtmClient(token);
var web = new WebClient(token);

// Data object for the web.chat.postMessage call
var msgdata = {
	username: (process.env.DEV) ? "apibot-dev" : "apibot",
	icon_emoji: (process.env.DEV) ? ":bug:" : ":bee:"
};

// Display variables
console.log("Slack Token: " + process.env.SLACK_API_TOKEN + " | Ticketmaster Key: " + process.env.TICKETMASTER_API_KEY + " | Port: " + process.env.PORT);

function sendHelpMenu(message) {
	msgdata.attachments = [{
        "color": "#B7C9D3",
        "title": "Get this help menu",
		"text": "`\\` or `\\ help`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Count all events in the API",
		"text": "`\\ count`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Count all events sourced by Ticketmaster",
		"text": "`\\ count ticketmaster`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Count all events sourced by Universe in Great Britain",
		"text": "`\\ count universe GB`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Search events by keyword",
		"text": "`\\ search event Adele`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#768692",
        "title": "Get event details by ID",
		"text": "`\\ get event Z7r9jZ1AvOYAP`",
		"mrkdwn_in": ["text"]
	}, {
        "color": "#B7C9D3",
        "title": "Get event details by source ID",
		"text": "`\\ get:source event 1500508BE50D4ED5`",
		"mrkdwn_in": ["text"]
	}];
    web.chat.postMessage(message.channel, "Hello! I'm your <http://developer.ticketmaster.com|Ticketmaster API> assistant. Here's a few examples of what I can do:", msgdata);
}

function sendAttrCard(message, url, data) {
	if (data.name) {
		var maxWidth = 0;
		var maxWidthImageUrl = data.images[0].url;

		data.images.forEach(function(image){
			if( image.width > maxWidth) {
				maxWidth = image.width;
				maxWidthImageUrl = image.url;
			}
		});

		if( data.classifications && data.classifications.length) {
			seg = data.classifications[0].segment.name;
			genre = data.classifications[0].genre.name;
			subGenre = data.classifications[0].subGenre.name;
		}

		msgdata.attachments = [{
			"color": "#768692",
			"title": "<" + data.url + "|" + data.name + ">",
			"image_url": maxWidthImageUrl,
			"mrkdwn_in": ["text"]
		}, {
			"color": "#768692",
			"fields": [{
				"title": "Attraction ID",
				"value": data.id,
				"short": true,
			}, {
				"title": "Source",
				"value": data.source.name,
				"short": true
			}, {
				"title": "Status",
				"value": (data.active) ? 'Active' : 'Inactive',
				"short": true
			}, {
				"title": "Segment",
				"value": seg,
				"short": true
			}, {
				"title": "Genre",
				"value": genre,
				"short": true
			}, {
				"title": "Sub-genre",
				"value": subGenre,
				"short": true
			}]
		}];
		web.chat.postMessage(message.channel, "Here's the attraction I found: (<"+ url.replace(process.env.TICKETMASTER_API_KEY, "") + "|api call>)", msgdata);
	} else {
		web.chat.postMessage(message.channel, "Hmm, something went wrong. #BlameSilverFox. Here's the API call I made: " + url.replace(process.env.TICKETMASTER_API_KEY, ""), msgdata);
	}
}

function sendEventCard(message, url, data) {
	if (data.name) {
		var attr, ven, seg, loc = "N/A";
		if (data.classifications && data.classifications.length) {
			seg = data.classifications[0].segment.name;
		}
		if (data._embedded && data._embedded.attractions && data._embedded.attractions.length) {
			attr = "<" + data._embedded.attractions[0].url + "|" + data._embedded.attractions[0].name + ">";
		}
		if (data._embedded && data._embedded.venues && data._embedded.venues.length) {
			ven = "<" + data._embedded.venues[0].url + "|" + data._embedded.venues[0].name + ">";
			loc = data._embedded.venues[0].city.name + ", " + data._embedded.venues[0].state.stateCode + " " + data._embedded.venues[0].postalCode + "\n" + data._embedded.venues[0].country.name;

		}
		msgdata.attachments = [{
            "color": "#768692",
			"title": "<" + data.url + "|" + data.name + "> ",
			"image_url": data.images[0].url,
			"mrkdwn_in": ["text"]
    	}, {
			"color": "#768692",
			"fields": [{
				"title": "Event ID",
				"value": data.id,
				"short": true
			}, {
				"title": "Source ID",
				"value": data.source.id,
				"short": true
			}, {
				"title": "Source",
				"value": data.source.name,
				"short": true
			}, {
				"title": "Attraction",
				"value": attr,
				"short": true
			}, {
				"title": "Venues",
				"value": ven,
				"short": true
			}, {
				"title": "Segment",
				"value": seg,
				"short": true
			}, {
				"title": "Location",
				"value": loc,
				"short": true
			}, {
				"title": "Status",
				"value": (data.active) ? 'Active' : 'Inactive',
				"short": true
			}]
    	}];
		web.chat.postMessage(message.channel, "Here's the event I found: (<"+ url.replace(process.env.TICKETMASTER_API_KEY, "") + "|api call>)", msgdata);
	} else {
		web.chat.postMessage(message.channel, "Hmm, something went wrong. #BlameSylvain. Here's the API call I made: " + url.replace(process.env.TICKETMASTER_API_KEY, ""), msgdata);
	}
}

function handleRtmMessage(message) { // listening in on the messages in the channels that added me!
	if (message.type == "message" && message.text && message.text.substring(0, 1) == "\\") { // Making sure they're asking me to do something!
		console.log('Message:', message);
		msgdata.attachments = [];
		// rtm.sendMessage('...', message.channel);
		// Analyze the command
		var arr = message.text.split(' ');
		if (arr[1]) {
			switch(arr[1]) {
			case 'count':
				var url = "https://app.ticketmaster.com/discovery/v2/events.json?apikey="+ apikey +"&size=1";
				if (arr[2]) {
					url += "&source=" + arr[2];
				}
				if (arr[3]) {
					url += "&countryCode=" + arr[3];
				}
				var source = arr[2] || 'The entire marketplace';
				client.get(url, function (data) {
					if (data.page) {
						var msg = source + ' has a total of *' + data.page.totalElements + '* events';
						if (arr[3]) {
							msg += " in " + arr[3];
						}
						web.chat.postMessage(message.channel, msg, msgdata);
					} else {
						web.chat.postMessage(message.channel, "Hmm, something went wrong. #BlameSylvain. Here's the <" + url.replace(process.env.TICKETMASTER_API_KEY, "") + "|API call> I made", msgdata);
					}
				});
				break;
			case 'search':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events.json?keyword=" + arr[3] + "&view=internal&size=1&apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data._embedded.events[0]);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event ID", msgdata);
						}
						break;
					case 'attr':
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'get':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events/" + arr[3] + ".json?view=internal&apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event ID", msgdata);
						}
						break;
					case 'attraction':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/attractions/" + arr[3] + ".json?view=internal&apikey="+ apikey;
							client.get(url, function(data) {
								sendAttrCard(message, url, data);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the attraction ID", msgdata);
						}
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'get:source':
			case 'legacy':
				if (arr[2]) {
					switch(arr[2]) {
					case 'event':
						if (arr[3]) {
							var url = "https://app.ticketmaster.com/discovery/v2/events/legacy/" + arr[3] + ".json?apikey="+ apikey;
							client.get(url, function (data) {
								sendEventCard(message, url, data);
							});
						} else {
							web.chat.postMessage(message.channel, "I need the event source ID", msgdata);
						}
						break;
					case 'attr':
						break;
					case 'venue':
						break;
					default:
						web.chat.postMessage(message.channel, 'Not sure I know what that is :)', msgdata);
						break;
					}
				} else {
					web.chat.postMessage(message.channel, 'What do you want me to get?', msgdata);
				}
				break;
			case 'help':
				sendHelpMenu(message);
				break;
			case 'list:sources':
				msgdata.attachments = [{
					"color": "#768692",
					"fields": [{
						"title": "Ticketmaster",
						"value": "All Host markets",
						"short": true
					}, {
						"title": "Universe",
						"value": "All markets",
						"short": true
					}, {
						"title": "Ticketmaster Resale (TMR)",
						"value": "All markets",
						"short": true
					}, {
						"title": "FrontGate",
						"value": "All markets",
						"short": true
					}]
		    	}];
				web.chat.postMessage(message.channel, "", msgdata);
			}
		} else {
			sendHelpMenu(message);
		}
	}
}

// Start the bot!
rtm.start();
rtm.on(RTM_EVENTS.MESSAGE, handleRtmMessage);
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict'

const fs = require('fs')
const removeSync = require('fs-extra').removeSync
const path = require('path')
const process = require('process')
const ArgParser = require('argparse').ArgumentParser
const pretty = require('@depmap/errors')
const VERSION = require('./package.json').version

const cli = new ArgParser({
  version: VERSION,
  addHelp: true,
  description: 'depmap - dependency map'
})

cli.addArgument(['-d', '--debug'], {
  action: 'storeTrue',
  help: 'Enable debugging'
})

cli.addArgument(['-s', '--stateless'], {
  action: 'storeTrue',
  help: 'Stateless mode'
})

cli.addArgument(['-c', '--cfg'], {
  action: 'store',
  type: 'string',
  nargs: 1,
  help: 'Set configuration'
})

const cmds = cli.addSubparsers({
  title: 'Commands',
  dest: 'cmd'
})

cmds.addParser('compile', {
  help: 'Build the project once. If the build directory is present, will only update the difference'
})

cmds.addParser('watch', {
  help: 'Continuously compile the project when files are updated'
})

let cleanCmd = cmds.addParser('clean', {
  help: 'Clean up build directory and/or cache'
})

cleanCmd.addArgument('what', {
  action: 'store',
  choices: ['build', 'cache', 'all'],
  defaultValue: 'all',
  nargs: '*'
})

class Debug {
  constructor(verbose) {
    this.log = console.log
    if (!verbose) this.log = function(){}
  }

  info(msg) {
    this.log(msg)
  }

  warn(msg) {
    pretty.warn(msg)
  }

  error(err) {
    pretty.error(err)
  }
}

const args = cli.parseArgs()
const debug = new Debug(args.debug)
Promise.all([findDepmap(args), findConfig(args.config), args])
  .then(run)
  .catch(pretty.error)

function run([depmap, config, args]) {
  if (args.cmd === 'clean') clean(args.what, config)

  depmap = require(depmap)
  let map = {}
  let opts = {} ;[map, opts] = depmap.build(config)
  opts.logger = debug

  depmap.compile(map, opts, !!(args.cmd === 'compile'))
}

function findConfig(path) {
  return new Promise((resolve, reject) => {
    let cfg
    let cfgPath = 'config.js'

    if (path) cfg = loadCfg(path[0])
    else cfg = loadCfg(cfgPath)

    if (!cfg) {
      cfgPath = 'package.json'
      cfg = loadCfg(cfgPath)
      cfg = cfg.depmap ? cfg.depmap : cfg
    }

    if (!cfg) reject(new Error('No config found.'))
    else {
      debug.info(`Config loaded from: ${cfgPath}`)
      resolve(cfg)
    }
    return
  })
}

function findDepmap() {
  return new Promise((resolve, reject) => {
    const global = path.join(process.cwd(), 'node_modules/@depmap/depmap')
    fs.stat(global, (err, data) => {
      if (err) resolve('@depmap/depmap')
      resolve(global)
    })
  })
}

function clean(argument, opts) {
  let build = opts.build || 'build'
  let cache = opts.cache && opts.cache.path ? opts.cache.path : '.cache'

  console.log(argument)
  if (argument[0] === 'build') {
    removeSync(build)
    console.log(`Lets rebuild from a clean slate, ${build} has been destoryed!`)
  } else if (argument[0] === 'cache') {
    removeSync(cache)
    console.log(`Removed the old for the new, ${cache} has been removed.`)
  } else {
    removeSync(build)
    removeSync(cache)
    console.log(`All clean, ${build} and ${cache} are no more!`)
  }

  process.exit(0)
}

function loadCfg (file) {
  let cfg
  try {
    cfg = require(path.join(process.cwd(), file))
  } catch (e) {
    cfg = undefined
  }

  return cfg
}

<commit_msg>remove console.log, add debug info<commit_after>#!/usr/bin/env node

'use strict'

const fs = require('fs')
const removeSync = require('fs-extra').removeSync
const path = require('path')
const process = require('process')
const ArgParser = require('argparse').ArgumentParser
const pretty = require('@depmap/errors')
const VERSION = require('./package.json').version

const cli = new ArgParser({
  version: VERSION,
  addHelp: true,
  description: 'depmap - dependency map'
})

cli.addArgument(['-d', '--debug'], {
  action: 'storeTrue',
  help: 'Enable debugging'
})

cli.addArgument(['-s', '--stateless'], {
  action: 'storeTrue',
  help: 'Stateless mode'
})

cli.addArgument(['-c', '--cfg'], {
  action: 'store',
  type: 'string',
  nargs: 1,
  help: 'Set configuration'
})

const cmds = cli.addSubparsers({
  title: 'Commands',
  dest: 'cmd'
})

cmds.addParser('compile', {
  help: 'Build the project once. If the build directory is present, will only update the difference'
})

cmds.addParser('watch', {
  help: 'Continuously compile the project when files are updated'
})

let cleanCmd = cmds.addParser('clean', {
  help: 'Clean up build directory and/or cache'
})

cleanCmd.addArgument('what', {
  action: 'store',
  choices: ['build', 'cache', 'all'],
  defaultValue: 'all',
  nargs: '*'
})

class Debug {
  constructor(verbose) {
    this.log = console.log
    if (!verbose) this.log = function(){}
  }

  info(msg) {
    this.log(msg)
  }

  warn(msg) {
    pretty.warn(msg)
  }

  error(err) {
    pretty.error(err)
  }
}

const args = cli.parseArgs()
const debug = new Debug(args.debug)
Promise.all([findDepmap(args), findConfig(args.config), args])
  .then(run)
  .catch(pretty.error)

function run([depmap, config, args]) {
  if (args.cmd === 'clean') clean(args.what, config)

  depmap = require(depmap)
  let map = {}
  let opts = {} ;[map, opts] = depmap.build(config)
  opts.logger = debug

  depmap.compile(map, opts, !!(args.cmd === 'compile'))
}

function findConfig(path) {
  return new Promise((resolve, reject) => {
    let cfg
    let cfgPath = 'config.js'

    if (path) cfg = loadCfg(path[0])
    else cfg = loadCfg(cfgPath)

    if (!cfg) {
      cfgPath = 'package.json'
      cfg = loadCfg(cfgPath)
      cfg = cfg.depmap ? cfg.depmap : cfg
    }

    if (!cfg) reject(new Error('No config found.'))
    else {
      debug.info(`Config loaded from: ${cfgPath}`)
      resolve(cfg)
    }
    return
  })
}

function findDepmap() {
  return new Promise((resolve, reject) => {
    const global = path.join(process.cwd(), 'node_modules/@depmap/depmap')
    fs.stat(global, (err, data) => {
      if (err) resolve('@depmap/depmap')
      resolve(global)
    })
  })
}

function clean(argument, opts) {
  let build = opts.build || 'build'
  let cache = opts.cache && opts.cache.path ? opts.cache.path : '.cache'

  if (argument[0] === 'build') {
    removeSync(build)
    console.log(`Lets rebuild from a clean slate, ${build} has been destoryed!`)
  } else if (argument[0] === 'cache') {
    removeSync(cache)
    console.log(`Removed the old for the new, ${cache} has been removed.`)
  } else {
    removeSync(build)
    removeSync(cache)
    console.log(`All clean, ${build} and ${cache} are no more!`)
  }

  process.exit(0)
}

function loadCfg (file) {
  let cfg
  try {
    cfg = require(path.join(process.cwd(), file))
  } catch (e) {
    debug.info(`Unable to load: ${file}`)
    debug.info(e)
    cfg = undefined
  }

  return cfg
}

<|endoftext|>