<commit_before>// Copyright 2018 Robert Adams
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/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.

'use strict';

import GP from 'GP';
import Config from '../config.js';

import { BItem, BItemType } from '../Items/BItem.js';

import { SpaceServerConnection } from './SpaceServer.js';
import { SpaceServerClientConnection } from './SpaceServerClient.js';
import { BasilServerConnection } from './BasilServer.js';
import { BasilClientConnection } from './BasilClient.js';
import { AliveCheckConnection } from './AliveCheckMsgs.js';
import { PestoClientConnection } from './PestoClient.js';

import { BuildBasilMessageOps } from './BasilMessageOps.js';

import { BTransportWW } from './BTransportWW.js';
import { BTransportWS } from './BTransportWS.js';
import { BTransportTest } from './BTransportTest.js';

import { CombineParameters } from '../Utilities.js';
import { BException } from '../BException.js';

export class Comm extends BItem {
    constructor() {
        GP.DebugLog('Comm: constructor');
        super('org.basil.b.comm', undefined, BItemType.COMM);
        this.layer = Config.layers ? Config.layers.comm : 'org.basil.b.layer.comm';

        this.transports = new Map();

        // Build the table of ops to names and via versa
        BuildBasilMessageOps();
    }

    Start() {
        this.SetReady();
    };

    // Make a connection to a service.
    // 'parms' is passed to the created transport/service
    ConnectTransport(parms) {
        let params = CombineParameters(undefined, parms, {
            'transportId': undefined,     // identifier for the created transport
            'transport': 'WS',            // the type of transport to connect (WW, WS, test)
            'transportURL': undefined,    // URL to connect transport to
            'waitTilTransportReadyMS': 5000  // MS before timeout waiting for transport ready
        });
        return new Promise(function(resolve, reject) {
            let xport = undefined;
            // If there is already a transport for this destination URL, return that
            if (this.transports.has(params.transportURL) {
                xport = this.transports.get(params.transportURL);
                GP.DebugLog('Comm.ConnectTransport: reusing transport ' + xport.id)
            }
            else {
                // Create a new transport to the URL
                try {
                    switch (params.transport) {
                        case 'WW':
                            xport = new BTransportWW(params);
                            break;
                        case 'WS':
                            xport = new BTransportWS(params);
                            break;
                        case 'Test':
                            xport = new BTransportTest(params);
                            break;
                        default:
                            let errorMsg = 'Comm.ConnectTransport: transport type unknown: '
                                            + JSON.stringify(params);
                            GP.ErrorLog(errorMsg);
                            reject(errorMsg);
                    }
                    this.transports.set(params.transportURL, xport);
                    GP.DebugLog('Comm.ConnectTransport: created transport ' + xport.id)
                }
                catch(e) {
                    reject('Comm.ConnectTransport: exception opening transport: ' + e.message);
                }
            }
            if (xport) {
                xport.WhenReady(params.waitTilTransportReadyMS)
                .then( xxport => {
                    resolve(xxport);
                })
                .catch( e => {
                    reject(new BException('Conn.ConnectTransport: timeout waiting for ready'));
                });
            }
            else {
                let errorMsg = 'Comm.ConnectTransport: Did not create transport: '
                                + JSON.stringify(params);
                GP.ErrorLog(errorMsg);
                reject(errorMsg);
            }
        }.bind(this));
    };

    // A misnomer as this will connect a transport to either a Pseto service or a
    //     Basil client (Creating the BasilService for this end))
    // Expects parms.service = either 'BasilServer" or 'Pesto'
    // Returns a Promise that has a handle to the created processor or undefined.
    ConnectService(pTransport, pParams) {
        let params = CombineParameters(undefined, pParams, {
            'service': 'SpaceServerClient',     // or 'Pesto'
            'serviceId': undefined,       // if not passed, unique one created
            'pestoId': undefined          // if not passed, unique one created
        });
        return new Promise(function(resolve, reject) {
            let svc = undefined;
            let serviceType = params.service;
            switch (serviceType) {
                case 'SpaceServer':
                    // This service is not used and is here for development and debugging
                    svc = new SpaceServerConnection(pTransport, params);
                    let basilSpace = new BasilClientConnection(pTransport, params);
                    let aliveSpace = new AliveCheckConnection(pTransport, params);
                    aliveSpace.Start();
                    basilSpace.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created SpaceServerConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
                case 'SpaceServerClient':
                    svc = new SpaceServerClientConnection(pTransport, params);
                    // A connection to the space server also lets the server talk to Basil
                    let basilSpaceClient = new BasilServerConnection(pTransport, params);
                    let aliveSpaceClient = new AliveCheckConnection(pTransport, params);
                    aliveSpaceClient.Start();
                    basilSpaceClient.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created SpaceServerClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              case 'Pesto':
                    svc = new PestoClientConnection(pTransport, params);
                    let basilPesto = new BasilServerConnection(pTransport, params);
                    let alivePesto = new AliveCheckConnection(pTransport, params);
                    alivePesto.Start();
                    basilPesto.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created PestoClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              case 'Broth':
                    svc = new BrothClientConnection(pTransport, params);
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created BrothClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              default:
                    let errorMsg = 'Comm.Connect: service type unknown: ' + JSON.stringify(params.service);
                    GP.ErrorLog(errorMsg)
                    reject(errorMsg)
            }
        });
    };
}
<commit_msg>Fix typo in connection processing (fixes a crash).<commit_after>// Copyright 2018 Robert Adams
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/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.

'use strict';

import GP from 'GP';
import Config from '../config.js';

import { BItem, BItemType } from '../Items/BItem.js';

import { SpaceServerConnection } from './SpaceServer.js';
import { SpaceServerClientConnection } from './SpaceServerClient.js';
import { BasilServerConnection } from './BasilServer.js';
import { BasilClientConnection } from './BasilClient.js';
import { AliveCheckConnection } from './AliveCheckMsgs.js';
import { PestoClientConnection } from './PestoClient.js';

import { BuildBasilMessageOps } from './BasilMessageOps.js';

import { BTransportWW } from './BTransportWW.js';
import { BTransportWS } from './BTransportWS.js';
import { BTransportTest } from './BTransportTest.js';

import { CombineParameters } from '../Utilities.js';
import { BException } from '../BException.js';

export class Comm extends BItem {
    constructor() {
        GP.DebugLog('Comm: constructor');
        super('org.basil.b.comm', undefined, BItemType.COMM);
        this.layer = Config.layers ? Config.layers.comm : 'org.basil.b.layer.comm';

        this.transports = new Map();

        // Build the table of ops to names and via versa
        BuildBasilMessageOps();
    }

    Start() {
        this.SetReady();
    };

    // Make a connection to a service.
    // 'parms' is passed to the created transport/service
    ConnectTransport(parms) {
        let params = CombineParameters(undefined, parms, {
            'transportId': undefined,     // identifier for the created transport
            'transport': 'WS',            // the type of transport to connect (WW, WS, test)
            'transportURL': undefined,    // URL to connect transport to
            'waitTilTransportReadyMS': 5000  // MS before timeout waiting for transport ready
        });
        return new Promise(function(resolve, reject) {
            let xport = undefined;
            // If there is already a transport for this destination URL, return that
            if (this.transports.has(params.transportURL)) {
                xport = this.transports.get(params.transportURL);
                GP.DebugLog('Comm.ConnectTransport: reusing transport ' + xport.id)
            }
            else {
                // Create a new transport to the URL
                try {
                    switch (params.transport) {
                        case 'WW':
                            xport = new BTransportWW(params);
                            break;
                        case 'WS':
                            xport = new BTransportWS(params);
                            break;
                        case 'Test':
                            xport = new BTransportTest(params);
                            break;
                        default:
                            let errorMsg = 'Comm.ConnectTransport: transport type unknown: '
                                            + JSON.stringify(params);
                            GP.ErrorLog(errorMsg);
                            reject(errorMsg);
                    }
                    this.transports.set(params.transportURL, xport);
                    GP.DebugLog('Comm.ConnectTransport: created transport ' + xport.id)
                }
                catch(e) {
                    reject('Comm.ConnectTransport: exception opening transport: ' + e.message);
                }
            }
            if (xport) {
                xport.WhenReady(params.waitTilTransportReadyMS)
                .then( xxport => {
                    resolve(xxport);
                })
                .catch( e => {
                    reject(new BException('Conn.ConnectTransport: timeout waiting for ready'));
                });
            }
            else {
                let errorMsg = 'Comm.ConnectTransport: Did not create transport: '
                                + JSON.stringify(params);
                GP.ErrorLog(errorMsg);
                reject(errorMsg);
            }
        }.bind(this));
    };

    // A misnomer as this will connect a transport to either a Pseto service or a
    //     Basil client (Creating the BasilService for this end))
    // Expects parms.service = either 'BasilServer" or 'Pesto'
    // Returns a Promise that has a handle to the created processor or undefined.
    ConnectService(pTransport, pParams) {
        let params = CombineParameters(undefined, pParams, {
            'service': 'SpaceServerClient',     // or 'Pesto'
            'serviceId': undefined,       // if not passed, unique one created
            'pestoId': undefined          // if not passed, unique one created
        });
        return new Promise(function(resolve, reject) {
            let svc = undefined;
            let serviceType = params.service;
            switch (serviceType) {
                case 'SpaceServer':
                    // This service is not used and is here for development and debugging
                    svc = new SpaceServerConnection(pTransport, params);
                    let basilSpace = new BasilClientConnection(pTransport, params);
                    let aliveSpace = new AliveCheckConnection(pTransport, params);
                    aliveSpace.Start();
                    basilSpace.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created SpaceServerConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
                case 'SpaceServerClient':
                    svc = new SpaceServerClientConnection(pTransport, params);
                    // A connection to the space server also lets the server talk to Basil
                    let basilSpaceClient = new BasilServerConnection(pTransport, params);
                    let aliveSpaceClient = new AliveCheckConnection(pTransport, params);
                    aliveSpaceClient.Start();
                    basilSpaceClient.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created SpaceServerClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              case 'Pesto':
                    svc = new PestoClientConnection(pTransport, params);
                    let basilPesto = new BasilServerConnection(pTransport, params);
                    let alivePesto = new AliveCheckConnection(pTransport, params);
                    alivePesto.Start();
                    basilPesto.Start();
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created PestoClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              case 'Broth':
                    svc = new BrothClientConnection(pTransport, params);
                    svc.Start();
                    GP.DebugLog('Comm.Connect: created BrothClientConnection. Id=' + svc.id);
                    resolve(svc);
                    break;
              default:
                    let errorMsg = 'Comm.Connect: service type unknown: ' + JSON.stringify(params.service);
                    GP.ErrorLog(errorMsg)
                    reject(errorMsg)
            }
        });
    };
}
<|endoftext|>


<commit_before>var st7735 = require('jsupm_st7735');
var lcd = new st7735.ST7735(7, 1, 9, 8);
lcd.fillScreen(st7735.ST7735_RED);
lcd.refresh();
lcd.fillScreen(st7735.ST7735_CYAN);
lcd.refresh();

lcd.fillScreen(st7735.ST7735_BLACK);
lcd.refresh();
//128 x 160 display
//lcd.Circle(64,80,50,st7735.ST7735_RED);
lcd.refresh();
function fillrectangle(x0, y0, x1, y1, color){
 var width = x1 - x0 +1;
 var height = y1 - y0 +1;

while (y0<= y1){
    lcd.drawLine(x0,y0,x1,y0,color);
    y0+=1;

}
    lcd.refresh();
    lcd.sdCSOn();

}
//fillrectangle(0,0,100,100,st7735.ST7735_RED);
var width = 128;
var height = 160;
lcd.drawcircle(width/2,height/2,50,st7735.ST7735_RED);
/*
lcd.refresh();

lcd.drawPixel(20, 20, st7735.ST7735_GREEN);
lcd.refresh();

lcd.drawTriangle(50, 50, 80, 80, 60, 90, st7735.ST7735_GREEN);
lcd.refresh();

lcd.drawCircle(100, 110, 10, st7735.ST7735_BLUE);
lcd.refresh();

lcd.setTextWrap(0x0);

lcd.setCursor(0, 30);
lcd.setTextColor(st7735.ST7735_RED, st7735.ST7735_RED);
lcd.setTextSize(1);
lcd.print('Hello World!');

lcd.setCursor(10, 50);
lcd.setTextColor(st7735.ST7735_RED, st7735.ST7735_RED);
lcd.setTextSize(2);
lcd.print('BIG');

lcd.refresh();*/
<commit_msg>fixsynta<commit_after>var st7735 = require('jsupm_st7735');
var lcd = new st7735.ST7735(7, 1, 9, 8);
lcd.fillScreen(st7735.ST7735_RED);
lcd.refresh();
lcd.fillScreen(st7735.ST7735_CYAN);
lcd.refresh();

lcd.fillScreen(st7735.ST7735_BLACK);
lcd.refresh();
//128 x 160 display
//lcd.Circle(64,80,50,st7735.ST7735_RED);
lcd.refresh();
function fillrectangle(x0, y0, x1, y1, color){
 var width = x1 - x0 +1;
 var height = y1 - y0 +1;

while (y0<= y1){
    lcd.drawLine(x0,y0,x1,y0,color);
    y0+=1;

}
    lcd.refresh();
    lcd.sdCSOn();

}
//fillrectangle(0,0,100,100,st7735.ST7735_RED);
var width = 128;
var height = 160;
lcd.drawCircle(width/2,height/2,50,st7735.ST7735_RED);
/*
lcd.refresh();

lcd.drawPixel(20, 20, st7735.ST7735_GREEN);
lcd.refresh();

lcd.drawTriangle(50, 50, 80, 80, 60, 90, st7735.ST7735_GREEN);
lcd.refresh();

lcd.drawCircle(100, 110, 10, st7735.ST7735_BLUE);
lcd.refresh();

lcd.setTextWrap(0x0);

lcd.setCursor(0, 30);
lcd.setTextColor(st7735.ST7735_RED, st7735.ST7735_RED);
lcd.setTextSize(1);
lcd.print('Hello World!');

lcd.setCursor(10, 50);
lcd.setTextColor(st7735.ST7735_RED, st7735.ST7735_RED);
lcd.setTextSize(2);
lcd.print('BIG');

lcd.refresh();*/
<|endoftext|>


<commit_before>'use strict';

var colorNarrator = new Narrator();
var colorUser = new User();
var currentPhase = 1;

colorNarrator.getGuest();
colorNarrator.popContent();
colorNarrator.popStyles();

var colorPhaseOne = new Phase(
    'Welcome to a world of color! Black and white can be very appealing, but color can also add a lot to a page. Let\'s experiment! First, choose a color for the background of your page.',
    '<input type="submit" value="Grey">',
    null,
    null,
    '<input type="submit" value="Light Blue">'
);

var colorPhaseTwo = new Phase(
    'Next, choose a color for your header.',
    '<input type="submit" value="Dark Green">',
    null,
    null,
    '<input type="submit" value="Maroon">'

);

var colorPhaseThree = new Phase(
    'Lastly, choose a color for the text in your paragraph.',
    '<input type="submit" value="Dark Blue">',
    null,
    null,
    '<input type="submit" value="Red">'
);

var colorPhaseFour = new Phase(
    'What do you think? If you\'re happy with it, submit it to see your changes, so far.',
    '<input type="submit" value="Onward!">',
    null,
    null,
    '
You\'re doing so well.
'
);
colorNarrator.popPageUser = function () {
    colorUser = this.guest;
};

var onLoadPage = function () {
    colorNarrator.talkLoc.innerText = colorPhaseOne.talkAt;
    colorNarrator.buttonOne.innerHTML = colorPhaseOne.buttonOne;
    colorNarrator.listenLocOne.innerHTML = colorPhaseOne.inputOne;
    colorNarrator.listenLocTwo.innerHTML = colorPhaseOne.inputTwo;
    colorNarrator.buttonTwo.innerHTML = colorPhaseOne.buttonTwo;
    colorNarrator.popPageUser();
};

Phase.prototype.executePhase = function () {
    colorNarrator.talkLoc.innerText = this.talkAt;
    colorNarrator.buttonOne.innerHTML = this.buttonOne;

    if (this.inputOne) {
        colorNarrator.listenLocOne.innerHTML = this.inputOne;
    }

    if (this.inputTwo) {
        colorNarrator.listenLocTwo.innerHTML = this.inputTwo;
    }

    if (this.buttonTwo) {
        colorNarrator.buttonTwo.innerHTML = this.buttonTwo;
    }
};

colorNarrator.saveGuest = function () {
    this.guest = colorUser;
};

onLoadPage();

colorPhaseOne.executePhase();

var submitButton = document.getElementById('buttonDiv');
submitButton.addEventListener('click', submitHandler);

function submitHandler() {
    event.preventDefault();
    // if (!event.target.id) {
    //     return;
    // }
    var selectedColor;
    if (currentPhase === 1 && event.target.value) {
        selectedColor = event.target.value;
        console.log(selectedColor);
        colorUser.color1 = selectedColor;
        document.getElementsByTagName('body')[0].style.backgroundColor = selectedColor;
        colorPhaseTwo.executePhase();
        currentPhase += 1;
    }
    else if (currentPhase === 2 && event.target.value) {
        selectedColor = event.target.value;
        console.log(selectedColor);
        colorUser.color2 = selectedColor;
        document.getElementsByTagName('h1')[0].style.color = selectedColor;
        colorPhaseThree.executePhase();
        currentPhase += 1;
    }
    else if (currentPhase === 3 && event.target.value) {
        selectedColor = event.target.value;
        console.log(selectedColor);
        colorUser.color3 = selectedColor;
        document.getElementsByTagName('p')[0].style.color = selectedColor;
        colorPhaseFour.executePhase();
        currentPhase += 1;
    }
    else if (currentPhase === 4 && event.target.value) {
        //save to localstorage and move to next page
        colorNarrator.saveGuest();
        colorNarrator.locallyStoreUser();
        window.location.href = './roughdraft.html';
    }
}

// var inputSpotOne = document.getElementById('inputOne');
// inputSpotOne.innerHTML = '<input type="radio" value="grey">';
<commit_msg>working on turning submitHandler into while loop<commit_after>'use strict';

var colorNarrator = new Narrator();
var colorUser = new User();
var currentPhase = 1;

colorNarrator.getGuest();
colorNarrator.popContent();
colorNarrator.popStyles();

var colorPhaseOne = new Phase(
    'Welcome to a world of color! Black and white can be very appealing, but color can also add a lot to a page. Let\'s experiment! First, choose a color for the background of your page.',
    '<input type="submit" id="actualButtonOne" value="This One!">',
    '<input type="color" id="inputFieldOne" value="#D3D3D3">',
    null,
    null
);

var colorPhaseTwo = new Phase(
    'Next, choose a color for your header.',
    '<input type="submit" id="actualButtonOne" value="This One!">',
    '<input type="color" id="inputFieldOne" value="#B03060">',
    null,
    null
);

var colorPhaseThree = new Phase(
    'Lastly, choose a color for the text in your paragraph.',
    '<input type="submit" id="actualButtonOne" value="This One!">',
    '<input type="color" id="inputFieldOne" value="#006400">',
    null,
    null
);

var colorPhaseFour = new Phase(
    'What do you think? If you\'re happy with it, submit it to see your changes, so far.',
    '<input type="submit" value="Onward!">',
    null,
    null,
    null
);
colorNarrator.popPageUser = function () {
    colorUser = this.guest;
};

var onLoadPage = function () {
    colorNarrator.talkLoc.innerText = colorPhaseOne.talkAt;
    colorNarrator.buttonOne.innerHTML = colorPhaseOne.buttonOne;
    colorNarrator.listenLocOne.innerHTML = colorPhaseOne.inputOne;
    colorNarrator.listenLocTwo.innerHTML = colorPhaseOne.inputTwo;
    colorNarrator.buttonTwo.innerHTML = colorPhaseOne.buttonTwo;
    colorNarrator.popPageUser();
};

Phase.prototype.executePhase = function () {
    colorNarrator.talkLoc.innerText = this.talkAt;
    colorNarrator.buttonOne.innerHTML = this.buttonOne;

    if (this.inputOne) {
        colorNarrator.listenLocOne.innerHTML = this.inputOne;
    }

    if (this.inputTwo) {
        colorNarrator.listenLocTwo.innerHTML = this.inputTwo;
    }

    if (this.buttonTwo) {
        colorNarrator.buttonTwo.innerHTML = this.buttonTwo;
    }
};

colorNarrator.saveGuest = function () {
    this.guest = colorUser;
};

onLoadPage();

colorPhaseOne.executePhase();

var submitButton = document.getElementById('buttonDiv');
submitButton.addEventListener('click', submitHandler);

function submitHandler() {
    event.preventDefault();
    // if (!event.target.id) {
    //     return;
    // }
    var selectedColor;
    while (currentPhase < 4 && event.target.value) {
        selectedColor = document.getElementById('inputFieldOne').value;
        console.log(selectedColor);
        if (currentPhase === 1) {
            colorUser.color1 = selectedColor;
            document.getElementsByTagName('body')[0].style.backgroundColor = selectedColor;
            currentPhase += 1;
        }
        else if (currentPhase === 2) {
            colorUser.color2 = selectedColor;
            document.getElementsByTagName('h1')[0].style.color = selectedColor;
            currentPhase += 1;
        }
        else if (currentPhase === 3) {
            colorUser.color3 = selectedColor;
            document.getElementsByTagName('p')[0].style.color = selectedColor;
            currentPhase += 1;
        }
        colorNarrator.clearThroat();
        colorPhaseTwo.executePhase();
    }
    // else if (currentPhase === 4 ) {
    //     //save to localstorage and move to next page
    //     colorNarrator.saveGuest();
    //     colorNarrator.locallyStoreUser();
    //     window.location.href = './roughdraft.html';
    // }
}

// var inputSpotOne = document.getElementById('inputOne');
// inputSpotOne.innerHTML = '<input type="radio" value="grey">';
<|endoftext|>


<commit_before>//
// File:            main.js
//
// Description:    This file defines the math mode for FoldingText. It
//                 processes the math lines using mathjs library. The
//                 library should be in the same directory as the extension.
//
// Author:        Richard A. Guay
// Author Email:  raguay@customct.com
//
define(function(require, exports, module) {
    'use strict';

    //
    // Load the libraries I need to use.
    //
    var Extensions = require('ft/core/extensions').Extensions;
    var math = require("./mathjs.js");

    //
    // Add the 'math' mode extension to the system.
    //
    Extensions.addMode({
        name: 'math'
    });

    //
    // Function:          inMathArea
    //
    // Description:       This function determines if the current node is in
    //                    a math area and is not empty.
    //
    function inMathArea(node) {
        if((node.modeContext() == "math")&&(node.text().trim()) != "") {
            return(true);
        } else {
            return(false);
        }
    };

    //
    // Function:          Calculate
    //
    // Description:       This function get the current node and the current node's
    //                    string contents. It returns the result of the calculation.
    //
    function Calculate(str) {
        var result = 0;
        try {
            //
            // Use the Mathjs library to evaluate the equation.
            //
           result = math.eval(str.substr(0,str.length-2));
        } catch(e) {
            //
            // Mathjs had a problem with the expressions. Return an ?
            //
            result = "?";
        }
        return(result);
    };

    //
    // Function:      ProcessNode
    //
    // Description:   This function is used to process a node in the math
    //                context. It expects the node to be passed to it.
    //
    function ProcessNode(node) {
        //
        // Calculate if needed. Get the text of the line.
        //
        var result = node.text();

        //
        // See if it ends in "=>". If so, process the line.
        //
        if(result.substr(-2) == "=>"){
            //
            // See if some of the previous lines had
            // variable declarations.
            //
            var loop = false;
            var pnode = node;
            do {
                //
                // Look for variable lines until reach the heading.
                //
                pnode = pnode.previousBranch();
                if(pnode.type() != "heading") {
                    //
                    // Not a heading, see if it has an evaluate command.
                    //
                    if(pnode.text().search("=>") < 0) {
                        //
                        // No evaluation, add it to the rest.
                        //
                        result = pnode.text() + "\n" + result;
                    }
                    loop = true;
                } else {
                    //
                    // Hit a header. Quit looping.
                    //
                    loop = false;
                }
            } while(loop);

            //
            // Calculate the result. If Calculate returns an array, there were
            // variables figured in as well. Just get the final result.
            //
            var cresult = Calculate(result);
            if(isArray(cresult)){
                //
                // We will get more than on answer back. Therefore,
                // just get the last result.
                //
                cresult = cresult[cresult.length-1];
            }

            //
            // Put the result together with the original line.
            //
            result = node.text() + " " + cresult;

            //
            // Update the line.
            //
            node.setText(result);
        }
    };

    //
    // Add a TreeChanged event handler to figure out when to run
    // a calculation.
    //
    Extensions.addTreeChanged(function(editor, e) {
        var deltas = e.deltas;
        for (var i = 0; i < deltas.length; i++) {
            var updatedNode = deltas[i].updatedNode,
                insertedNodes = deltas[i].insertedNodes,
                length = 0;

            length = insertedNodes.length;
            for (var j = 0; j < length; j++) {
                var each = insertedNodes[j];
                if (inMathArea(each)) {
                    ProcessNode(each);
                }
            }

            if (updatedNode) {
                //
                // It is an updated Node. Make sure it is in the math area.
                //
                if(inMathArea(updatedNode)) {
                    //
                    // It's a math node. Process it.
                    //
                    ProcessNode(updatedNode);
                }
            }
        }
    });
});
<commit_msg>Changed mode to imath and fixed the back search to not require a header.<commit_after>//
// File:            main.js
//
// Description:    This file defines the math mode for FoldingText. It
//                 processes the math lines using mathjs library. The
//                 library should be in the same directory as the extension.
//
// Author:        Richard A. Guay
// Author Email:  raguay@customct.com
//
define(function(require, exports, module) {
    'use strict';

    //
    // Load the libraries I need to use.
    //
    var Extensions = require('ft/core/extensions').Extensions;
    var math = require("./mathjs.js");

    //
    // Add the 'imath' mode extension to the system.
    //
    Extensions.addMode({
        name: 'imath'
    });

    //
    // Function:          inMathArea
    //
    // Description:       This function determines if the current node is in
    //                    a math area and is not empty.
    //
    function inMathArea(node) {
        if((node.modeContext() === 'imath')&&(node.text().trim() != "")) {
            return(true);
        } else {
            return(false);
        }
    };

    //
    // Function:          Calculate
    //
    // Description:       This function get the current node and the current node's
    //                    string contents. It returns the result of the calculation.
    //
    function Calculate(str) {
        var result = 0;
        try {
            //
            // Use the Mathjs library to evaluate the equation.
            //
           result = math.eval(str.substr(0,str.length-2));
        } catch(e) {
            //
            // Mathjs had a problem with the expressions. Return an ?
            //
            result = "?";
        }
        return(result);
    };

    //
    // Function:      ProcessNode
    //
    // Description:   This function is used to process a node in the math
    //                context. It expects the node to be passed to it.
    //
    function ProcessNode(node) {
        //
        // Calculate if needed. Get the text of the line.
        //
        var result = node.text();

        //
        // See if it ends in "=>". If so, process the line.
        //
        if(result.substr(-2) == "=>"){
            //
            // See if some of the previous lines had
            // variable declarations.
            //
            var pnode = node,
                text = "";
            while(pnode && (!pnode.mode()) && (pnode.modeContext() === 'imath')) {
                //
                // Not a heading, see if it has an evaluate command.
                //
                text = pnode.text();
                if(text.search("=>") < 0) {
                    //
                    // No evaluation, add it to the rest.
                    //
                    result = text + "\n" + result;
                }
                pnode = pnode.previousBranch();
            }

            //
            // Calculate the result. If Calculate returns an array, there were
            // variables figured in as well. Just get the final result.
            //
            var cresult = Calculate(result);
            if(isArray(cresult)){
                //
                // We will get more than on answer back. Therefore,
                // just get the last result.
                //
                cresult = cresult[cresult.length-1];
            }

            //
            // Put the result together with the original line.
            //
            result = node.text() + " " + cresult;

            //
            // Update the line.
            //
            node.setText(result);
        }
    };

    //
    // Add a TreeChanged event handler to figure out when to run
    // a calculation.
    //
    Extensions.addTreeChanged(function(editor, e) {
        var deltas = e.deltas;
        for (var i = 0; i < deltas.length; i++) {
            var updatedNode = deltas[i].updatedNode,
                insertedNodes = deltas[i].insertedNodes,
                length = 0;

            length = insertedNodes.length;
            for (var j = 0; j < length; j++) {
                var each = insertedNodes[j];
                if (inMathArea(each)) {
                    ProcessNode(each);
                }
            }

            if (updatedNode) {
                //
                // It is an updated Node. Make sure it is in the math area.
                //
                if(inMathArea(updatedNode)) {
                    //
                    // It's a math node. Process it.
                    //
                    ProcessNode(updatedNode);
                }
            }
        }
    });
});
<|endoftext|>


<commit_before>var app = require('app')
var setting = require('./module/setting')
var BrowserWindow = require('browser-window')

var window = null

// Generate default settings
setting
.default('app.startup_check_updates', true)
.default('app.startup_check_updates_delay', 100)
.default('app.startup_loadgame_delay', 100)
.default('console.blocked_commands', ['boardsize', 'clear_board', 'play', 'genmove'])
.default('console.max_history_count', 30)
.default('game.default_board_size', 19)
.default('game.default_komi', 6.5)
.default('game.show_end_after_loading', false)
.default('game.show_ko_warning', true)
.default('game.show_suicide_warning', true)
.default('graph.collapse_min_depth', 1)
.default('graph.collapse_tokens_count', 100000)
.default('graph.delay', 300)
.default('graph.grid_size', 25)
.default('graph.node_active_color', '#f76047')
.default('graph.node_collapsed_color', '#333')
.default('graph.node_inactive_color', '#777')
.default('graph.node_color', '#eee')
.default('graph.node_comment_color', '#6bb1ff')
.default('graph.node_size', 4)
.default('scoring.method', 'territory')
.default('sound.enable', true)
.default('view.comments_height', 50)
.default('view.comments_minheight', 20)
.default('view.console_width', 250)
.default('view.fuzzy_stone_placement', true)
.default('view.show_console', false)
.default('view.show_comments', false)
.default('view.show_coordinates', false)
.default('view.show_variations', true)
.default('view.show_graph', false)
.default('view.sidebar_width', 200)
.default('view.sidebar_minwidth', 100)
.default('window.height', 648)
.default('window.minheight', 590)
.default('window.minwidth', 550)
.default('window.width', 608)

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin')
        app.quit()
})

app.on('ready', function() {
    window = new BrowserWindow({
        'width': setting.get('window.width'),
        'height': setting.get('window.height'),
        'min-width': setting.get('window.minwidth'),
        'min-height': setting.get('window.minheight'),
        'use-content-size': true,
        'show': false,
        'web-preferences': {
            'text-areas-are-resizable': false
        }
    })

    // window.toggleDevTools()
    window.webContents.setAudioMuted(!setting.get('sound.enable'))

    window.on('closed', function() { window = null })
    window.webContents.on('did-finish-load', function() { window.show() })
        .on('new-window', function(e) { e.preventDefault() })

    window.loadUrl('file://' + __dirname + '/view/index.html')
})
<commit_msg>Add more blocked commands<commit_after>var app = require('app')
var setting = require('./module/setting')
var BrowserWindow = require('browser-window')

var window = null

// Generate default settings
setting
.default('app.startup_check_updates', true)
.default('app.startup_check_updates_delay', 100)
.default('app.startup_loadgame_delay', 100)
.default('console.blocked_commands', [
    'boardsize', 'clear_board', 'play',
    'genmove', 'undo', 'fixed_handicap',
    'place_free_handicap', 'set_free_handicap',
    'loadsgf'
])
.default('console.max_history_count', 30)
.default('game.default_board_size', 19)
.default('game.default_komi', 6.5)
.default('game.show_end_after_loading', false)
.default('game.show_ko_warning', true)
.default('game.show_suicide_warning', true)
.default('graph.collapse_min_depth', 1)
.default('graph.collapse_tokens_count', 100000)
.default('graph.delay', 300)
.default('graph.grid_size', 25)
.default('graph.node_active_color', '#f76047')
.default('graph.node_collapsed_color', '#333')
.default('graph.node_inactive_color', '#777')
.default('graph.node_color', '#eee')
.default('graph.node_comment_color', '#6bb1ff')
.default('graph.node_size', 4)
.default('scoring.method', 'territory')
.default('sound.enable', true)
.default('view.comments_height', 50)
.default('view.comments_minheight', 20)
.default('view.console_width', 250)
.default('view.fuzzy_stone_placement', true)
.default('view.show_console', false)
.default('view.show_comments', false)
.default('view.show_coordinates', false)
.default('view.show_variations', true)
.default('view.show_graph', false)
.default('view.sidebar_width', 200)
.default('view.sidebar_minwidth', 100)
.default('window.height', 648)
.default('window.minheight', 590)
.default('window.minwidth', 550)
.default('window.width', 608)

// Quit when all windows are closed.
app.on('window-all-closed', function() {
    if (process.platform != 'darwin')
        app.quit()
})

app.on('ready', function() {
    window = new BrowserWindow({
        'width': setting.get('window.width'),
        'height': setting.get('window.height'),
        'min-width': setting.get('window.minwidth'),
        'min-height': setting.get('window.minheight'),
        'use-content-size': true,
        'show': false,
        'web-preferences': {
            'text-areas-are-resizable': false
        }
    })

    // window.toggleDevTools()
    window.webContents.setAudioMuted(!setting.get('sound.enable'))

    window.on('closed', function() { window = null })
    window.webContents.on('did-finish-load', function() { window.show() })
        .on('new-window', function(e) { e.preventDefault() })

    window.loadUrl('file://' + __dirname + '/view/index.html')
})
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var feedparser = require('feedparser')
var request = require('request');

var feedSchema = mongoose.Schema({
    _id:              { type: String, required: true, unique: true },
    title:            String,
    description:      String,
    link:             String,
    xmlUrl:           String,
    date:             { type: Date },
    pubDate:          { type: Date },
    author:           String,
    language:         String,
    image:            { title: String, url: String },
    favicon:          String,
    copyright:        String,
    generator:        String,
    categories:       [String],
    lastModified:     String
});

feedSchema.virtual('url').get(function () {
  return this._id;
});

feedSchema.virtual('url').set(function (url) {
  this._id = url;
});

var Feed = mongoose.model('Feed', feedSchema);

var articleSchema = mongoose.Schema({
    title:            String,
    description:      String,
    link:             String,
    origLink:         String,
    date:             { type: Date },
    pubDate:          { type: Date },
    author:           String,
    guid:             String,
    comments:         String,
    image:            { title: String, url: String },
    categories:       [String],
    source:           { title: String, url: String },
    enclosures:       [{ url: String, type: String, length: String }],
    feed:             { type: String, ref: 'Feed' },
});

var Article = mongoose.model('Article', articleSchema);

var timeoutInMs = 10000;
var defaultMongoDbPort = 27017;
var updateIntervalHandle = null;

function connect(uri, database, port) {
    port = typeof port !== 'undefined' ? port : defaultMongoDbPort;
    mongoose.connect(uri, database, port);

    mongoose.connection.on('error', function(e){
        console.error("Could not connect to MongoDB: "+e.message);
        process.exit(1);
    });

    mongoose.connection.once('open', function callback () {
        console.log("Connection to MongoDB was successful.");
    });
}

function addFeed(url) {
    Feed.count({ _id: url }, function(error, count) {
        if(error != null) {
            console.error('Failed to check if feed exists in MongoDB: '+error);
        }
        else {
            if(count == 0) {
               requestAndParseFeed(url);
            }
            else if(count == 1) {
                console.warn('Feed '+url+' already exists in the MongoDB. '
                + 'Skipping database write.');
            }
            else {
                console.error('Multiple documents with same url exist in '
                + 'MongoDB. This should not happen!');
            }
        }
    });
}

function requestAndParseFeed(url) {
    var requestObject = createDefaultRequest(url);

    Feed.findOne({ _id: url }, 'lastModified', function(error,
        partialFeedDocument) {
        if(error != null) {
            console.error('Failed to get feeds Last-Modified from MongoDB: '+
                error);
        }
        else if(partialFeedDocument != null &&
            partialFeedDocument.lastModified != null) {
            requestObject.headers = { 'If-Modified-Since':
                partialFeedDocument.lastModified }
        }

        request(requestObject, function(error, response, body) {
            handleResponse(url, error, response, body)
        });
    });
}

function createDefaultRequest(url) {
    return { url: url, timeout: timeoutInMs };
}

function handleResponse(url, error, response, body) {
    if(error != null) {
        console.error('Failed to handle HTTP response: '+error);
    }
    else if (response.statusCode == 200) {
        var lastModified = getLastModifiedFromResponseHeaders(response.headers);
        feedparser.parseString(body)
        .on('meta', function(meta) { saveOrUpdateFeedMeta(meta, url,
            lastModified) })
        .on('article', function(article) { saveOrUpdateArticle(article, url) })
        .on('error', function(error) { handleParseError(error, url) });
    }
    else if (response.statusCode == 304) {
        console.log('Feed '+url+' not modified (304). Skipping parsing.' );
    }
    else {
        console.warn('HTTP status code received that can not be handled by '
            + 'this module: '+response.statusCode);
    }
}

function handleParseError(error, url) {
    console.error('Could not parse feed at '+url+'. '+error);
}

function getLastModifiedFromResponseHeaders(headers) {
    var lastModified = null;

    for(var headerName in headers){
        if(headerName.toLowerCase() == 'last-modified') {
            lastModified = headers[headerName];
        }
    }

    return lastModified;
}

function saveOrUpdateFeedMeta(meta, url, lastModified) {
    Feed.findOne({ _id: url }, function(error, feedDocument) {
        if(error != null) {
            console.error('Failed to get feed from MongoDB: '+error);
        }
        else {
            if(feedDocument == null) {
                saveFeedMeta(meta, url, lastModified);
            }
            else {
                updateFeedMeta(feedDocument, meta, url, lastModified);
            }
        }
    });
}

function saveFeedMeta(meta, url, lastModified) {
    var feedDocument = createFeedDocument(meta, url, lastModified);

    feedDocument.save(function (error, feedDocument) {
        if(error != null) {
            console.error('Failed to save feed meta to MongoDB: '+error);
        }
        else {
            console.log('Added new feed "'+feedDocument.url+'" to MongoDB.');
        }
    });
}

function updateFeedMeta(feedDocument, meta, lastModified) {
    if(feedRequiresUpdate(feedDocument, meta, lastModified)) {
        feedDocument.title = meta.title;
        feedDocument.description = meta.description;
        feedDocument.link = meta.link;
        feedDocument.xmlUrl = meta.xmlUrl;
        feedDocument.date = meta.date;
        feedDocument.pubDate = meta.pubDate;
        feedDocument.author = meta.author;
        feedDocument.language = meta.language;
        feedDocument.image = meta.image;
        feedDocument.favicon = meta.favicon;
        feedDocument.copyright = meta.copyright;
        feedDocument.generator = meta.generator;
        feedDocument.categories = meta.categories;
        feedDocument.lastModified = lastModified;

        feedDocument.save(function (error, feedDocument) {
            if(error != null) {
                console.error('Failed to update feed meta to MongoDB: '+error);
            }
            else {
                console.log('Updated feed "'+feedDocument.url+'" in MongoDB.');
            }
        });
    }
}

function feedRequiresUpdate(feedDocument, meta, lastModified) {
    var requiresUpdate = false;

    if(feedDocument.title != meta.title &&
        feedDocument.description != meta.description &&
        feedDocument.link != meta.link &&
        feedDocument.xmlUrl != meta.xmlUrl &&
        feedDocument.author != meta.author &&
        feedDocument.language != meta.language &&
        feedDocument.image.title != meta.image.title &&
        feedDocument.image.url != meta.image.url &&
        feedDocument.favicon != meta.favicon &&
        feedDocument.copyright != meta.copyright &&
        feedDocument.generator != meta.generator &&
        JSON.stringify(feedDocument.categories) !=
            JSON.stringify(meta.categories) &&
        feedDocument.lastModified != lastModified) {
        requiresUpdate = true;
    }

    return requiresUpdate;
}

function createFeedDocument(meta, url, lastModified) {
    return new Feed({ url: url, title: meta.title,
        description: meta.description, link: meta.link, xmlUrl: meta.xmlUrl,
        date: meta.date, pubDate: meta.pubDate, author: meta.author,
        language: meta.language, image: meta.image, favicon: meta.favicon,
        copyright: meta.copyright, generator: meta.generator,
        categories: meta.categories, lastModified: lastModified });
}

function saveOrUpdateArticle(article, url) {
    Article.findOne({ guid: article.guid, feed: url }, function(error, articleDocument) {
        if(error != null) {
            console.error('Failed to get article from MongoDB: '+error);
        }
        else {
            if(articleDocument == null) {
                saveArticle(article, url);
            }
            else {
                updateArticle(articleDocument, article);
            }
        }
    });
}

function saveArticle(article, url) {
    var articleDocument = createArticleDocument(article, url);

    articleDocument.save(function (error, articleDocument) {
        if(error != null) {
            console.error('Failed to save article to MongoDB: '+error);
        }
        else {
            console.log('Added new article "'+articleDocument.guid
            + '" to MongoDB.');
        }
    });
}

function updateArticle(articleDocument, article) {
    if(articleRequiresUpdate(articleDocument, article)) {
        articleDocument.title = article.title;
        articleDocument.description = article.description;
        articleDocument.link = article.link;
        articleDocument.xmlUrl = article.xmlUrl;
        articleDocument.date = article.date;
        articleDocument.pubDate = article.pubDate;
        articleDocument.author = article.author;
        articleDocument.language = article.language;
        articleDocument.image = article.image;
        articleDocument.favicon = article.favicon;
        articleDocument.copyright = article.copyright;
        articleDocument.generator = article.generator;
        articleDocument.categories = article.categories;

        articleDocument.save(function (error, feedDocument) {
            if(error != null) {
                console.error('Failed to update article to MongoDB: '+error);
            }
            else {
                console.log('Updated article "'+articleDocument.guid+'" in MongoDB.');
            }
        });
    }
}

function articleRequiresUpdate(articleDocument, article) {
    var requiresUpdate = false;

    if(articleDocument.title != article.title &&
        articleDocument.description != article.description &&
        articleDocument.link != article.link &&
        articleDocument.origLink != article.origLink &&
        articleDocument.author != article.author &&
        articleDocument.guid != article.guid &&
        articleDocument.comments != article.comments &&
        articleDocument.image.title != article.image.title &&
        articleDocument.image.url != article.image.url &&
        JSON.stringify(articleDocument.categories) !=
            JSON.stringify(article.categories) &&
        articleDocument.source.title != article.source.title &&
        articleDocument.source.url != article.source.url &&
        articleDocument.enclosures.url != article.enclosures.url &&
        articleDocument.enclosures.type != article.enclosures.type &&
        articleDocument.enclosures.length != article.enclosures.length) {
        requiresUpdate = true;
    }

    return requiresUpdate;

}

function createArticleDocument(article, url) {
    return new Article({ title: article.title,
        description: article.description, link: article.link,
        origLink: article.origLink, author: article.author, guid: article.guid,
        comments: article.comments, image: article.image,
        categories: article.categories, source: article.source,
        enclosures: article.enclosures, feed: url });
}

function updateDatabase() {
    Feed.find(function(error, feedDocuments) {
        if(error != null) {
            console.error('Failed to get feeds from MongoDB: '+error);
        }
        else {
            feedDocuments.forEach(function(feedDocument) {
                console.log('Updating feed and articles from '
                + feedDocument.url);
                requestAndParseFeed(feedDocument.url);
            });
        }
    });
}

function updateDatabaseAtInterval(seconds) {
    if(updateIntervalHandle == null) {
        updateIntervalHandle = setInterval(updateDatabase, seconds);
    }
    else {
        console.warn('Database update interval already set. Skipping.');
    }
}

function stopUpdateDataBaseAtInterval() {
    if(updateIntervalHandle != null) {
        clearInterval(updateIntervalHandle);
        updateIntervalHandle = null;
    }
}

function getArticlesByKeyword(keyword, limit, callback) {
    var searchTerm = new RegExp('.*(\\s|-)+'+keyword+'(\\s|-)+.*', 'i');

    var query = Article.find({ $or: [ { title: searchTerm }, { description:
    searchTerm }, { author: searchTerm } ] }).limit(limit);

    query.execFind(function (error, articleDocuments) {
        if(error != null) {
            console.error('Failed to get articles from MongoDB: '+error);
        }
        else {
            callback(articleDocuments);
        }
    });
}

exports.connect = connect;
exports.addFeed = addFeed;
exports.updateDatabase = updateDatabase;
exports.updateDatabaseAtInterval = updateDatabaseAtInterval;
exports.stopUpdateDataBaseAtInterval = stopUpdateDataBaseAtInterval;
exports.getArticlesByKeyword = getArticlesByKeyword;
<commit_msg>Implemented convenience function to get feeds with multiple keywords.<commit_after>var mongoose = require('mongoose');
var feedparser = require('feedparser')
var request = require('request');

var feedSchema = mongoose.Schema({
    _id:              { type: String, required: true, unique: true },
    title:            String,
    description:      String,
    link:             String,
    xmlUrl:           String,
    date:             { type: Date },
    pubDate:          { type: Date },
    author:           String,
    language:         String,
    image:            { title: String, url: String },
    favicon:          String,
    copyright:        String,
    generator:        String,
    categories:       [String],
    lastModified:     String
});

feedSchema.virtual('url').get(function () {
  return this._id;
});

feedSchema.virtual('url').set(function (url) {
  this._id = url;
});

var Feed = mongoose.model('Feed', feedSchema);

var articleSchema = mongoose.Schema({
    title:            String,
    description:      String,
    link:             String,
    origLink:         String,
    date:             { type: Date },
    pubDate:          { type: Date },
    author:           String,
    guid:             String,
    comments:         String,
    image:            { title: String, url: String },
    categories:       [String],
    source:           { title: String, url: String },
    enclosures:       [{ url: String, type: String, length: String }],
    feed:             { type: String, ref: 'Feed' },
});

var Article = mongoose.model('Article', articleSchema);

var timeoutInMs = 10000;
var defaultMongoDbPort = 27017;
var updateIntervalHandle = null;

function connect(uri, database, port) {
    port = typeof port !== 'undefined' ? port : defaultMongoDbPort;
    mongoose.connect(uri, database, port);

    mongoose.connection.on('error', function(e){
        console.error("Could not connect to MongoDB: "+e.message);
        process.exit(1);
    });

    mongoose.connection.once('open', function callback () {
        console.log("Connection to MongoDB was successful.");
    });
}

function addFeed(url) {
    Feed.count({ _id: url }, function(error, count) {
        if(error != null) {
            console.error('Failed to check if feed exists in MongoDB: '+error);
        }
        else {
            if(count == 0) {
               requestAndParseFeed(url);
            }
            else if(count == 1) {
                console.warn('Feed '+url+' already exists in the MongoDB. '
                + 'Skipping database write.');
            }
            else {
                console.error('Multiple documents with same url exist in '
                + 'MongoDB. This should not happen!');
            }
        }
    });
}

function requestAndParseFeed(url) {
    var requestObject = createDefaultRequest(url);

    Feed.findOne({ _id: url }, 'lastModified', function(error,
        partialFeedDocument) {
        if(error != null) {
            console.error('Failed to get feeds Last-Modified from MongoDB: '+
                error);
        }
        else if(partialFeedDocument != null &&
            partialFeedDocument.lastModified != null) {
            requestObject.headers = { 'If-Modified-Since':
                partialFeedDocument.lastModified }
        }

        request(requestObject, function(error, response, body) {
            handleResponse(url, error, response, body)
        });
    });
}

function createDefaultRequest(url) {
    return { url: url, timeout: timeoutInMs };
}

function handleResponse(url, error, response, body) {
    if(error != null) {
        console.error('Failed to handle HTTP response: '+error);
    }
    else if (response.statusCode == 200) {
        var lastModified = getLastModifiedFromResponseHeaders(response.headers);
        feedparser.parseString(body)
        .on('meta', function(meta) { saveOrUpdateFeedMeta(meta, url,
            lastModified) })
        .on('article', function(article) { saveOrUpdateArticle(article, url) })
        .on('error', function(error) { handleParseError(error, url) });
    }
    else if (response.statusCode == 304) {
        console.log('Feed '+url+' not modified (304). Skipping parsing.' );
    }
    else {
        console.warn('HTTP status code received that can not be handled by '
            + 'this module: '+response.statusCode);
    }
}

function handleParseError(error, url) {
    console.error('Could not parse feed at '+url+'. '+error);
}

function getLastModifiedFromResponseHeaders(headers) {
    var lastModified = null;

    for(var headerName in headers){
        if(headerName.toLowerCase() == 'last-modified') {
            lastModified = headers[headerName];
        }
    }

    return lastModified;
}

function saveOrUpdateFeedMeta(meta, url, lastModified) {
    Feed.findOne({ _id: url }, function(error, feedDocument) {
        if(error != null) {
            console.error('Failed to get feed from MongoDB: '+error);
        }
        else {
            if(feedDocument == null) {
                saveFeedMeta(meta, url, lastModified);
            }
            else {
                updateFeedMeta(feedDocument, meta, url, lastModified);
            }
        }
    });
}

function saveFeedMeta(meta, url, lastModified) {
    var feedDocument = createFeedDocument(meta, url, lastModified);

    feedDocument.save(function (error, feedDocument) {
        if(error != null) {
            console.error('Failed to save feed meta to MongoDB: '+error);
        }
        else {
            console.log('Added new feed "'+feedDocument.url+'" to MongoDB.');
        }
    });
}

function updateFeedMeta(feedDocument, meta, lastModified) {
    if(feedRequiresUpdate(feedDocument, meta, lastModified)) {
        feedDocument.title = meta.title;
        feedDocument.description = meta.description;
        feedDocument.link = meta.link;
        feedDocument.xmlUrl = meta.xmlUrl;
        feedDocument.date = meta.date;
        feedDocument.pubDate = meta.pubDate;
        feedDocument.author = meta.author;
        feedDocument.language = meta.language;
        feedDocument.image = meta.image;
        feedDocument.favicon = meta.favicon;
        feedDocument.copyright = meta.copyright;
        feedDocument.generator = meta.generator;
        feedDocument.categories = meta.categories;
        feedDocument.lastModified = lastModified;

        feedDocument.save(function (error, feedDocument) {
            if(error != null) {
                console.error('Failed to update feed meta to MongoDB: '+error);
            }
            else {
                console.log('Updated feed "'+feedDocument.url+'" in MongoDB.');
            }
        });
    }
}

function feedRequiresUpdate(feedDocument, meta, lastModified) {
    var requiresUpdate = false;

    if(feedDocument.title != meta.title &&
        feedDocument.description != meta.description &&
        feedDocument.link != meta.link &&
        feedDocument.xmlUrl != meta.xmlUrl &&
        feedDocument.author != meta.author &&
        feedDocument.language != meta.language &&
        feedDocument.image.title != meta.image.title &&
        feedDocument.image.url != meta.image.url &&
        feedDocument.favicon != meta.favicon &&
        feedDocument.copyright != meta.copyright &&
        feedDocument.generator != meta.generator &&
        JSON.stringify(feedDocument.categories) !=
            JSON.stringify(meta.categories) &&
        feedDocument.lastModified != lastModified) {
        requiresUpdate = true;
    }

    return requiresUpdate;
}

function createFeedDocument(meta, url, lastModified) {
    return new Feed({ url: url, title: meta.title,
        description: meta.description, link: meta.link, xmlUrl: meta.xmlUrl,
        date: meta.date, pubDate: meta.pubDate, author: meta.author,
        language: meta.language, image: meta.image, favicon: meta.favicon,
        copyright: meta.copyright, generator: meta.generator,
        categories: meta.categories, lastModified: lastModified });
}

function saveOrUpdateArticle(article, url) {
    Article.findOne({ guid: article.guid, feed: url }, function(error, articleDocument) {
        if(error != null) {
            console.error('Failed to get article from MongoDB: '+error);
        }
        else {
            if(articleDocument == null) {
                saveArticle(article, url);
            }
            else {
                updateArticle(articleDocument, article);
            }
        }
    });
}

function saveArticle(article, url) {
    var articleDocument = createArticleDocument(article, url);

    articleDocument.save(function (error, articleDocument) {
        if(error != null) {
            console.error('Failed to save article to MongoDB: '+error);
        }
        else {
            console.log('Added new article "'+articleDocument.guid
            + '" to MongoDB.');
        }
    });
}

function updateArticle(articleDocument, article) {
    if(articleRequiresUpdate(articleDocument, article)) {
        articleDocument.title = article.title;
        articleDocument.description = article.description;
        articleDocument.link = article.link;
        articleDocument.xmlUrl = article.xmlUrl;
        articleDocument.date = article.date;
        articleDocument.pubDate = article.pubDate;
        articleDocument.author = article.author;
        articleDocument.language = article.language;
        articleDocument.image = article.image;
        articleDocument.favicon = article.favicon;
        articleDocument.copyright = article.copyright;
        articleDocument.generator = article.generator;
        articleDocument.categories = article.categories;

        articleDocument.save(function (error, feedDocument) {
            if(error != null) {
                console.error('Failed to update article to MongoDB: '+error);
            }
            else {
                console.log('Updated article "'+articleDocument.guid+'" in MongoDB.');
            }
        });
    }
}

function articleRequiresUpdate(articleDocument, article) {
    var requiresUpdate = false;

    if(articleDocument.title != article.title &&
        articleDocument.description != article.description &&
        articleDocument.link != article.link &&
        articleDocument.origLink != article.origLink &&
        articleDocument.author != article.author &&
        articleDocument.guid != article.guid &&
        articleDocument.comments != article.comments &&
        articleDocument.image.title != article.image.title &&
        articleDocument.image.url != article.image.url &&
        JSON.stringify(articleDocument.categories) !=
            JSON.stringify(article.categories) &&
        articleDocument.source.title != article.source.title &&
        articleDocument.source.url != article.source.url &&
        articleDocument.enclosures.url != article.enclosures.url &&
        articleDocument.enclosures.type != article.enclosures.type &&
        articleDocument.enclosures.length != article.enclosures.length) {
        requiresUpdate = true;
    }

    return requiresUpdate;

}

function createArticleDocument(article, url) {
    return new Article({ title: article.title,
        description: article.description, link: article.link,
        origLink: article.origLink, author: article.author, guid: article.guid,
        comments: article.comments, image: article.image,
        categories: article.categories, source: article.source,
        enclosures: article.enclosures, feed: url });
}

function updateDatabase() {
    Feed.find(function(error, feedDocuments) {
        if(error != null) {
            console.error('Failed to get feeds from MongoDB: '+error);
        }
        else {
            feedDocuments.forEach(function(feedDocument) {
                console.log('Updating feed and articles from '
                + feedDocument.url);
                requestAndParseFeed(feedDocument.url);
            });
        }
    });
}

function updateDatabaseAtInterval(seconds) {
    if(updateIntervalHandle == null) {
        updateIntervalHandle = setInterval(updateDatabase, seconds);
    }
    else {
        console.warn('Database update interval already set. Skipping.');
    }
}

function stopUpdateDataBaseAtInterval() {
    if(updateIntervalHandle != null) {
        clearInterval(updateIntervalHandle);
        updateIntervalHandle = null;
    }
}

function getArticlesByKeyword(keyword, limit, callback) {
    var searchTerm = new RegExp('.*(\\s|-)+'+keyword+'(\\s|-)+.*', 'i');

    var query = Article.find({ $or: [ { title: searchTerm }, { description:
    searchTerm }, { author: searchTerm } ] }).limit(limit);

    query.execFind(function (error, articleDocuments) {
        if(error != null) {
            console.error('Failed to get articles from MongoDB: '+error);
        }
        else {
            callback(articleDocuments);
        }
    });
}

function getArticlesByKeywordArray(keywords, limit, callback) {
    var keyword = '('+keywords.join('|')+')';
    getArticlesByKeyword(keyword, limit, callback);
}

exports.connect = connect;
exports.addFeed = addFeed;
exports.updateDatabase = updateDatabase;
exports.updateDatabaseAtInterval = updateDatabaseAtInterval;
exports.stopUpdateDataBaseAtInterval = stopUpdateDataBaseAtInterval;
exports.getArticlesByKeyword = getArticlesByKeyword;
exports.getArticlesByKeywordArray = getArticlesByKeywordArray;
<|endoftext|>


<commit_before>/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
// Leave the above lines for propper jshinting

/*
    The Serial Peripheral Interface (SPI) sample application distributed within Intel® XDK IoT Edition under the IoT with Node.js Projects project creation option showcases how to communicate with SPI devices with Intel(R) IoT platforms such as Intel(R) Edison as the master device.

	This sends 4 bytes on MOSI and if connected correctly will yield a 4 buffer object with the result on MISO and print both. Connect MOSI to MISO and input should match the result
	Acceptable parameters to the SPI constructor depends on the amount of SPI buses & chip selects you have. Mraa considers every chip select on every bus to be represented by a SPI object. But 0 is always the default.
	SPI pins are 10/11/12 on an Intel(R) Edison Arduino type board.
		* Pin 10 >> SS
		* Pin 11 >> MOSI
		* Pin 12 >> MISO
		* Pin 13 >> SCK

    MRAA - Low Level Skeleton Library for Communication on GNU/Linux platforms
    Library in C/C++ to interface with Galileo & other Intel platforms, in a structured API with port names/numbering that match compatible boards & with bindings to javascript.

    Steps for installing MRAA & UPM Library on Intel IoT Platform with IoTDevKit Linux* image and an active internet connection
    Using a ssh client:
	    1. echo "src maa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/intel-iotdk.conf
	    2. opkg update
	    3. opkg upgrade

    Article: https://software.intel.com/en-us/node-js-templates-for-intel-xdk-iot-edition
*/
//SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK)
// DC 9
// reset 8

////gpio init

var sleep = require('sleep');
var m = require('mraa'); //require mraa

var SWRESET =char('0x01'); // software reset
var SLPOUT = char('0x11'); // sleep out
var DISPOFF = char('0x28'); // display off
var DISPON = char('0x29'); // display on
var CASET = char('0x2A'); // column address set
var RASET = char('0x2B'); // row address set
var RAMWR = char('0x2C'); // RAM write
var MADCTL = char('0x36'); // axis control
var COLMOD = char('0x3A'); // color mode
// 1.8" TFT display constants
var XSIZE = 128;
var YSIZE =160;
var XMAX = XSIZE-1
var YMAX  = YSIZE-1
// Color constants
var BLACK = char('0x0000');
var BLUE = char('0x001F');
var RED = char('0xF800');
var GREEN = char('0x0400');
var LIME = char('0x07E0');
var CYAN = char('0x07FF');
var MAGENTA = char('0xF81F');
var YELLOW = char('0xFFE0');
var WHITE = char('0xFFFF');

var GPIO9 = new m.Gpio(9); //setup Digital pin #9 (D9)  DC
GPIO9.dir(m.DIR_OUT); //set the gpio direction to output

var GPIO8 = new m.Gpio(8) //setup Digital pin #8 (d8) reset
GPIO8.dir(m.DIR_OUT); // set the gpio direction to output

var transfer = new m.Spi(0); //spi bus

function WriteCmd(byte){
    GPIO9.write(0);
    transfer.write(byte);
    GPIO9.write(1);
}

function HardwareReset(){
    GPIO8.write(0); //pulling line temporarily low
    sleep.usleep(1000);// 1 ms delay
    GPI08.write(1);
}
function char(x) {
	return parseInt(x, 16);
}

function initDisplay(){
    HardwareReset();
    WriteCmd(SLPOUT);
    sleep.usleep(1500); //150ms delay
    WriteCmd(COLMOD);
    transfer.write(char('0x05'));
    WriteCMD(DISPON);

}

console.log('MRAA Version: ' + m.getVersion()); //write the mraa version to the console

initDisplay();
console.log('done');<commit_msg>codefix<commit_after>/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
// Leave the above lines for propper jshinting

/*
    The Serial Peripheral Interface (SPI) sample application distributed within Intel® XDK IoT Edition under the IoT with Node.js Projects project creation option showcases how to communicate with SPI devices with Intel(R) IoT platforms such as Intel(R) Edison as the master device.

	This sends 4 bytes on MOSI and if connected correctly will yield a 4 buffer object with the result on MISO and print both. Connect MOSI to MISO and input should match the result
	Acceptable parameters to the SPI constructor depends on the amount of SPI buses & chip selects you have. Mraa considers every chip select on every bus to be represented by a SPI object. But 0 is always the default.
	SPI pins are 10/11/12 on an Intel(R) Edison Arduino type board.
		* Pin 10 >> SS
		* Pin 11 >> MOSI
		* Pin 12 >> MISO
		* Pin 13 >> SCK

    MRAA - Low Level Skeleton Library for Communication on GNU/Linux platforms
    Library in C/C++ to interface with Galileo & other Intel platforms, in a structured API with port names/numbering that match compatible boards & with bindings to javascript.

    Steps for installing MRAA & UPM Library on Intel IoT Platform with IoTDevKit Linux* image and an active internet connection
    Using a ssh client:
	    1. echo "src maa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/intel-iotdk.conf
	    2. opkg update
	    3. opkg upgrade

    Article: https://software.intel.com/en-us/node-js-templates-for-intel-xdk-iot-edition
*/
//SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK)
// DC 9
// reset 8

////gpio init

var sleep = require('sleep');
var m = require('mraa'); //require mraa

var SWRESET =char('0x01'); // software reset
var SLPOUT = char('0x11'); // sleep out
var DISPOFF = char('0x28'); // display off
var DISPON = char('0x29'); // display on
var CASET = char('0x2A'); // column address set
var RASET = char('0x2B'); // row address set
var RAMWR = char('0x2C'); // RAM write
var MADCTL = char('0x36'); // axis control
var COLMOD = char('0x3A'); // color mode
// 1.8" TFT display constants
var XSIZE = 128;
var YSIZE =160;
var XMAX = XSIZE-1;
var YMAX  = YSIZE-1;
// Color constants
var BLACK = char('0x0000');
var BLUE = char('0x001F');
var RED = char('0xF800');
var GREEN = char('0x0400');
var LIME = char('0x07E0');
var CYAN = char('0x07FF');
var MAGENTA = char('0xF81F');
var YELLOW = char('0xFFE0');
var WHITE = char('0xFFFF');

var GPIO9 = new m.Gpio(9); //setup Digital pin #9 (D9)  DC
GPIO9.dir(m.DIR_OUT); //set the gpio direction to output

var GPIO8 = new m.Gpio(8); //setup Digital pin #8 (d8) reset
GPIO8.dir(m.DIR_OUT); // set the gpio direction to output

var transfer = new m.Spi(0); //spi bus

function WriteCmd(byte){
    GPIO9.write(0);
    transfer.write(byte);
    GPIO9.write(1);
}

function HardwareReset(){
    GPIO8.write(0); //pulling line temporarily low
    sleep.usleep(1000);// 1 ms delay
    GPIO8.write(1);
}
function char(x) {
	return parseInt(x, 16);
}

function initDisplay(){
    HardwareReset();
    WriteCmd(SLPOUT);
    sleep.usleep(1500); //150ms delay
    WriteCmd(COLMOD);
    transfer.write(char('0x05'));
    WriteCmd(DISPON);

}

console.log('MRAA Version: ' + m.getVersion()); //write the mraa version to the console

initDisplay();
console.log('done');<|endoftext|>


<commit_before>var bot = require('./bot');
start();
bot.on('message',message =>
	{
var guild = bot.guilds.find("name","Revive Network Dev");
if(message.guild != guild)
{return;}
if(message.content.toLowerCase()==='~restart')
{
	message.channel.sendMessage('~stop');
	start();
message.reply('restarted');
}
if(message.content.toLowerCase()==='~start')
{
	start();
	message.reply('started');
}

	});
function start(){
	var dt = process.env.DISCORD_TOKEN || process.argv[2];
	console.log('Starting?');
	const exec = require('child_process').exec;
	exec('index.js '+process.argv[2], (error, stdout, stderr) => {
		  if (error) {
			  console.log("error");
              console.log(error);
			      start; return;
			    }
		  console.log(`stdout: ${stdout}`);
		  console.log(`stderr: ${stderr}`);
		});
};
<commit_msg>Great going trying to run index.js without node<commit_after>var bot = require('./bot');
start();
bot.on('message',message =>
	{
var guild = bot.guilds.find("name","Revive Network Dev");
if(message.guild != guild)
{return;}
if(message.content.toLowerCase()==='~restart')
{
	message.channel.sendMessage('~stop');
	start();
message.reply('restarted');
}
if(message.content.toLowerCase()==='~start')
{
	start();
	message.reply('started');
}

	});
function start(){
	var dt = process.env.DISCORD_TOKEN || process.argv[2];
	console.log('Starting?');
	const exec = require('child_process').exec;
	exec('node index.js '+process.argv[2], (error, stdout, stderr) => {
		  if (error) {
			  console.log("error");
              console.log(error);
			      start; return;
			    }
		  console.log(`stdout: ${stdout}`);
		  console.log(`stderr: ${stderr}`);
		});
};
<|endoftext|>


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

    // Function to update labels of text fields
    Materialize.updateTextFields = function() {
      var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
      $(input_selector).each(function(index, element) {
        if ($(element).val().length > 0 || $(this).attr('placeholder') !== undefined) {
          $(this).siblings('label, i').addClass('active');
        }
        else {
          $(this).siblings('label, i').removeClass('active');
        }
      });
    }

    // Text based inputs
    var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';

    // Handle HTML5 autofocus
    $('input[autofocus]').siblings('label, i').addClass('active');

    // Add active if form auto complete
    $(document).on('change', input_selector, function () {
      if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
        $(this).siblings('label, i').addClass('active');
      }
      validate_field($(this));
    });

    // Add active if input element has been pre-populated on document ready
    $(document).ready(function() {
      Materialize.updateTextFields();
    });

    // HTML DOM FORM RESET handling
    $(document).on('reset', function(e) {
      if ($(e.target).is('form')) {
        $(this).find(input_selector).removeClass('valid').removeClass('invalid');

        // Reset select
        $(this).find('select.initialized').each(function () {
          var reset_text = $(this).find('option[selected]').text();
          $(this).siblings('input.select-dropdown').val(reset_text);
        });
      }
    });

    // Add active when element has focus
    $(document).on('focus', input_selector, function () {
      $(this).siblings('label, i').addClass('active');
    });

    $(document).on('blur', input_selector, function () {
      if ($(this).val().length === 0 && $(this).attr('placeholder') === undefined) {
        $(this).siblings('label, i').removeClass('active');
      }
      validate_field($(this));
    });

    validate_field = function(object) {
      if (object.val().length === 0) {
        if (object.hasClass('validate')) {
          object.removeClass('valid');
          object.removeClass('invalid');
        }
      }
      else {
        if (object.hasClass('validate')) {
          if (object.is(':valid')) {
            object.removeClass('invalid');
            object.addClass('valid');
          }
          else {
            object.removeClass('valid');
            object.addClass('invalid');
          }
        }
      }
    }

    // Textarea Auto Resize
    var hiddenDiv = $('.hiddendiv').first();
    if (!hiddenDiv.length) {
      hiddenDiv = $('

');
      $('body').append(hiddenDiv);
    }
    var text_area_selector = '.materialize-textarea';

    function textareaAutoResize($textarea) {
      hiddenDiv.text($textarea.val() + '\n');
      var content = hiddenDiv.html().replace(/\n/g, '
');
      hiddenDiv.html(content);

      // When textarea is hidden, width goes crazy.
      // Approximate with half of window size

      if ($textarea.is(':visible')) {
        hiddenDiv.css('width', $textarea.width());
      }
      else {
        hiddenDiv.css('width', $(window).width()/2);
      }

      $textarea.css('height', hiddenDiv.height());
    }

    $(text_area_selector).each(function () {
      var $textarea = $(this);
      if ($textarea.val().length) {
        textareaAutoResize($textarea);
      }
    });

    $('body').on('keyup keydown', text_area_selector, function () {
      textareaAutoResize($(this));
    });

    // File Input Path
    $('.file-field').each(function() {
      var path_input = $(this).find('input.file-path');
      $(this).find('input[type="file"]').change(function () {
        path_input.val($(this)[0].files[0].name);
        path_input.trigger('change');
      });
    });

    // Range Input
    var range_type = 'input[type=range]';
    var range_mousedown = false;

    $(range_type).each(function () {
      var thumb = $('');
      $(this).after(thumb);
    });

    var range_wrapper = '.range-field';

      $(document).on("mousedown", range_wrapper, function(e) {
        var thumb = $(this).children('.thumb');
        if (thumb.length <= 0) {
          thumb = $('');
          $(this).append(thumb);
        }

      range_mousedown = true;
      $(this).addClass('active');

      if (!thumb.hasClass('active')) {
        thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
      }
      var left = e.pageX - $(this).offset().left;
      var width = $(this).outerWidth();

      if (left < 0) {
        left = 0;
      }
      else if (left > width) {
        left = width;
      }
      thumb.addClass('active').css('left', left);
      thumb.find('.value').html($(this).children('input[type=range]').val());

    });
    $(document).on("mouseup", range_wrapper, function() {
      range_mousedown = false;
      $(this).removeClass('active');
    });

    $(document).on("mousemove", range_wrapper, function(e) {

      var thumb = $(this).children('.thumb');
      if (range_mousedown) {
        if (!thumb.hasClass('active')) {
          thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
        }
        var left = e.pageX - $(this).offset().left;
        var width = $(this).outerWidth();

        if (left < 0) {
          left = 0;
        }
        else if (left > width) {
          left = width;
        }
        thumb.addClass('active').css('left', left);
        thumb.find('.value').html($(this).children('input[type=range]').val());
      }

    });
    $(document).on("mouseout", range_wrapper, function() {
      if (!range_mousedown) {

        var thumb = $(this).children('.thumb');

        if (thumb.hasClass('active')) {
          thumb.velocity({ height: "0", width: "0", top: "10px", marginLeft: "-6px"}, { duration: 100 });
        }
        thumb.removeClass('active');
      }
    });

  }); // End of $(document).ready

  // Select Plugin
  $.fn.material_select = function (callback) {
    $(this).each(function(){
      $select = $(this);

      if ( $select.hasClass('browser-default')) {
        return; // Continue to next (return false breaks out of entire loop)
      }

      // Tear down structure if Select needs to be rebuilt
      var lastID = $select.data('select-id');
      if (lastID) {
        $select.parent().find('i').remove();
        $select.parent().find('input').remove();

        $select.unwrap();
        $('ul#select-options-'+lastID).remove();
      }

      var uniqueID = Materialize.guid();
      $select.data('select-id', uniqueID);
      var wrapper = $('

');
      var options = $('

');
      var selectOptions = $select.children('option');
      if ($select.find('option:selected') !== undefined) {
        var label = $select.find('option:selected');
      }
      else {
        var label = options.first();
      }

      // Create Dropdown structure
      selectOptions.each(function () {
        // Add disabled attr if disabled
        options.append($('
' + $(this).html() + '
'));
      });

      options.find('li').each(function (i) {
        var $curr_select = $select;
        $(this).click(function () {
          // Check if option element is disabled
          if (!$(this).hasClass('disabled')) {
            $curr_select.find('option').eq(i).prop('selected', true);
            // Trigger onchange() event
            $curr_select.trigger('change');
            $curr_select.siblings('input.select-dropdown').val($(this).text());
            if (typeof callback !== 'undefined') callback();
          }
        });

      });

      // Wrap Elements
      $select.wrap(wrapper);
      // Add Select Display Element
      var dropdownIcon = $('');
      if ( $select.is(':disabled') )
        dropdownIcon.addClass('disabled');

      var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '')
                       + ' data-activates="select-options-' + uniqueID +'" value="'+ label.html() +'"/>');
      $select.before($newSelect);
      $newSelect.before(dropdownIcon);

      $('body').append(options);
      // Check if section element is disabled
      if (!$select.is(':disabled')) {
        $newSelect.dropdown({"hover": false});
      }
      $select.addClass('initialized');

      $newSelect.on('focus', function(){
        $(this).trigger('open');
        label = $(this).val();
        selectedOption = options.find('li').filter(function() {
          return $(this).text().toLowerCase() === label.toLowerCase();
        })[0];
        activateOption(options, selectedOption);
      });

      $newSelect.on('blur', function(){
        $(this).trigger('close');
      });

      // Make option as selected and scroll to selected position
      activateOption = function(collection, newOption) {
        collection.find('li.active').removeClass('active');
        $(newOption).addClass('active');
        collection.scrollTo(newOption);
      }

      // Allow user to search by typing
      // this array is cleared after 1 second
      filterQuery = []

      onKeyDown = function(event){
        // TAB - switch to another input
        if(event.which == 9){
          $newSelect.trigger('close');
          return
        }

        // ARROW DOWN WHEN SELECT IS CLOSED - open select options
        if(event.which == 40 && !options.is(":visible")){
          $newSelect.trigger('open');
          return
        }

        // ENTER WHEN SELECT IS CLOSED - submit form
        if(event.which == 13 && !options.is(":visible")){
          return
        }

        event.preventDefault();

        // CASE WHEN USER TYPE LETTERS
        letter = String.fromCharCode(event.which).toLowerCase();

        if (letter){
          filterQuery.push(letter);

          string = filterQuery.join("");

          newOption = options.find('li').filter(function() {
            return $(this).text().toLowerCase().indexOf(string) === 0;
          })[0];

          if(newOption){
            activateOption(options, newOption);
          }
        }

        // ENTER - select option and close when select options are opened
        if(event.which == 13){
          activeOption = options.find('li.active:not(.disabled)')[0];
          if(activeOption){
            $(activeOption).trigger('click');
            $newSelect.trigger('close');
          }
        }

        // ARROW DOWN - move to next not disabled option
        if(event.which == 40){
          newOption = options.find('li.active').next('li:not(.disabled)')[0];
          if(newOption){
            activateOption(options, newOption);
          }
        }

        // ESC - close options
        if(event.which == 27){
          $newSelect.trigger('close');
        }

        // ARROW UP - move to previous not disabled option
        if(event.which == 38){
          newOption = options.find('li.active').prev('li:not(.disabled)')[0];
          if(newOption){
            activateOption(options, newOption);
          }
        }

        // Automaticaly clean filter query so user can search again by starting letters
        setTimeout(function(){filterQuery = []}, 1000)
      }

      $newSelect.on('keydown', onKeyDown);
    });
  }

}( jQuery ));
<commit_msg>Removing active class on form labels on reset trigger.<commit_after>(function ($) {
  $(document).ready(function() {

    // Function to update labels of text fields
    Materialize.updateTextFields = function() {
      var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
      $(input_selector).each(function(index, element) {
        if ($(element).val().length > 0 || $(this).attr('placeholder') !== undefined) {
          $(this).siblings('label, i').addClass('active');
        }
        else {
          $(this).siblings('label, i').removeClass('active');
        }
      });
    }

    // Text based inputs
    var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';

    // Handle HTML5 autofocus
    $('input[autofocus]').siblings('label, i').addClass('active');

    // Add active if form auto complete
    $(document).on('change', input_selector, function () {
      if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
        $(this).siblings('label, i').addClass('active');
      }
      validate_field($(this));
    });

    // Add active if input element has been pre-populated on document ready
    $(document).ready(function() {
      Materialize.updateTextFields();
    });

    // HTML DOM FORM RESET handling
    $(document).on('reset', function(e) {
      if ($(e.target).is('form')) {
        $(this).find(input_selector).removeClass('valid').removeClass('invalid');
        $(this).find(input_selector).siblings('label, i').removeClass('active');

        // Reset select
        $(this).find('select.initialized').each(function () {
          var reset_text = $(this).find('option[selected]').text();
          $(this).siblings('input.select-dropdown').val(reset_text);
        });
      }
    });

    // Add active when element has focus
    $(document).on('focus', input_selector, function () {
      $(this).siblings('label, i').addClass('active');
    });

    $(document).on('blur', input_selector, function () {
      if ($(this).val().length === 0 && $(this).attr('placeholder') === undefined) {
        $(this).siblings('label, i').removeClass('active');
      }
      validate_field($(this));
    });

    validate_field = function(object) {
      if (object.val().length === 0) {
        if (object.hasClass('validate')) {
          object.removeClass('valid');
          object.removeClass('invalid');
        }
      }
      else {
        if (object.hasClass('validate')) {
          if (object.is(':valid')) {
            object.removeClass('invalid');
            object.addClass('valid');
          }
          else {
            object.removeClass('valid');
            object.addClass('invalid');
          }
        }
      }
    }

    // Textarea Auto Resize
    var hiddenDiv = $('.hiddendiv').first();
    if (!hiddenDiv.length) {
      hiddenDiv = $('

');
      $('body').append(hiddenDiv);
    }
    var text_area_selector = '.materialize-textarea';

    function textareaAutoResize($textarea) {
      hiddenDiv.text($textarea.val() + '\n');
      var content = hiddenDiv.html().replace(/\n/g, '
');
      hiddenDiv.html(content);

      // When textarea is hidden, width goes crazy.
      // Approximate with half of window size

      if ($textarea.is(':visible')) {
        hiddenDiv.css('width', $textarea.width());
      }
      else {
        hiddenDiv.css('width', $(window).width()/2);
      }

      $textarea.css('height', hiddenDiv.height());
    }

    $(text_area_selector).each(function () {
      var $textarea = $(this);
      if ($textarea.val().length) {
        textareaAutoResize($textarea);
      }
    });

    $('body').on('keyup keydown', text_area_selector, function () {
      textareaAutoResize($(this));
    });

    // File Input Path
    $('.file-field').each(function() {
      var path_input = $(this).find('input.file-path');
      $(this).find('input[type="file"]').change(function () {
        path_input.val($(this)[0].files[0].name);
        path_input.trigger('change');
      });
    });

    // Range Input
    var range_type = 'input[type=range]';
    var range_mousedown = false;

    $(range_type).each(function () {
      var thumb = $('');
      $(this).after(thumb);
    });

    var range_wrapper = '.range-field';

      $(document).on("mousedown", range_wrapper, function(e) {
        var thumb = $(this).children('.thumb');
        if (thumb.length <= 0) {
          thumb = $('');
          $(this).append(thumb);
        }

      range_mousedown = true;
      $(this).addClass('active');

      if (!thumb.hasClass('active')) {
        thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
      }
      var left = e.pageX - $(this).offset().left;
      var width = $(this).outerWidth();

      if (left < 0) {
        left = 0;
      }
      else if (left > width) {
        left = width;
      }
      thumb.addClass('active').css('left', left);
      thumb.find('.value').html($(this).children('input[type=range]').val());

    });
    $(document).on("mouseup", range_wrapper, function() {
      range_mousedown = false;
      $(this).removeClass('active');
    });

    $(document).on("mousemove", range_wrapper, function(e) {

      var thumb = $(this).children('.thumb');
      if (range_mousedown) {
        if (!thumb.hasClass('active')) {
          thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
        }
        var left = e.pageX - $(this).offset().left;
        var width = $(this).outerWidth();

        if (left < 0) {
          left = 0;
        }
        else if (left > width) {
          left = width;
        }
        thumb.addClass('active').css('left', left);
        thumb.find('.value').html($(this).children('input[type=range]').val());
      }

    });
    $(document).on("mouseout", range_wrapper, function() {
      if (!range_mousedown) {

        var thumb = $(this).children('.thumb');

        if (thumb.hasClass('active')) {
          thumb.velocity({ height: "0", width: "0", top: "10px", marginLeft: "-6px"}, { duration: 100 });
        }
        thumb.removeClass('active');
      }
    });

  }); // End of $(document).ready

  // Select Plugin
  $.fn.material_select = function (callback) {
    $(this).each(function(){
      $select = $(this);

      if ( $select.hasClass('browser-default')) {
        return; // Continue to next (return false breaks out of entire loop)
      }

      // Tear down structure if Select needs to be rebuilt
      var lastID = $select.data('select-id');
      if (lastID) {
        $select.parent().find('i').remove();
        $select.parent().find('input').remove();

        $select.unwrap();
        $('ul#select-options-'+lastID).remove();
      }

      var uniqueID = Materialize.guid();
      $select.data('select-id', uniqueID);
      var wrapper = $('

');
      var options = $('

');
      var selectOptions = $select.children('option');
      if ($select.find('option:selected') !== undefined) {
        var label = $select.find('option:selected');
      }
      else {
        var label = options.first();
      }

      // Create Dropdown structure
      selectOptions.each(function () {
        // Add disabled attr if disabled
        options.append($('
' + $(this).html() + '
'));
      });

      options.find('li').each(function (i) {
        var $curr_select = $select;
        $(this).click(function () {
          // Check if option element is disabled
          if (!$(this).hasClass('disabled')) {
            $curr_select.find('option').eq(i).prop('selected', true);
            // Trigger onchange() event
            $curr_select.trigger('change');
            $curr_select.siblings('input.select-dropdown').val($(this).text());
            if (typeof callback !== 'undefined') callback();
          }
        });

      });

      // Wrap Elements
      $select.wrap(wrapper);
      // Add Select Display Element
      var dropdownIcon = $('');
      if ( $select.is(':disabled') )
        dropdownIcon.addClass('disabled');

      var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '')
                       + ' data-activates="select-options-' + uniqueID +'" value="'+ label.html() +'"/>');
      $select.before($newSelect);
      $newSelect.before(dropdownIcon);

      $('body').append(options);
      // Check if section element is disabled
      if (!$select.is(':disabled')) {
        $newSelect.dropdown({"hover": false});
      }
      $select.addClass('initialized');

      $newSelect.on('focus', function(){
        $(this).trigger('open');
        label = $(this).val();
        selectedOption = options.find('li').filter(function() {
          return $(this).text().toLowerCase() === label.toLowerCase();
        })[0];
        activateOption(options, selectedOption);
      });

      $newSelect.on('blur', function(){
        $(this).trigger('close');
      });

      // Make option as selected and scroll to selected position
      activateOption = function(collection, newOption) {
        collection.find('li.active').removeClass('active');
        $(newOption).addClass('active');
        collection.scrollTo(newOption);
      }

      // Allow user to search by typing
      // this array is cleared after 1 second
      filterQuery = []

      onKeyDown = function(event){
        // TAB - switch to another input
        if(event.which == 9){
          $newSelect.trigger('close');
          return
        }

        // ARROW DOWN WHEN SELECT IS CLOSED - open select options
        if(event.which == 40 && !options.is(":visible")){
          $newSelect.trigger('open');
          return
        }

        // ENTER WHEN SELECT IS CLOSED - submit form
        if(event.which == 13 && !options.is(":visible")){
          return
        }

        event.preventDefault();

        // CASE WHEN USER TYPE LETTERS
        letter = String.fromCharCode(event.which).toLowerCase();

        if (letter){
          filterQuery.push(letter);

          string = filterQuery.join("");

          newOption = options.find('li').filter(function() {
            return $(this).text().toLowerCase().indexOf(string) === 0;
          })[0];

          if(newOption){
            activateOption(options, newOption);
          }
        }

        // ENTER - select option and close when select options are opened
        if(event.which == 13){
          activeOption = options.find('li.active:not(.disabled)')[0];
          if(activeOption){
            $(activeOption).trigger('click');
            $newSelect.trigger('close');
          }
        }

        // ARROW DOWN - move to next not disabled option
        if(event.which == 40){
          newOption = options.find('li.active').next('li:not(.disabled)')[0];
          if(newOption){
            activateOption(options, newOption);
          }
        }

        // ESC - close options
        if(event.which == 27){
          $newSelect.trigger('close');
        }

        // ARROW UP - move to previous not disabled option
        if(event.which == 38){
          newOption = options.find('li.active').prev('li:not(.disabled)')[0];
          if(newOption){
            activateOption(options, newOption);
          }
        }

        // Automaticaly clean filter query so user can search again by starting letters
        setTimeout(function(){filterQuery = []}, 1000)
      }

      $newSelect.on('keydown', onKeyDown);
    });
  }

}( jQuery ));
<|endoftext|>