<commit_before>/**
 * Shopware 5
 * Copyright (c) shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    ProductStream
 * @version    $Id$
 * @author shopware AG
 */

//{namespace name="backend/attributes/main"}

Ext.define('Shopware.apps.Attributes.store.Table', {
    extend: 'Ext.data.Store',
    proxy: {
        type: 'ajax',
        url: '{url controller="Attributes" action="getTables"}',
        reader: { type: 'json', root: 'data' }
    },
    model: 'Shopware.apps.Attributes.model.Table'
});
<commit_msg>SW-18959 - sort attribute tables by label in backend module<commit_after>/**
 * Shopware 5
 * Copyright (c) shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    ProductStream
 * @version    $Id$
 * @author shopware AG
 */

//{namespace name="backend/attributes/main"}

Ext.define('Shopware.apps.Attributes.store.Table', {
    extend: 'Ext.data.Store',
    proxy: {
        type: 'ajax',
        url: '{url controller="Attributes" action="getTables"}',
        reader: { type: 'json', root: 'data' }
    },
    model: 'Shopware.apps.Attributes.model.Table',
    sorters: [{
        property: 'label',
        direction: 'ASC'
    }]
});
<|endoftext|>


<commit_before>'use strict';

var nodecg = {};

function Filter(extensionApi) {
    if (Filter.prototype._singletonInstance) {
        return Filter.prototype._singletonInstance;
    }
    Filter.prototype._singletonInstance = this;

    nodecg = extensionApi;
    this.wordfilter = require('./extension/wordfilter')(nodecg);
    this.emailfilter = require('./extension/emailfilter')(nodecg);
}

module.exports = function(extensionApi) { return new Filter(extensionApi) };
<commit_msg>remove redundant singleton code<commit_after>'use strict';

function Filter(nodecg) {
    this.wordfilter = require('./extension/wordfilter')(nodecg);
    this.emailfilter = require('./extension/emailfilter')(nodecg);
}

module.exports = function(nodecg) { return new Filter(nodecg) };
<|endoftext|>


<commit_before>"use strict";

// Requires
var vscode = require("vscode");
var markdownlint = require("markdownlint");
var fs = require("fs");
var path = require("path");
var packageJson = require("./package.json");

// Constants
var extensionName = packageJson.name;
var markdownlintVersion = packageJson
	.dependencies
	.markdownlint
	.replace(/[^\d.]/, "");
var configFileName = ".markdownlint.json";
var markdownLanguageId = "markdown";
var markdownlintRulesMdPrefix = "https://github.com/DavidAnson/markdownlint/blob/v";
var markdownlintRulesMdPostfix = "/doc/Rules.md";
var codeActionPrefix = "Click for more information about ";
var throttleDuration = 500;

// Variables
var outputChannel = null;
var diagnosticCollection = null;
var workspaceConfig = null;
var configMap = {};
var throttle = {
	"document": null,
	"timeout": null
};

// Writes date and message to the output channel
function outputLine (message) {
	var datePrefix = "[" + (new Date()).toLocaleTimeString() + "] ";
	outputChannel.appendLine(datePrefix + message);
}

// Returns rule configuration from nearest .markdownlint.json or workspace
function getConfig (document) {
	var dir = path.dirname(document.fileName);
	// While inside the workspace
	while (!path.relative(vscode.workspace.rootPath, dir).startsWith("..")) {
		// Use cached configuration if present
		if (configMap[dir]) {
			return configMap[dir];
		}
		if (configMap[dir] === undefined) {
			// Look for .markdownlint.json in current directory
			var configFilePath = path.join(dir, configFileName);
			if (fs.existsSync(configFilePath)) {
				outputLine("INFO: Loading custom configuration from '" + configFilePath +
					"', will override user/workspace/custom configuration for parent directory and children.");
				try {
					return (configMap[dir] = markdownlint.readConfigSync(configFilePath));
				} catch (ex) {
					outputLine("ERROR: Unable to read configuration file '" +
						configFilePath + "' (" + (ex.message || ex.toString()) + ").");
					outputChannel.show();
				}
			}
			// Remember missing or invalid file
			configMap[dir] = null;
		}
		// Move to parent directory, stop if no parent
		var parent = path.dirname(dir);
		if (dir === parent) {
			break;
		}
		dir = parent;
	}
	// Default to workspace configuration
	return workspaceConfig;
}

// Lints a Markdown document
function lint (document) {
	// Skip if not Markdown
	if (document.languageId !== markdownLanguageId) {
		return;
	}

	// Configure
	var options = {
		"strings": {
			"document": document.getText()
		},
		"config": getConfig(document),
		"resultVersion": 1
	};
	var diagnostics = [];

	// Lint and create Diagnostics
	markdownlint
		.sync(options)
		.document
		.forEach(function forResult (result) {
			var ruleName = result.ruleName;
			var ruleDescription = result.ruleDescription;
			var message = ruleName + "/" + result.ruleAlias + ": " + ruleDescription;
			if (result.errorDetail) {
				message += " [" + result.errorDetail + "]";
			}
			var range = document.lineAt(result.lineNumber - 1).range;
			if (result.errorRange) {
				var start = result.errorRange[0] - 1;
				var end = start + result.errorRange[1];
				range = range.with(range.start.with(undefined, start), range.end.with(undefined, end));
			}
			var diagnostic = new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Warning);
			diagnostic.code = markdownlintRulesMdPrefix + markdownlintVersion + markdownlintRulesMdPostfix +
				"#" + ruleName.toLowerCase();
			diagnostics.push(diagnostic);
		});

	// Publish
	diagnosticCollection.set(document.uri, diagnostics);
}

// Implements CodeActionsProvider.provideCodeActions to open info links for rules
function provideCodeActions (document, range, codeActionContext) {
	var diagnostics = codeActionContext.diagnostics || [];
	return diagnostics.map(function forDiagnostic (diagnostic) {
		return {
			"title": codeActionPrefix + diagnostic.message.substr(0, 5),
			"command": "vscode.open",
			"arguments": [ vscode.Uri.parse(diagnostic.code) ]
		};
	});
}

// Lint all open files
function lintOpenFiles () {
	(vscode.workspace.textDocuments || []).forEach(lint);
}

// Clears the map of custom configuration files and re-lints open files
function clearConfigMap () {
	configMap = {};
	lintOpenFiles();
}

// Load workspace configuration
function loadWorkspaceConfig () {
	outputLine("INFO: Loading user/workspace configuration from Visual Studio Code preferences.");
	var settings = vscode.workspace.getConfiguration(packageJson.displayName);
	workspaceConfig = settings.get("config");
	lintOpenFiles();
}

// Suppresses a pending lint for the specified document
function suppressLint (document) {
	if (throttle.timeout && (document === throttle.document)) {
		clearTimeout(throttle.timeout);
		throttle.document = null;
		throttle.timeout = null;
	}
}

// Requests a lint of the specified document
function requestLint (document) {
	suppressLint(document);
	throttle.document = document;
	throttle.timeout = setTimeout(function waitThrottleDuration () {
		// Do not use throttle.document in this function; it may have changed
		lint(document);
		suppressLint(document);
	}, throttleDuration);
}

// Handles the didChangeTextDocument event
function didChangeTextDocument (change) {
	requestLint(change.document);
}

// Handles the didCloseTextDocument event
function didCloseTextDocument (document) {
	suppressLint(document);
	diagnosticCollection.delete(document.uri);
}

function activate (context) {
	// Create OutputChannel
	outputChannel = vscode.window.createOutputChannel(extensionName);
	context.subscriptions.push(outputChannel);

	// Hook up to workspace events
	context.subscriptions.push(
		vscode.workspace.onDidOpenTextDocument(lint),
		vscode.workspace.onDidChangeTextDocument(didChangeTextDocument),
		vscode.workspace.onDidCloseTextDocument(didCloseTextDocument),
		vscode.workspace.onDidChangeConfiguration(loadWorkspaceConfig));

	// Register CodeActionsProvider
	context.subscriptions.push(
		vscode.languages.registerCodeActionsProvider(markdownLanguageId, {
			"provideCodeActions": provideCodeActions
		}));

	// Create DiagnosticCollection
	diagnosticCollection = vscode.languages.createDiagnosticCollection(extensionName);
	context.subscriptions.push(diagnosticCollection);

	// Hook up to file system changes for custom config file(s)
	if (vscode.workspace.rootPath) {
		// Use "/" instead of "\" due to bug in VS Code glob implementation
		var fileSystemWatcher = vscode.workspace.createFileSystemWatcher("**/" + configFileName);
		context.subscriptions.push(
			fileSystemWatcher,
			fileSystemWatcher.onDidCreate(clearConfigMap),
			fileSystemWatcher.onDidChange(clearConfigMap),
			fileSystemWatcher.onDidDelete(clearConfigMap));
	}

	loadWorkspaceConfig();
}

exports.activate = activate;
<commit_msg>Fix problem where linting would not happen if no folder was currently open.<commit_after>"use strict";

// Requires
var vscode = require("vscode");
var markdownlint = require("markdownlint");
var fs = require("fs");
var path = require("path");
var packageJson = require("./package.json");

// Constants
var extensionName = packageJson.name;
var markdownlintVersion = packageJson
	.dependencies
	.markdownlint
	.replace(/[^\d.]/, "");
var configFileName = ".markdownlint.json";
var markdownLanguageId = "markdown";
var markdownlintRulesMdPrefix = "https://github.com/DavidAnson/markdownlint/blob/v";
var markdownlintRulesMdPostfix = "/doc/Rules.md";
var codeActionPrefix = "Click for more information about ";
var throttleDuration = 500;

// Variables
var outputChannel = null;
var diagnosticCollection = null;
var workspaceConfig = null;
var configMap = {};
var throttle = {
	"document": null,
	"timeout": null
};

// Writes date and message to the output channel
function outputLine (message) {
	var datePrefix = "[" + (new Date()).toLocaleTimeString() + "] ";
	outputChannel.appendLine(datePrefix + message);
}

// Returns rule configuration from nearest .markdownlint.json or workspace
function getConfig (document) {
	var dir = path.dirname(document.fileName);
	// While inside the workspace
	while (vscode.workspace.rootPath && !path.relative(vscode.workspace.rootPath, dir).startsWith("..")) {
		// Use cached configuration if present
		if (configMap[dir]) {
			return configMap[dir];
		}
		if (configMap[dir] === undefined) {
			// Look for .markdownlint.json in current directory
			var configFilePath = path.join(dir, configFileName);
			if (fs.existsSync(configFilePath)) {
				outputLine("INFO: Loading custom configuration from '" + configFilePath +
					"', will override user/workspace/custom configuration for parent directory and children.");
				try {
					return (configMap[dir] = markdownlint.readConfigSync(configFilePath));
				} catch (ex) {
					outputLine("ERROR: Unable to read configuration file '" +
						configFilePath + "' (" + (ex.message || ex.toString()) + ").");
					outputChannel.show();
				}
			}
			// Remember missing or invalid file
			configMap[dir] = null;
		}
		// Move to parent directory, stop if no parent
		var parent = path.dirname(dir);
		if (dir === parent) {
			break;
		}
		dir = parent;
	}
	// Default to workspace configuration
	return workspaceConfig;
}

// Lints a Markdown document
function lint (document) {
	// Skip if not Markdown
	if (document.languageId !== markdownLanguageId) {
		return;
	}

	// Configure
	var options = {
		"strings": {
			"document": document.getText()
		},
		"config": getConfig(document),
		"resultVersion": 1
	};
	var diagnostics = [];

	// Lint and create Diagnostics
	markdownlint
		.sync(options)
		.document
		.forEach(function forResult (result) {
			var ruleName = result.ruleName;
			var ruleDescription = result.ruleDescription;
			var message = ruleName + "/" + result.ruleAlias + ": " + ruleDescription;
			if (result.errorDetail) {
				message += " [" + result.errorDetail + "]";
			}
			var range = document.lineAt(result.lineNumber - 1).range;
			if (result.errorRange) {
				var start = result.errorRange[0] - 1;
				var end = start + result.errorRange[1];
				range = range.with(range.start.with(undefined, start), range.end.with(undefined, end));
			}
			var diagnostic = new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Warning);
			diagnostic.code = markdownlintRulesMdPrefix + markdownlintVersion + markdownlintRulesMdPostfix +
				"#" + ruleName.toLowerCase();
			diagnostics.push(diagnostic);
		});

	// Publish
	diagnosticCollection.set(document.uri, diagnostics);
}

// Implements CodeActionsProvider.provideCodeActions to open info links for rules
function provideCodeActions (document, range, codeActionContext) {
	var diagnostics = codeActionContext.diagnostics || [];
	return diagnostics.map(function forDiagnostic (diagnostic) {
		return {
			"title": codeActionPrefix + diagnostic.message.substr(0, 5),
			"command": "vscode.open",
			"arguments": [ vscode.Uri.parse(diagnostic.code) ]
		};
	});
}

// Lint all open files
function lintOpenFiles () {
	(vscode.workspace.textDocuments || []).forEach(lint);
}

// Clears the map of custom configuration files and re-lints open files
function clearConfigMap () {
	configMap = {};
	lintOpenFiles();
}

// Load workspace configuration
function loadWorkspaceConfig () {
	outputLine("INFO: Loading user/workspace configuration from Visual Studio Code preferences.");
	var settings = vscode.workspace.getConfiguration(packageJson.displayName);
	workspaceConfig = settings.get("config");
	lintOpenFiles();
}

// Suppresses a pending lint for the specified document
function suppressLint (document) {
	if (throttle.timeout && (document === throttle.document)) {
		clearTimeout(throttle.timeout);
		throttle.document = null;
		throttle.timeout = null;
	}
}

// Requests a lint of the specified document
function requestLint (document) {
	suppressLint(document);
	throttle.document = document;
	throttle.timeout = setTimeout(function waitThrottleDuration () {
		// Do not use throttle.document in this function; it may have changed
		lint(document);
		suppressLint(document);
	}, throttleDuration);
}

// Handles the didChangeTextDocument event
function didChangeTextDocument (change) {
	requestLint(change.document);
}

// Handles the didCloseTextDocument event
function didCloseTextDocument (document) {
	suppressLint(document);
	diagnosticCollection.delete(document.uri);
}

function activate (context) {
	// Create OutputChannel
	outputChannel = vscode.window.createOutputChannel(extensionName);
	context.subscriptions.push(outputChannel);

	// Hook up to workspace events
	context.subscriptions.push(
		vscode.workspace.onDidOpenTextDocument(lint),
		vscode.workspace.onDidChangeTextDocument(didChangeTextDocument),
		vscode.workspace.onDidCloseTextDocument(didCloseTextDocument),
		vscode.workspace.onDidChangeConfiguration(loadWorkspaceConfig));

	// Register CodeActionsProvider
	context.subscriptions.push(
		vscode.languages.registerCodeActionsProvider(markdownLanguageId, {
			"provideCodeActions": provideCodeActions
		}));

	// Create DiagnosticCollection
	diagnosticCollection = vscode.languages.createDiagnosticCollection(extensionName);
	context.subscriptions.push(diagnosticCollection);

	// Hook up to file system changes for custom config file(s)
	if (vscode.workspace.rootPath) {
		// Use "/" instead of "\" due to bug in VS Code glob implementation
		var fileSystemWatcher = vscode.workspace.createFileSystemWatcher("**/" + configFileName);
		context.subscriptions.push(
			fileSystemWatcher,
			fileSystemWatcher.onDidCreate(clearConfigMap),
			fileSystemWatcher.onDidChange(clearConfigMap),
			fileSystemWatcher.onDidDelete(clearConfigMap));
	}

	loadWorkspaceConfig();
}

exports.activate = activate;
<|endoftext|>


<commit_before>// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
var vscode = require('vscode');
var _ = require('lodash');

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
function activate(context) {

    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "assignalign" is now active!');

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with  registerCommand
    // The commandId parameter must match the command field in package.json
    var disposable = vscode.commands.registerCommand('extension.assignAlign', function() {
        var editor = vscode.window.activeTextEditor;
        if (!editor) {
            return;
        }

        var lines = _.flatMap(editor.selections, function(s) {
            return _.range(s.start.line, s.end.line + 1).map(function(i) {
                return editor.document.lineAt(i);
            });
        });

        lines.sort(function(a,b) {
            return _.clamp(a.lineNumber - b.lineNumber, -1, 1);
        });

        lines = _.filter(lines, function findAssignment(l) {
           return _.some(['='], function hasAssignmentOperator(c) {
               var firstIndex = l.text.indexOf(c);
               return ~firstIndex ? firstIndex === l.text.lastIndexOf(c) : false;
           });
        });

        if(lines.length <= 1) {
            return;
        }

        var exp = /(\w+)\s*=/;
        var maxAssignmentIndex = -1;
        var newLines = _.map(lines, function(line) {
            return line.text.replace(exp, function(match, p1, offset, str) {
                var replacement = p1 + ' =';
                maxAssignmentIndex = Math.max(replacement.length - 1, maxAssignmentIndex);
                return replacement;
            });
        });

        newLines = _.map(newLines, function(newLine) {
            var currentIndex = newLine.indexOf('=');
            var spaceRequired = maxAssignmentIndex - currentIndex;
            var offsetAssignment = ' '.repeat(spaceRequired) + '=';
            return newLine.replace('=', offsetAssignment);
        });

        editor.edit(function(edit) {
           _.forEach(lines, function(line, index) {
             edit.replace(line.range, newLines[index]);
           });
        });
    });

    context.subscriptions.push(disposable);
}
exports.activate = activate;

// this method is called when your extension is deactivated
function deactivate() {
}
exports.deactivate = deactivate;<commit_msg>Fix assignment index arithmetic<commit_after>// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
var vscode = require('vscode');
var _ = require('lodash');

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
function activate(context) {

    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "assignalign" is now active!');

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with  registerCommand
    // The commandId parameter must match the command field in package.json
    var disposable = vscode.commands.registerCommand('extension.assignAlign', function() {
        var editor = vscode.window.activeTextEditor;
        if (!editor) {
            return;
        }

        var lines = _.flatMap(editor.selections, function(s) {
            return _.range(s.start.line, s.end.line + 1).map(function(i) {
                return editor.document.lineAt(i);
            });
        });

        lines.sort(function(a,b) {
            return _.clamp(a.lineNumber - b.lineNumber, -1, 1);
        });

        lines = _.filter(lines, function findAssignment(l) {
           return _.some(['='], function hasAssignmentOperator(c) {
               var firstIndex = l.text.indexOf(c);
               return ~firstIndex ? firstIndex === l.text.lastIndexOf(c) : false;
           });
        });

        if(lines.length <= 1) {
            return;
        }

        var exp = /(\w+)\s*=/;
        var maxAssignmentIndex = -1;
        var newLines = _.map(lines, function(line) {
            return line.text.replace(exp, function(match, p1, offset, str) {
                var replacement = p1 + ' =';
                maxAssignmentIndex = Math.max(offset + replacement.length - 1, maxAssignmentIndex);
                return replacement;
            });
        });

        newLines = _.map(newLines, function(newLine) {
            var currentIndex = newLine.indexOf('=');
            var spaceRequired = maxAssignmentIndex - currentIndex;
            var offsetAssignment = ' '.repeat(spaceRequired) + '=';
            return newLine.replace('=', offsetAssignment);
        });

        editor.edit(function(edit) {
           _.forEach(lines, function(line, index) {
             edit.replace(line.range, newLines[index]);
           });
        });
    });

    context.subscriptions.push(disposable);
}
exports.activate = activate;

// this method is called when your extension is deactivated
function deactivate() {
}
exports.deactivate = deactivate;<|endoftext|>


<commit_before>var vscode = require('vscode');             // Contains the VS Code extensibility API.
var exec = require('child_process').exec;   // Used for executing the php-cs-fixer command
var path = require('path');                 // Used for normalizing the document's path
var open = require('open');                 // Used for opening a browser on the Github page
var tmp = require('tmp');                   // Used for creating a temporary file with a copy of the current buffer - the formatter can format this file, optionally
var fs = require('fs');                     // Used for reading and writing the temporary file

// This method is called when your extension is activated.
// Your extension is activated the very first time the command is executed.
function activate(context) {
    var config = vscode.workspace.getConfiguration('phpformatter');

    tmp.setGracefulCleanup();

    // Not supported until https://github.com/Microsoft/vscode/issues/239 is implemented.
    // var saveCommand = vscode.workspace.onDidSaveTextDocument(function(document) {
    //     if(config.get('onSave', false) == false) {
    //         return;
    //     }
    //     fix(document);
    // });
    var fixCommand = vscode.commands.registerCommand('phpformatter.fix', function() {
        fix(vscode.window.activeTextEditor.document);
    });

    if( config.get('notifications', false) &&       // Check whether we are allowed to show notifications
        config.get('pharPath', '') == '' &&         // Did the user not set a .phar path?
        config.get('composer', false) == false      // Did the user not set composer to true?
        ) {
        // If we arrive here, then we can safely say the user has not set up the extension yet. So let's notify them about that.

        // Create a button that opens browser with the Github page at the installation guide anchor
        var guideButton = {
            'title': 'Guide',
            'slug': 'open-guide',
            'action': function() {
                open('https://github.com/Dickurt/vscode-php-formatter#installation-guide');
            }
        };

        // Show a notification to the user with the button that opens a browser
        vscode.window.showInformationMessage('Thanks for using PHP Formatter! There is still some setting up to do, however.', guideButton)
            .then(function(selection) {
                if(selection && selection.hasOwnProperty('slug') && selection.slug == 'open-guide') {
                    selection.action();
                }
            });
    }

    // context.subscriptions.push(saveCommand);
    context.subscriptions.push(fixCommand);
}

function fix(document) {
    // Makes our code a little more readable
    var config = vscode.workspace.getConfiguration('phpformatter');
    var _settings = {};
    _settings.pharPath = config.get('pharPath', '');
    _settings.phpPath = config.get('phpPath', '');
    _settings.composer = config.get('composer', false);
    _settings.onSave = config.get('onSave', false);
    _settings.level = config.get('level', '');
    _settings.fixers = config.get('fixers', '');
    _settings.additionalExtensions = config.get('additionalExtensions', []);
    _settings.useTempFiles = config.get('useTempFiles', false);
    _settings.notifications = config.get('notifications', false);

    if(document.languageId != 'php') {
        if(Array.isArray(_settings.additionalExtensions) && _settings.additionalExtensions.indexOf(document.languageId) != -1) {
            logDebug('File is in additionalExtensions array, continuing...');
        } else {
            logDebug('This is neither a .php file, nor anything that was set in additionalExtensions. Aborting...');
            return;
        }
    }

    var args = ['fix'];

    var filePath = path.normalize(document.uri.fsPath);

    var selection = false;
    if(!vscode.window.activeTextEditor.selection.isEmpty) {
        sel = vscode.window.activeTextEditor.selection;
        selection = new vscode.Range(sel.start, sel.end);
        logDebug('User has made a selection in the document ([' + sel.start.line + ', ' + sel.start.character + '], [' + sel.end.line + ', ' + sel.end.character + ']).');
    }

    if(selection != false && _settings.useTempFiles == false) {
        if(_settings.notifications) vscode.window.showInformationMessage('Fixing current selection is only possible when the "useTempFiles" setting is on. Aborting...');
        logDebug('Fixing current selection is only possible when the "useTempFiles" setting is on. Aborting...');
        return;
    }

    var tempFile = null;
    var tempFileFd = -1;
    var prependedPhpTag = false;
    if(_settings.useTempFiles) {
        // TODO: Use document.lineCount to warn user about possibly crashing the editor because of having to write the file contents
        logDebug('Creating temp file.');

        // Create temp file
        tempFile = tmp.fileSync({prefix: 'phpfmt-'});
        tempFileFd = tempFile.fd;
        filePath = tempFile.name;

        logDebug('Tempfile fd: ' + tempFile.fd);
        logDebug('Tempfile name: ' + filePath);

        logDebug('Writing current document content to temp file. Until VSCode will have a way of querying encoding, utf8 will be used for reading and writing.');

        // Content to fix
        var fixContent = '';

        // If the user made a selection, then only copy the selected text.
        if(selection != false) {
            var selectionText = document.getText(selection);

            // If the selected text does not have a PHP opening tag, then
            // prepend one manually. Otherwise PHP-CS-Fixer will not do
            // anything at all.
            if(selectionText.indexOf('<?') == -1) {
                logDebug('No PHP opening tag found, prepending <?php to selection');
                selectionText = '<?php\n' + selectionText;
                prependedPhpTag = true;
            }

            fixContent = selectionText;
        } else {
            fixContent = document.getText();
        }

        // Write the relevant content to the temp file
        fs.writeFileSync(tempFileFd, fixContent, {encoding: 'utf8'});
    }

    // Make sure to put double quotes around our path, otherwise the command
    // (Symfony, actually) will fail when it encounters paths with spaces in them.
    var escapedPath = enquote(filePath);

    args.push(escapedPath);

    if(_settings.level) {
        args.push('--level=' + _settings.level);
    }
    if(_settings.fixers) {
        args.push('--fixers=' + _settings.fixers);
    }

    var fixCmd = '';
    if(_settings.composer) {
        // If PHP-CS-Fixer was installed using Composer, and it was added to the PATH,
        // then we don't have to prepend the command with 'php' or point to the .phar file.
        fixCmd = 'php-cs-fixer ' + args.join(' ');
    } else if(_settings.pharPath) {
        // If PHP-CS-Fixer was installed manually, then we will have to provide the full
        // .phar file path. And optionally include the php path as well.
        args.unshift(enquote(_settings.pharPath));
        fixCmd = enquote(_settings.phpPath) + ' ' + args.join(' ');
    } else {
        if(_settings.notifications) vscode.window.showInformationMessage('Neither a pharPath or use of Composer was specified. Aborting...');
        logDebug('Neither a pharPath or use of Composer was specified. Aborting...');
        return;
    }

    logDebug('Full command being executed: ' + fixCmd);

    var stdout = '';
    var stderr = '';
    var execResult = exec(fixCmd);

    execResult.stdout.on('data', function(buffer) {
        stdout += buffer.toString();
    });

    execResult.stderr.on('data', function(buffer) {
        stderr += buffer.toString();
    });

    execResult.on('close', function(code) {
        if(stdout) {
            logDebug('Logging PHP-CS-Fixer command stdout result');
            logDebug(stdout);
        }
        if(stderr) {
            logDebug('Logging PHP-CS-Fixer command stderr result');
            logDebug(stderr);
        }

        // If we are using the temp file, we'll have file reading and text
        // editing to do.
        if(_settings.useTempFiles) {
            // Read the content from the temp file. Pass the encoding as utf8,
            // because we need it to return a string (fs would return buffer
            // otherwise, see https://nodejs.org/docs/latest/api/fs.html#fs_fs_readfilesync_file_options)
            // TODO: Detect current document file encoding so we don't have to
            // assume utf8.
            logDebug('Reading temp file content.');
            // var tempFileContent = fs.readFileSync(tempFileFd, {encoding: 'utf8'}); // Not using this because the file descriptor cursor position cannot be set manually

            var tempFileContent = '';
            var readStream = fs.createReadStream(filePath, {fd: tempFileFd, start: 0});

            readStream.on('data', function(chunk) {
                tempFileContent += chunk;
            });

            readStream.on('end', function() {
                logDebug(tempFileContent);

                // If we prepended a PHP opening tag manually, we'll have to remove
                // it now, before we overwrite our document.
                if(prependedPhpTag) {
                    tempFileContent = tempFileContent.substring(6);
                    logDebug('Removed the prepended PHP opening tag from the formatted text.');
                }

                // Determine the active document's end position (last line, last character)
                var documentEndPosition = new vscode.Position(document.lineCount - 1, document.lineAt(new vscode.Position(document.lineCount - 1, 0)).range.end.character);
                var editRange = new vscode.Range(new vscode.Position(0, 0), documentEndPosition);

                // If the user made a selection, save that range so we will only
                // replace that part of code after formatting.
                if(selection != false) {
                    editRange = selection;
                }

                // Replace either all of the active document's content with that of
                // the temporary file, or, in case there is a selection, replace
                // only the part that the user selected.
                logDebug('Replacing editor content with formatted code.');
                var textEditResult = vscode.window.activeTextEditor.edit(function(textEditorEdit) {
                    textEditorEdit.replace(editRange, tempFileContent);
                });

                textEditResult.then(function(success) {
                    if(success) {
                        logDebug('Document successfully formatted (' + document.lineCount + ' lines).');
                    } else {
                        logDebug('Document failed to format (' + document.lineCount + ' lines) [from success promise].');
                    }
                }, function(reason) {
                    logDebug('Document failed to format (' + document.lineCount + ' lines) [from reason promise].');
                });

                // tempFile.removeCallback();
            });
        } else {
            // Reopen the window. Since the file is edited externally,
            // the text editor's buffer is not aware of the changes made to the file.
            logDebug('Closing active editor.');
            vscode.commands.executeCommand('workbench.action.closeActiveEditor');
            logDebug('Reopening editor.');
            vscode.window.showTextDocument(document);
        }

        return;
    });
}

// Puts quotes around the given string and returns the resulting string.
function enquote(input) {
    return '"' + input + '"';
}

// Logs a message to the console if the phpformatter.logging setting is set to true.
function logDebug(message) {
    if( vscode.workspace.getConfiguration('phpformatter').get('enableFixerLogging', false) == true || // enableFixerLogging is deprecated in favor of phpformatter.logging.
        vscode.workspace.getConfiguration('phpformatter').get('logging', false) == true) {
        console.log('PHPFormatter: ' + message);
    }
}

exports.activate = activate;

// This method is called when the extension is deactivated.
function deactivate() {
}
exports.deactivate = deactivate;
<commit_msg>Reorganized code to improve readability.<commit_after>var vscode = require('vscode');             // Contains the VS Code extensibility API.
var exec = require('child_process').exec;   // Used for executing the php-cs-fixer command
var path = require('path');                 // Used for normalizing the document's path
var open = require('open');                 // Used for opening a browser on the Github page
var tmp = require('tmp');                   // Used for creating a temporary file with a copy of the current buffer - the formatter can format this file, optionally
var fs = require('fs');                     // Used for reading and writing the temporary file

// This method is called when your extension is activated.
// Your extension is activated the very first time the command is executed.
function activate(context) {
    var config = vscode.workspace.getConfiguration('phpformatter');

    tmp.setGracefulCleanup();

    // Not supported until https://github.com/Microsoft/vscode/issues/239 is implemented.
    // var saveCommand = vscode.workspace.onDidSaveTextDocument(function(document) {
    //     if(config.get('onSave', false) == false) {
    //         return;
    //     }
    //     fix(document);
    // });
    var fixCommand = vscode.commands.registerCommand('phpformatter.fix', function() {
        fix(vscode.window.activeTextEditor.document);
    });

    if( config.get('notifications', false) &&       // Check whether we are allowed to show notifications
        config.get('pharPath', '') == '' &&         // Did the user not set a .phar path?
        config.get('composer', false) == false      // Did the user not set composer to true?
        ) {
        // If we arrive here, then we can safely say the user has not set up the extension yet. So let's notify them about that.

        // Create a button that opens browser with the Github page at the installation guide anchor
        var guideButton = {
            'title': 'Guide',
            'slug': 'open-guide',
            'action': function() {
                open('https://github.com/Dickurt/vscode-php-formatter#installation-guide');
            }
        };

        // Show a notification to the user with the button that opens a browser
        vscode.window.showInformationMessage('Thanks for using PHP Formatter! There is still some setting up to do, however.', guideButton)
            .then(function(selection) {
                if(selection && selection.hasOwnProperty('slug') && selection.slug == 'open-guide') {
                    selection.action();
                }
            });
    }

    // context.subscriptions.push(saveCommand);
    context.subscriptions.push(fixCommand);
}

function fix(document) {
    // Makes our code a little more readable
    var config = vscode.workspace.getConfiguration('phpformatter');
    var _settings = {};
    _settings.pharPath = config.get('pharPath', '');
    _settings.phpPath = config.get('phpPath', '');
    _settings.composer = config.get('composer', false);
    _settings.onSave = config.get('onSave', false);
    _settings.level = config.get('level', '');
    _settings.fixers = config.get('fixers', '');
    _settings.additionalExtensions = config.get('additionalExtensions', []);
    _settings.useTempFiles = config.get('useTempFiles', false);
    _settings.notifications = config.get('notifications', false);

    if(document.languageId != 'php') {
        if(Array.isArray(_settings.additionalExtensions) && _settings.additionalExtensions.indexOf(document.languageId) != -1) {
            logDebug('File is in additionalExtensions array, continuing...');
        } else {
            logDebug('This is neither a .php file, nor anything that was set in additionalExtensions. Aborting...');
            return;
        }
    }

    // Variable args will represent the command string.
    // All the arguments for the command will be appended to the array,
    // so they can later be joined and delimited by spaces more easily.
    var args = ['fix'];
    var filePath = path.normalize(document.uri.fsPath);

    // Get the currently selected document text
    var selection = getSelection();
    if(selection != false) {
        logDebug('User has made a selection in the document ([' + sel.start.line + ', ' + sel.start.character + '], [' + sel.end.line + ', ' + sel.end.character + ']).');

        if(_settings.useTempFiles == false) {
            if(_settings.notifications) vscode.window.showInformationMessage('Fixing current selection is only possible when the "useTempFiles" setting is on. Aborting...');
            logDebug('Fixing current selection is only possible when the "useTempFiles" setting is on. Aborting...');
            return;
        }
    }

    // Now let's handle anything related to temp files.
    // These vars will be referenced down the road, so we instantiate them here, even if the user did not enable temp files.
    var tempFile = null;
    var tempFileFd = -1;
    var prependedPhpTag = false;

    // If the user enabled temp files, then generate one.
    if(_settings.useTempFiles) {
        createTempFile(selection);
    }

    // Make sure to put double quotes around our path, otherwise the command
    // (Symfony, actually) will fail when it encounters paths with spaces in them.
    var escapedPath = enquote(filePath);

    args.push(escapedPath);

    if(_settings.level) {
        args.push('--level=' + _settings.level);
    }
    if(_settings.fixers) {
        args.push('--fixers=' + _settings.fixers);
    }

    var fixCmd = '';
    if(_settings.composer) {
        // If PHP-CS-Fixer was installed using Composer, and it was added to the PATH,
        // then we don't have to prepend the command with 'php' or point to the .phar file.
        fixCmd = 'php-cs-fixer ' + args.join(' ');
    } else if(_settings.pharPath) {
        // If PHP-CS-Fixer was installed manually, then we will have to provide the full
        // .phar file path. And optionally include the php path as well.
        args.unshift(enquote(_settings.pharPath));
        fixCmd = enquote(_settings.phpPath) + ' ' + args.join(' ');
    } else {
        if(_settings.notifications) vscode.window.showInformationMessage('Neither a pharPath or use of Composer was specified. Aborting...');
        logDebug('Neither a pharPath or use of Composer was specified. Aborting...');
        return;
    }

    logDebug('Full command being executed: ' + fixCmd);

    var stdout = '';
    var stderr = '';
    var execResult = exec(fixCmd);

    // Output stdout of the fix command result.
    execResult.stdout.on('data', function(buffer) {
        stdout += buffer.toString();
    });

    // Output stderr of the fix command result.
    execResult.stderr.on('data', function(buffer) {
        stderr += buffer.toString();
    });

    // Handle finishing of the fix command.
    execResult.on('close', function(code) {
        if(stdout) {
            logDebug('Logging PHP-CS-Fixer command stdout result');
            logDebug(stdout);
        }
        if(stderr) {
            logDebug('Logging PHP-CS-Fixer command stderr result');
            logDebug(stderr);
        }

        // If we are using the temp file, we'll have file reading and text
        // editing to do.
        if(_settings.useTempFiles) {
            // Read the content from the temp file. Pass the encoding as utf8,
            // because we need it to return a string (fs would return buffer
            // otherwise, see https://nodejs.org/docs/latest/api/fs.html#fs_fs_readfilesync_file_options)
            // TODO: Detect current document file encoding so we don't have to
            // assume utf8.
            logDebug('Reading temp file content.');

            // This var will hold the content of the temp file. Every chunk that is read from the ReadStream
            // will be appended to this var.
            var tempFileContent = '';

            // The reason we are using fs.createReadStream() instead of simply using fs.readFileSync(),
            // is that the latter does not allow you to set the file descriptor cursor position manually.
            // Doing so is crucial, because otherwise only parts of the file will be read in many cases.
            var readStream = fs.createReadStream(filePath, {fd: tempFileFd, start: 0});

            // Read the data from the file and append it to the string builder.
            readStream.on('data', function(chunk) {
                tempFileContent += chunk;
            });

            // When EOF is reached, copy the results back to the original file.
            readStream.on('end', function() {
                logDebug(tempFileContent, selection);

                // If we prepended a PHP opening tag manually, we'll have to remove
                // it now, before we overwrite our document.
                if(prependedPhpTag) {
                    tempFileContent = tempFileContent.substring(6);
                    logDebug('Removed the prepended PHP opening tag from the formatted text.');
                }

                handleTempFileFixResults(tempFileContent);
            });
        } else {
            // Reopen the window. Since the file is edited externally,
            // the text editor's buffer is not aware of the changes made to the file.
            logDebug('Closing active editor.');
            vscode.commands.executeCommand('workbench.action.closeActiveEditor');
            logDebug('Reopening editor.');
            vscode.window.showTextDocument(document);
        }

        return;
    });
}

function createTempFile(selection) {
    // TODO: Use document.lineCount to warn user about possibly crashing the editor because of having to write the file contents
    logDebug('Creating temp file.');

    // Create temp file itself (empty).
    tempFile = tmp.fileSync({prefix: 'phpfmt-'});
    tempFileFd = tempFile.fd;
    filePath = tempFile.name;

    logDebug('Tempfile fd: ' + tempFile.fd);
    logDebug('Tempfile name: ' + filePath);

    logDebug('Writing current document content to temp file. Until VSCode will have a way of querying encoding, utf8 will be used for reading and writing.');

    // Content to fix.
    var fixContent = '';

    // If the user made a selection, then only copy the selected text.
    if(selection != false) {
        var selectionText = document.getText(selection);

        // If the selected text does not have a PHP opening tag, then
        // prepend one manually. Otherwise PHP-CS-Fixer will not do
        // anything at all.
        if(selectionText.indexOf('<?') == -1) {
            logDebug('No PHP opening tag found, prepending <?php to selection');
            selectionText = '<?php\n' + selectionText;
            prependedPhpTag = true;
        }

        fixContent = selectionText;
    } else {
        fixContent = document.getText();
    }

    // Write the relevant content to the temp file
    fs.writeFileSync(tempFileFd, fixContent, {encoding: 'utf8'});
}

function handleTempFileFixResults(tempFileContent, selection) {
    // Determine the active document's end position (last line, last character)
    var documentEndPosition = new vscode.Position(document.lineCount - 1, document.lineAt(new vscode.Position(document.lineCount - 1, 0)).range.end.character);
    var editRange = new vscode.Range(new vscode.Position(0, 0), documentEndPosition);

    // If the user made a selection, save that range so we will only
    // replace that part of code after formatting.
    if(selection != false) {
        editRange = selection;
    }

    // Replace either all of the active document's content with that of
    // the temporary file, or, in case there is a selection, replace
    // only the part that the user selected.
    logDebug('Replacing editor content with formatted code.');
    var textEditResult = vscode.window.activeTextEditor.edit(function(textEditorEdit) {
        textEditorEdit.replace(editRange, tempFileContent);
    });

    // Inform the user of the document edits.
    textEditResult.then(function(success) {
        if(success) {
            logDebug('Document successfully formatted (' + document.lineCount + ' lines).');
        } else {
            logDebug('Document failed to format (' + document.lineCount + ' lines) [from success promise].');
        }
    }, function(reason) {
        logDebug('Document failed to format (' + document.lineCount + ' lines) [from reason promise].');
    });

    // This does not work for some reason. Keeping this here as a reminder.
    // tempFile.removeCallback();
}

function getSelection() {
    var selection = false;
    if(!vscode.window.activeTextEditor.selection.isEmpty) {
        sel = vscode.window.activeTextEditor.selection;
        selection = new vscode.Range(sel.start, sel.end);
    }

    return selection;
}

// Puts quotes around the given string and returns the resulting string.
function enquote(input) {
    return '"' + input + '"';
}

// Logs a message to the console if the phpformatter.logging setting is set to true.
function logDebug(message) {
    if( vscode.workspace.getConfiguration('phpformatter').get('enableFixerLogging', false) == true || // enableFixerLogging is deprecated in favor of phpformatter.logging.
        vscode.workspace.getConfiguration('phpformatter').get('logging', false) == true) {
        console.log('PHPFormatter: ' + message);
    }
}

exports.activate = activate;

// This method is called when the extension is deactivated.
function deactivate() {
}
exports.deactivate = deactivate;
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');

/*
 * read *.<type> files at given `path',
 * return array of files and their
 * textual content
 */
exports.read = function (path, callback, opts) {

    var textFiles = {};
    var type = checkOptions(opts);

    var regex = new RegExp("\\." + type);
    var typeLen = (type.length * -1) -1;

    fs.readdir(path, function (error, files) {
        if (error) throw new Error("Error reading from path: " + path);

        for (var file = 0; file < files.length; file++) {
            if (files[file].match(regex)) {
                // load textFiles with content
                textFiles[files[file]
                  .slice(0, typeLen)] = fs.readFileSync(path
                    + '/'
                    + files[file]
                    , 'utf8');
            }
        }
        if (typeof callback === 'function') {
            callback(textFiles);
        }
    });

    /*
     * presently only checks for file extension option
     */
    function checkOptions(opts) {
        if (typeof opts === 'object') {
            for (var o in opts) {
                switch (o) {
                    case 'extension':
                        return String(opts[o]);
                        break;
                }
            }
        }
        return 'txt';
    }
}
<commit_msg>Refactoring: Fully use options object internally<commit_after>'use strict';

var fs = require('fs');

/*
 * read *.<type> files at given `path',
 * return array of files and their
 * textual content
 */
exports.read = function (path, callback, opts) {

    var textFiles = {};
    var options   = checkOptions(opts);
    var type      = options.extension;

    var regex = new RegExp("\\." + type);
    var typeLen = (type.length * -1) -1;

    fs.readdir(path, function (error, files) {
        if (error) throw new Error("Error reading from path: " + path);

        for (var file = 0; file < files.length; file++) {
            if (files[file].match(regex)) {
                // load textFiles with content
                textFiles[files[file]
                  .slice(0, typeLen)] = fs.readFileSync(path
                    + '/'
                    + files[file]
                    , 'utf8');
            }
        }
        if (typeof callback === 'function') {
            callback(textFiles);
        }
    });

    /*
     * presently only checks for file extension option
     *  TODO add capability of parsing more options
     */
    function checkOptions(opts) {

        var options = {};

        if (typeof opts === 'object') { // parse opts for recognized options
            for (var o in opts) {
                switch (o) {
                    case 'extension':
                        options.extension = String(opts[o]);
                        break;
                }
            }
        } else { // load with defaults
            options.extension = 'txt';
        }
        return options;
    }
}
<|endoftext|>


<commit_before>$(document).ready(function(){

	document.addEventListener("touchstart", function(){}, true);

    var $list = $(".editable-list");

    var listID = $list.attr('data-id');

    var userID = $list.attr('data-user_id');

    var $saveIndicator = $('#save_indicator');

    var $item_template = $('#item-template');

    var list = document.getElementById('editable-list-'+listID);

    var saving_msg = "Saving...";
    var saved_msg = "Saved.";

    if (list) {
        var sortableList = new Sortable(list, {
            handle: ".number", // Restricts sort start click/touch to the specified element
            ghostClass: "dragging",
            onUpdate: function (evt){
                reorder_list_items();
            }
        });
    }

    $(document).ready(function(){
        $('textarea.description', '.editable-list').autosize();
    });

	/*
	*
	* Show Share
	*
	*/
	$('.share').on('mouseover', function(e){

		$(this).addClass('move-right');
		$('.share-buttons ul li').addClass('move-left');

	});

	/*
	*
	* Show Save
	*
	*/
	function show_save(msg){

		$saveIndicator.fadeIn().text(msg);

	}

	/*
	*
	* Hide Save
	*
	*/
	function hide_save(){

		setTimeout(function(){
			$saveIndicator.fadeOut();
		}, 1200);

	}

	/*
	*
	* Add a list item and save it to the DB
	*
	*/
	var listCount = $('.list-item').length;

	$('#add').on('click', function(e){

        e.preventDefault();

		listCount++;

		$.ajax({
		  type: "POST",
		  url: '/list/new_item/'+listID,
		  data : {},
		  success: function(data){

              var $template = $item_template.clone();
              var $item = $template.find('li.list-item');
              var $number = $item.find('.number');
              var $description = $item.find('.description');
              $description.autosize();
              $number.html(data.orderIndex);
              $item.attr('data-id', data.id)
              $item.attr('data-order_index', data.orderIndex);
              $('.editable-list').append($item);

		  }

		});
	});

	/*
	*
	* Delete a list and remove it from the DOM
	*
	*/

	$('.delete-list').on('click', function(e){

        e.preventDefault();

        $this = $(this);

        var $container = $this.parents('li');
        var listID = $container.attr('data-id');

        var url = '/list/remove/'+listID;

        var confirmation = confirm("Are you sure you want to delete this list?");

		if(confirmation == true){

			$.ajax({
			  type: "POST",
			  url: url,
			  data : {},
			  success: function(data){
				  $container.fadeOut();
                  $container.remove();
                  show_save('List deleted.');
	              hide_save()
			  }

			});

		} else {

			show_save("That was a close one!");
			hide_save();

		}
	});

	/*
	*
	* Listen for stop in typing on title and subtitle and then call save_list()
	*
	*/
	$('.edit-list-head-wrapper').on('keyup', function(e) {

        var $this = $(this);

		var title = $this.find('.list-title').val();

		var subtitle = $this.find('.list-subtitle').val();

		var imgURL = $this.find('.list-img').val();

        if(imgURL){
            $('.bg-wrapper').css('background-image', 'url(' + imgURL + ')');
        } else {
            $('.bg-wrapper').css('background-image', 'none');
        }

		clearTimeout($.data(this, 'timer'));

		$(this).data('timer', setTimeout(function(){

			save_list(userID, listID, title, subtitle, imgURL);

		}, 300));

	});

	/*
	*
	* Take list title and save
	*
	* Communicate saved
	*
	*/
	function save_list(userID, dataID, title, subtitle, imgURL){

		show_save(saving_msg);

		$.ajax({

		  type: "POST",
		  url: '/list/save',
		  data: {
		  	'id': dataID,
		  	'title' : title,
		  	'subtitle' : subtitle,
		  	'imageURL' : imgURL
		  },
		  success: function(data) {

              show_save(saved_msg);
              hide_save();

		  }

		});

	}

	/*
	*
	* Listen for stop in typing on items and then call save_list_item()
	*
	*
	*/
	$('.list').on('keyup', '.list-item', function(e){

        var $this = $(this);

		clearTimeout($.data(this, 'timer'));
		$(this).data('timer', setTimeout(function(){

            save_list_item(listID, $this);

        }, 300));

	});

    $('.list').on('keyup', '.description', function(e) {
        $(this).trigger('autosize.resize');
    } );

	/*
	*
	* Take list item and save
	*
	* Communicate saved
	*
	*/
	function save_list_item(listID, $item){

        var title = $item.find('.item').val();

        var dataID = $item.attr('data-id');

        var desc = $item.find('.description').val();

        var orderIndex = $item.attr('data-order_index');

		show_save(saving_msg);

		$.ajax({
		  type: "POST",
		  url: 'save_item/'+listID,
		  data: {
		  	'id': dataID,
		  	'title' : title,
		  	'description' : desc,
            'orderIndex' : orderIndex
		  },
		  success: function(data){
              show_save(saved_msg);
              hide_save();
		  }
		});

	}

	/*
	*
	* Reorder the current list
	*
	*/
    function reorder_list_items()
    {
        $('.list-item', '.editable-list').each(function(index, object) {

            var $this = $(this);
            var newNum = index + 1;
            var oldNum = $this.attr('data-order_index');
            if (oldNum != newNum) {
                $this.find('.number').html(""+newNum);
                $this.attr('data-order_index', newNum);
                save_list_item(listID, $this);
            }

        });
    }

	/*
	*
	* Delete a list item and remove it from the DOM
	*
	*/

	$('.list').on('click', '.delete-list-item', function(e){

        e.preventDefault();

        $container = $(this).parents('li.list-item');

        var itemID = $container.attr('data-id');
        var url = '/list/remove_item/'+itemID;

        var confirmation = confirm("Are you sure you want to delete this item?");

		if(confirmation == true){

			show_save("Deleting item...");

			$.ajax({
			  type: "POST",
			  url: url,
			  data : {},
			  success: function(data) {
				  $container.fadeOut();
                  $container.remove();
                  reorder_list_items();

                  show_save("Item deleted.");
                  hide_save();
			  }
			});
		} else {
			show_save("Good choice!");
			hide_save();
		}
	});

	/*
	*
	* Search
	*
	*/
	$userResults = $('#user-results ul');
	$listResults = $('#list-results ul');
	$search =  $('#search');

	/*
	*
	* Listen for stop in typing on search
	*
	*
	*/

	$search.on('keyup', function(e){

        var $this = $(this);
        var keyword = $search.val();

		if( !$search.val() ){
			$userResults.empty();
			$listResults.empty();
			return;
		}

		clearTimeout($.data(this, 'timer'));
		$(this).data('timer', setTimeout(function(){

			$userResults.empty();
			$listResults.empty();

	        $.ajax({
				url: '/search/find?all=' + keyword,
				type: 'GET',
			}).done(function(response){

				var users = response.users;
				var lists = response.lists;

				var usersEmpty = false;
				var listsEmpty = false;

				if(!users.length && !lists.length){
					var html = "

Nothing Found...

";
					$listResults.append(html);
					return;
				}

				if (!users.length){
					var usersEmpty = true;
					search_print_user(user, usersEmpty);

				} else {
					for(i = 0; i < users.length && i < 6; i++){
						var user = users[i];
						search_print_user(user, usersEmpty);
					}
				}

				if (!lists.length){
					var listsEmpty = true;
					search_print_list(list, listsEmpty);
				} else {
					for(i = 0; i < lists.length && i < 8; i++){
						var list = lists[i];
						search_print_list(list, listsEmpty);
					}
				}

			})

        }, 300));

	});

	function search_print_user(user, empty){
		if(empty){
			var html = "

No user found...

";
		} else {
			var html = "

  " + user.username + "
  </li";
		}
		$userResults.append(html);
	}

	function search_print_list(list, empty){
		if(empty){
			var html = "

No lists found...

";
		} else {
			var html = "

" + list.title + "

" + list.subtitle + "

by " + list.user.username + "

";
		}

		$listResults.append(html);
	}

});<commit_msg>Fixed link in list profile url<commit_after>$(document).ready(function(){

	document.addEventListener("touchstart", function(){}, true);

    var $list = $(".editable-list");

    var listID = $list.attr('data-id');

    var userID = $list.attr('data-user_id');

    var $saveIndicator = $('#save_indicator');

    var $item_template = $('#item-template');

    var list = document.getElementById('editable-list-'+listID);

    var saving_msg = "Saving...";
    var saved_msg = "Saved.";

    if (list) {
        var sortableList = new Sortable(list, {
            handle: ".number", // Restricts sort start click/touch to the specified element
            ghostClass: "dragging",
            onUpdate: function (evt){
                reorder_list_items();
            }
        });
    }

    $(document).ready(function(){
        $('textarea.description', '.editable-list').autosize();
    });

	/*
	*
	* Show Share
	*
	*/
	$('.share').on('mouseover', function(e){

		$(this).addClass('move-right');
		$('.share-buttons ul li').addClass('move-left');

	});

	/*
	*
	* Show Save
	*
	*/
	function show_save(msg){

		$saveIndicator.fadeIn().text(msg);

	}

	/*
	*
	* Hide Save
	*
	*/
	function hide_save(){

		setTimeout(function(){
			$saveIndicator.fadeOut();
		}, 1200);

	}

	/*
	*
	* Add a list item and save it to the DB
	*
	*/
	var listCount = $('.list-item').length;

	$('#add').on('click', function(e){

        e.preventDefault();

		listCount++;

		$.ajax({
		  type: "POST",
		  url: '/list/new_item/'+listID,
		  data : {},
		  success: function(data){

              var $template = $item_template.clone();
              var $item = $template.find('li.list-item');
              var $number = $item.find('.number');
              var $description = $item.find('.description');
              $description.autosize();
              $number.html(data.orderIndex);
              $item.attr('data-id', data.id)
              $item.attr('data-order_index', data.orderIndex);
              $('.editable-list').append($item);

		  }

		});
	});

	/*
	*
	* Delete a list and remove it from the DOM
	*
	*/

	$('.delete-list').on('click', function(e){

        e.preventDefault();

        $this = $(this);

        var $container = $this.parents('li');
        var listID = $container.attr('data-id');

        var url = '/list/remove/'+listID;

        var confirmation = confirm("Are you sure you want to delete this list?");

		if(confirmation == true){

			$.ajax({
			  type: "POST",
			  url: url,
			  data : {},
			  success: function(data){
				  $container.fadeOut();
                  $container.remove();
                  show_save('List deleted.');
	              hide_save()
			  }

			});

		} else {

			show_save("That was a close one!");
			hide_save();

		}
	});

	/*
	*
	* Listen for stop in typing on title and subtitle and then call save_list()
	*
	*/
	$('.edit-list-head-wrapper').on('keyup', function(e) {

        var $this = $(this);

		var title = $this.find('.list-title').val();

		var subtitle = $this.find('.list-subtitle').val();

		var imgURL = $this.find('.list-img').val();

        if(imgURL){
            $('.bg-wrapper').css('background-image', 'url(' + imgURL + ')');
        } else {
            $('.bg-wrapper').css('background-image', 'none');
        }

		clearTimeout($.data(this, 'timer'));

		$(this).data('timer', setTimeout(function(){

			save_list(userID, listID, title, subtitle, imgURL);

		}, 300));

	});

	/*
	*
	* Take list title and save
	*
	* Communicate saved
	*
	*/
	function save_list(userID, dataID, title, subtitle, imgURL){

		show_save(saving_msg);

		$.ajax({

		  type: "POST",
		  url: '/list/save',
		  data: {
		  	'id': dataID,
		  	'title' : title,
		  	'subtitle' : subtitle,
		  	'imageURL' : imgURL
		  },
		  success: function(data) {

              show_save(saved_msg);
              hide_save();

		  }

		});

	}

	/*
	*
	* Listen for stop in typing on items and then call save_list_item()
	*
	*
	*/
	$('.list').on('keyup', '.list-item', function(e){

        var $this = $(this);

		clearTimeout($.data(this, 'timer'));
		$(this).data('timer', setTimeout(function(){

            save_list_item(listID, $this);

        }, 300));

	});

    $('.list').on('keyup', '.description', function(e) {
        $(this).trigger('autosize.resize');
    } );

	/*
	*
	* Take list item and save
	*
	* Communicate saved
	*
	*/
	function save_list_item(listID, $item){

        var title = $item.find('.item').val();

        var dataID = $item.attr('data-id');

        var desc = $item.find('.description').val();

        var orderIndex = $item.attr('data-order_index');

		show_save(saving_msg);

		$.ajax({
		  type: "POST",
		  url: 'save_item/'+listID,
		  data: {
		  	'id': dataID,
		  	'title' : title,
		  	'description' : desc,
            'orderIndex' : orderIndex
		  },
		  success: function(data){
              show_save(saved_msg);
              hide_save();
		  }
		});

	}

	/*
	*
	* Reorder the current list
	*
	*/
    function reorder_list_items()
    {
        $('.list-item', '.editable-list').each(function(index, object) {

            var $this = $(this);
            var newNum = index + 1;
            var oldNum = $this.attr('data-order_index');
            if (oldNum != newNum) {
                $this.find('.number').html(""+newNum);
                $this.attr('data-order_index', newNum);
                save_list_item(listID, $this);
            }

        });
    }

	/*
	*
	* Delete a list item and remove it from the DOM
	*
	*/

	$('.list').on('click', '.delete-list-item', function(e){

        e.preventDefault();

        $container = $(this).parents('li.list-item');

        var itemID = $container.attr('data-id');
        var url = '/list/remove_item/'+itemID;

        var confirmation = confirm("Are you sure you want to delete this item?");

		if(confirmation == true){

			show_save("Deleting item...");

			$.ajax({
			  type: "POST",
			  url: url,
			  data : {},
			  success: function(data) {
				  $container.fadeOut();
                  $container.remove();
                  reorder_list_items();

                  show_save("Item deleted.");
                  hide_save();
			  }
			});
		} else {
			show_save("Good choice!");
			hide_save();
		}
	});

	/*
	*
	* Search
	*
	*/
	$userResults = $('#user-results ul');
	$listResults = $('#list-results ul');
	$search =  $('#search');

	/*
	*
	* Listen for stop in typing on search
	*
	*
	*/

	$search.on('keyup', function(e){

        var $this = $(this);
        var keyword = $search.val();

		if( !$search.val() ){
			$userResults.empty();
			$listResults.empty();
			return;
		}

		clearTimeout($.data(this, 'timer'));
		$(this).data('timer', setTimeout(function(){

			$userResults.empty();
			$listResults.empty();

	        $.ajax({
				url: '/search/find?all=' + keyword,
				type: 'GET',
			}).done(function(response){

				var users = response.users;
				var lists = response.lists;

				var usersEmpty = false;
				var listsEmpty = false;

				if(!users.length && !lists.length){
					var html = "

Nothing Found...

";
					$listResults.append(html);
					return;
				}

				if (!users.length){
					var usersEmpty = true;
					search_print_user(user, usersEmpty);

				} else {
					for(i = 0; i < users.length && i < 6; i++){
						var user = users[i];
						search_print_user(user, usersEmpty);
					}
				}

				if (!lists.length){
					var listsEmpty = true;
					search_print_list(list, listsEmpty);
				} else {
					for(i = 0; i < lists.length && i < 8; i++){
						var list = lists[i];
						search_print_list(list, listsEmpty);
					}
				}

			})

        }, 300));

	});

	function search_print_user(user, empty){
		if(empty){
			var html = "

No user found...

";
		} else {
			var html = "

  " + user.username + "
  </li";
		}
		$userResults.append(html);
	}

	function search_print_list(list, empty){
		if(empty){
			var html = "

No lists found...

";
		} else {
			var html = "

" + list.title + "

" + list.subtitle + "

by " + list.user.username + "

";
		}

		$listResults.append(html);
	}

});<|endoftext|>


<commit_before>/* global window, document, coge*/
var coge = window.coge = (function(ns) {
    ns.utils = {
        ascending: function(a, b) {
            return a  b ? 1 : 0;
        },

        descending: function(a, b) {
            return a > b ? -1 : a < b ? 1 : 0;
        },

        open: function(link) {
            window.open(link, "_self");
        },

        shuffle: function(array) {
            var copy = array.slice(0), n = array.length, tmp, i;

            while (n) {
                i = Math.floor(Math.random() * n--);
                tmp = copy[n];
                copy[n] = copy[i];
                copy[i] = tmp;
            };

            return copy;
        },

        post: function(action, params) {
            var key,
                input,
                form = document.createElement("form");

            form.method = "post";
            form.action = action;
            form.setAttribute("target", "_blank");
            form.setAttribute("enctype", "multipart/form-data");

            for(key in params) {
                if (params.hasOwnProperty(key)) {
                    input = document.createElement("textarea");
                    input.name = key;
                    input.value = params[key];
                    form.appendChild(input);
                }
            }

            form.submit("action");
        },

        toPrettyDuration: function(seconds) {
            var fields = [
                [parseInt((seconds / 86400).toFixed(1), 10), " day"],
                [parseInt((seconds / 3600).toFixed(1), 10) % 24, " hour"],
                [parseInt(((seconds / 60) % 60).toFixed(1), 10), " minute"],
                [(seconds % 60).toFixed(2), " second"]
            ];

            return fields.filter(function(item) { return item[0] !== 0; })
                .map(function(item) {
                    var word = (item[0] > 1) ? item[1] + "s" : item[1];
                    return item[0] + word;
                })
                .join(", ");
        },

        log10: function(value) {
            return Math.log(value) / Math.log(10);
        },

        ucfirst: function(string) {
            return string.charAt(0).toUpperCase() + string.slice(1);
        },

        getURLParameters: function () { // returns object of query params
            var match,
                pl     = /\+/g,  // Regex for replacing addition symbol with a space
                search = /([^&=]+)=?([^&]*)/g,
                decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
                query  = window.location.search.substring(1);

            var urlParams = {};
            while (match = search.exec(query))
               urlParams[decode(match[1])] = decode(match[2]);
            return urlParams;
        },

        toQueryString: function(obj, prefix) { // accepts an object of query params
		    var str = [];
		    for (var p in obj) {
		        if (obj.hasOwnProperty(p)) {
		        	var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
		        	str.push(typeof v == "object" ?
		        			serialize(v, k) :
		        			encodeURIComponent(k) + "=" + encodeURIComponent(v));
		        }
		    }
		    return str.join("&");
    	},

    	objToString: function(obj) {
    	    var str = '
';
    	    for (var p in obj) {
    	        if (obj.hasOwnProperty(p)) {
    	            str += '     ' + p + ': ' + obj[p] + '
';
    	        }
    	    }
    	    return str;
    	},
    };

    return ns;
})(coge || {});
<commit_msg>Add wait_to_search<commit_after>/* global window, document, coge*/
var coge = window.coge = (function(ns) {
	var waitToSearchTimer;

    ns.utils = {
        ascending: function(a, b) {
            return a  b ? 1 : 0;
        },

        descending: function(a, b) {
            return a > b ? -1 : a < b ? 1 : 0;
        },

        open: function(link) {
            window.open(link, "_self");
        },

        shuffle: function(array) {
            var copy = array.slice(0), n = array.length, tmp, i;

            while (n) {
                i = Math.floor(Math.random() * n--);
                tmp = copy[n];
                copy[n] = copy[i];
                copy[i] = tmp;
            };

            return copy;
        },

        post: function(action, params) {
            var key,
                input,
                form = document.createElement("form");

            form.method = "post";
            form.action = action;
            form.setAttribute("target", "_blank");
            form.setAttribute("enctype", "multipart/form-data");

            for(key in params) {
                if (params.hasOwnProperty(key)) {
                    input = document.createElement("textarea");
                    input.name = key;
                    input.value = params[key];
                    form.appendChild(input);
                }
            }

            form.submit("action");
        },

        toPrettyDuration: function(seconds) {
            var fields = [
                [parseInt((seconds / 86400).toFixed(1), 10), " day"],
                [parseInt((seconds / 3600).toFixed(1), 10) % 24, " hour"],
                [parseInt(((seconds / 60) % 60).toFixed(1), 10), " minute"],
                [(seconds % 60).toFixed(2), " second"]
            ];

            return fields.filter(function(item) { return item[0] !== 0; })
                .map(function(item) {
                    var word = (item[0] > 1) ? item[1] + "s" : item[1];
                    return item[0] + word;
                })
                .join(", ");
        },

        log10: function(value) {
            return Math.log(value) / Math.log(10);
        },

        ucfirst: function(string) {
            return string.charAt(0).toUpperCase() + string.slice(1);
        },

        getURLParameters: function () { // returns object of query params
            var match,
                pl     = /\+/g,  // Regex for replacing addition symbol with a space
                search = /([^&=]+)=?([^&]*)/g,
                decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
                query  = window.location.search.substring(1);

            var urlParams = {};
            while (match = search.exec(query))
               urlParams[decode(match[1])] = decode(match[2]);
            return urlParams;
        },

        toQueryString: function(obj, prefix) { // accepts an object of query params
		    var str = [];
		    for (var p in obj) {
		        if (obj.hasOwnProperty(p)) {
		        	var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
		        	str.push(typeof v == "object" ?
		        			serialize(v, k) :
		        			encodeURIComponent(k) + "=" + encodeURIComponent(v));
		        }
		    }
		    return str.join("&");
    	},

    	objToString: function(obj) {
    	    var str = '
';
    	    for (var p in obj) {
    	        if (obj.hasOwnProperty(p)) {
    	            str += '     ' + p + ': ' + obj[p] + '
';
    	        }
    	    }
    	    return str;
    	},

    	wait_to_search: function(search_func, search_obj) {
    		if (waitToSearchTimer)
    			clearTimeout(waitToSearchTimer);

    		waitToSearchTimer = setTimeout(
    			function() {
    				search_func(search_obj.value);
    			},
    			500
    		);
    	}
    };

    return ns;
})(coge || {});
<|endoftext|>


<commit_before>const Promise = require('bluebird')
const fs = require('fs-extra')
const path = require('path')
const moment = require('moment')
const CSON = require('cson')
const { isEqual, last, padStart } = require('lodash')

const DEST = path.resolve(__dirname, '../assets/data/fcd')

// current: currentData in forms of {meta, data}
// next: data part
// if current.data different with next, bump meta's version
const getMeta = (current, next) => {
  if (isEqual(current.data, next)) {
    return current.meta
  }

  const { version } = current.meta
  const today = moment().format('YYYY/MM/DD')

  if (version.slice(0, 10) === today) {
    const v = parseInt(last(version.split('/')), 10) + 1
    return {
      ...current.meta,
      version: `${today}/${padStart(v, 2, '0')}`,
    }
  }

  return {
    ...current.meta,
    version: `${today}/01`,
  }
}

async function writeJSON(fname, data) {
  const JSON_OPTIONS = { spaces: '' }
  await fs.outputJSON(path.join(DEST, fname), data, JSON_OPTIONS)
}

async function CSON2JSON(name) {
  const data = await fs.readFile(`${name}.cson`)
  await writeJSON(`${name}.json`, CSON.parse(data))
}

async function buildData(name) {
  const current = await fs.readJSON(path.join(DEST, name))
  const data = await fs.readJSON(name)
  const meta = getMeta(current, data)
  await writeJSON(name, { meta, data })
}

async function build_meta(flist) {
  const meta = await Promise.map(flist, async fname => {
    const fpath = path.join(DEST, fname)
    const data = JSON.parse(await fs.readFile(fpath))
    return data.meta
  })
  await writeJSON('meta.json', meta)
}

;(async () => {
  await Promise.all([buildData('map.json'), buildData('shipavatar.json'), CSON2JSON('shiptag')])

  await build_meta(['map.json', 'shipavatar.json', 'shiptag.json'].sort())
})()
<commit_msg>feat: check ship tag data when building fcd<commit_after>const Promise = require('bluebird')
const fs = require('fs-extra')
const path = require('path')
const moment = require('moment')
const CSON = require('cson')
const { isEqual, last, padStart, size } = require('lodash')
const assert = require('assert')

const DEST = path.resolve(__dirname, '../assets/data/fcd')

// current: currentData in forms of {meta, data}
// next: data part
// if current.data different with next, bump meta's version
const getMeta = (current, next) => {
  if (isEqual(current.data, next)) {
    return current.meta
  }

  const { version } = current.meta
  const today = moment().format('YYYY/MM/DD')

  if (version.slice(0, 10) === today) {
    const v = parseInt(last(version.split('/')), 10) + 1
    return {
      ...current.meta,
      version: `${today}/${padStart(v, 2, '0')}`,
    }
  }

  return {
    ...current.meta,
    version: `${today}/01`,
  }
}

async function writeJSON(fname, data) {
  const JSON_OPTIONS = { spaces: '' }
  await fs.outputJSON(path.join(DEST, fname), data, JSON_OPTIONS)
}

async function CSON2JSON(name) {
  const data = await fs.readFile(`${name}.cson`)
  await writeJSON(`${name}.json`, CSON.parse(data))
}

async function buildData(name) {
  const current = await fs.readJSON(path.join(DEST, name))
  const data = await fs.readJSON(name)
  const meta = getMeta(current, data)
  await writeJSON(name, { meta, data })
}

async function build_meta(flist) {
  const meta = await Promise.map(flist, async fname => {
    const fpath = path.join(DEST, fname)
    const data = JSON.parse(await fs.readFile(fpath))
    return data.meta
  })
  await writeJSON('meta.json', meta)
}

const validateShipTag = async () => {
  const file = await fs.readFile('shiptag.cson')
  const { data } = CSON.parse(file)

  const count = size(data.mapname)

  assert(count > 0)
  assert(size(data.color) === count)
  assert(size(data.fleetname['zh-CN']) === count)
  assert(size(data.fleetname['zh-TW']) === count)
  assert(size(data.fleetname['ja-JP']) === count)
  assert(size(data.fleetname['en-US']) === count)
}

;(async () => {
  await validateShipTag()

  await Promise.all([buildData('map.json'), buildData('shipavatar.json'), CSON2JSON('shiptag')])

  await build_meta(['map.json', 'shipavatar.json', 'shiptag.json'].sort())
})()
<|endoftext|>


<commit_before>const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sheetrock = require('sheetrock');

const app = express();

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    // GET where ssl_check set to 1 from Slack
    if (req.query.ssl_check == 1) {
        return res.sendStatus(200);
    }
    return res.sendStatus(403);
});

app.get('/slack-auth', function(req, res) {
    let data = {form: {
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: req.query.code
    }};

    request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            res.redirect(process.env.THANK_YOU_REDIRECT);
        }
    });
});

app.post('/', function(req, res) {
    if (!req.body) {
        return res.sendStatus(400);
    }

    if (req.body.token == process.env.SLACK_AUTH_TOKEN) {
        console.log('req.body.text', req.body.text);

        let text = req.body.text ? req.body.text : 'excuseme';
        console.log('text', text);
        sheetrock({
            // url: "https://docs.google.com/spreadsheets/d/1QO5dyK6EgIP81SGZMlHMk8xn88u_budzF2Td3OoOZzY/edit#gid=0",
            url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit?usp=sharing`,
            query: `Select A where B = ${text}`,
            reset: true,
            callback: function (error, options, response) {
                console.log('>>', response.rows.cellsArray[0]);

                let donger = response.rows.cellsArray[0] ? response.rows.cellsArray[0] : 'no donger';
                var response = {
                    "response_type": "in_channel",
                    "text": donger,
                }
                res.json(response);
            }
        });
    }
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
<commit_msg>JS debug<commit_after>const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sheetrock = require('sheetrock');

const app = express();

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    // GET where ssl_check set to 1 from Slack
    if (req.query.ssl_check == 1) {
        return res.sendStatus(200);
    }
    return res.sendStatus(403);
});

app.get('/slack-auth', function(req, res) {
    let data = {form: {
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: req.query.code
    }};

    request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            res.redirect(process.env.THANK_YOU_REDIRECT);
        }
    });
});

app.post('/', function(req, res) {
    if (!req.body) {
        return res.sendStatus(400);
    }

    if (req.body.token == process.env.SLACK_AUTH_TOKEN) {

        let text = req.body.text ? req.body.text : 'excuseme';

        sheetrock({
            // url: "https://docs.google.com/spreadsheets/d/1QO5dyK6EgIP81SGZMlHMk8xn88u_budzF2Td3OoOZzY/edit#gid=0",
            url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit?usp=sharing`,
            query: `Select A where B = ${text}`,
            reset: true,
            callback: function (error, options, response) {
                console.log('>>', response);

                let donger = response.rows.cellsArray[0] ? response.rows.cellsArray[0] : 'no donger';
                var response = {
                    "response_type": "in_channel",
                    "text": donger,
                }
                res.json(response);
            }
        });
    }
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
<|endoftext|>


<commit_before><?php
/*
Copyright 2010 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

require_once("utils.php");

$gPageid = ( array_key_exists('pageid', $_GET) ? $_GET['pageid'] : "" );

$query = "select harfile, url, wptid, wptrun, onLoad, renderStart from $gPagesTable where pageid=$gPageid;";
$result = doQuery($query);
$row = mysql_fetch_assoc($result);
$harfile = $row['harfile'];
$url = $row['url'];
$wptid = $row['wptid'];
$wptrun = $row['wptrun'];
$onLoad = $row['onLoad'];
$renderStart = $row['renderStart'];

$xmlurl = "http://www.webpagetest.org/xmlResult.php?test=$wptid";
$xmlstr = file_get_contents($xmlurl);
$xml = new SimpleXMLElement($xmlstr);
$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;

$aTimes = array();
foreach($frames->frame as $frame) {
	$time = floatval($frame->time) * 1000;
	$aTimes[$time] = true;
}

$sTh = "";
$sTd = "";
$aMatches = array();
$url = "";
$pattern = '/([0-9][0-9])([0-9][0-9])([0-9][0-9])_(.*)/';
if ( preg_match($pattern, $wptid, $aMatches) ) {
	$url = "http://www.webpagetest.org/results/" . $aMatches[1] . "/" . $aMatches[2] . "/" . $aMatches[3] . "/" . $aMatches[4] . "/video_$wptrun/frame_";
}
$lastFrameTime = 0;
for ( $i = 0; $i < $onLoad; $i += 100 ) {
	$sTh .= "" . ($i/1000) . "s	 ";
	if ( array_key_exists($i, $aTimes) ) {
		$lastFrameTime = $i;
	}
	$f = "0000" . ($lastFrameTime/100);
	$f = substr($f, strlen($f)-4);
	$sTd .= "	";
}
?>

var sTh = "<?php echo $sTh ?>";
var sTd = "<?php echo $sTd ?>";
document.getElementById('videoDiv').innerHTML = "

" + sTh + "

" + sTd + "

";

var renderStart = <?php echo $renderStart ?>;
var scrollPos = (parseInt(renderStart/100))*200;
document.getElementById("videoDiv").scrollLeft = scrollPos;
<commit_msg>add gold border for paint events<commit_after><?php
/*
Copyright 2010 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

require_once("utils.php");

$gPageid = ( array_key_exists('pageid', $_GET) ? $_GET['pageid'] : "" );

$query = "select harfile, url, wptid, wptrun, onLoad, renderStart from $gPagesTable where pageid=$gPageid;";
$result = doQuery($query);
$row = mysql_fetch_assoc($result);
$harfile = $row['harfile'];
$url = $row['url'];
$wptid = $row['wptid'];
$wptrun = $row['wptrun'];
$onLoad = $row['onLoad'];
$renderStart = $row['renderStart'];

$xmlurl = "http://www.webpagetest.org/xmlResult.php?test=$wptid";
$xmlstr = file_get_contents($xmlurl);
$xml = new SimpleXMLElement($xmlstr);
$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;

$aTimes = array();
foreach($frames->frame as $frame) {
	$time = floatval($frame->time) * 1000;
	$aTimes[$time] = true;
}

$sTh = "";
$sTd = "";
$aMatches = array();
$url = "";
$pattern = '/([0-9][0-9])([0-9][0-9])([0-9][0-9])_(.*)/';
if ( preg_match($pattern, $wptid, $aMatches) ) {
	$url = "http://www.webpagetest.org/results/" . $aMatches[1] . "/" . $aMatches[2] . "/" . $aMatches[3] . "/" . $aMatches[4] . "/video_$wptrun/frame_";
}
$lastFrameTime = 0;
for ( $i = 0; $i < $onLoad; $i += 100 ) {
	$sTh .= "" . ($i/1000) . "s	 ";
	$border = "";
	if ( array_key_exists($i, $aTimes) ) {
		$lastFrameTime = $i;
		$border = "style='border: 3px solid #FEB301;'";
	}
	$f = "0000" . ($lastFrameTime/100);
	$f = substr($f, strlen($f)-4);
	$sTd .= "	";
}
?>

var sTh = "<?php echo $sTh ?>";
var sTd = "<?php echo $sTd ?>";
document.getElementById('videoDiv').innerHTML = "

" + sTh + "

" + sTd + "

";

var renderStart = <?php echo $renderStart ?>;
var scrollPos = (parseInt(renderStart/100))*200;
document.getElementById("videoDiv").scrollLeft = scrollPos;
<|endoftext|>